js面向对象之继承
原型链继承
用法:把实例的父类给子函数的原型
缺点:
1、因为修改了obj1.arr后obj2.arr也变了,因为来自原型对象的引用属性里所有实例共享的
2、创建子类实例时,无法向父类构造函数传递参数
1 function Parent(){//父 2 3 this.userName = "父函数"; 4 this.arr = [1,2,3]; 5 6 } 7 8 function Child(age){//子 9 10 this.age = age; 11 12 } 13 14 Child.prototype=new Parent(); //原型链===》核心 15 16 17 var obj1 = new Child(18); 18 var obj2 = new Child(); 19 //console.log(obj1.userName); 20 21 obj1.arr[0] = "张三"; 22 23 console.log(obj1.arr); 24 console.log(obj2.arr);
借用构造函数继承
核心:借父类的构造函数来增强子类实例,就是说,相当于复制了一份父类的属性或者方法给子类了
优点:
1、解决了子类实例共享父类引用属性的问题
2、创建子类实例时,可以向父类构造函数传递参数
缺点:
无法实现复用,每一个子类实例都有一个新的run函数,如果实例的对象多了,内存消耗过大
1 function Parent(name,arr){ 2 3 this.userName = name; 4 this.arr = arr; 5 this.run = function(){ 6 7 return 1111; 8 } 9 } 10 11 function Child(name,arr){ 12 13 this.age = 18; 14 15 Parent.call(this,name,arr); //借用构造函数 ====》 核心代码 16 17 } 18 19 var obj1 = new Child("张三",[4,5,6]); 20 var obj2 = new Child("张三",[4,5,6]); 21 22 /*console.log(obj1.userName); 23 console.log(obj2.userName);*/ 24 25 obj1.arr[0] = "你好构造函数"; 26 console.log( obj1.arr ); 27 console.log( obj2.arr );
组合式继承
优点:
1》不存在引用属性共享的问题
2》可传递参数
3》方法可复用
缺点:(小瑕疵)
子类原型上有一份多余的父类实例的属性
1 function Parent(name,arr){ 2 3 this.userName = name; 4 this.arr = arr; 5 6 } 7 Parent.prototype.run = function(){ 8 9 return "我是run方法"; 10 }; 11 12 function Child(name,arr){ 13 14 Parent.call(this,name,arr); //借用构造函数===>核心语句 1》不能复用 15 16 } 17 18 Child.prototype=new Parent(); //原型链===》核心语句 1》不能传递参数2》arr是引用属性,一个改变,互相影响 19 20 var obj1 = new Child("张三",[1,2,3]); 21 var obj2 = new Child("李四",[1,2,3]);
原型式继承
核心:用一个函数,生出来一个新的对象
优点:从已有对象繁衍出新的对象,不需要创建自定义类型
缺点:
1、原型的引用属性会互相影响(公用一个地址)
2、无法实现代码复用,属性是后添加的,都没用到函数封装
1 function fn(obj){ //用来生新对象的 2 3 function F(){}//构造函数 4 5 F.prototype=obj; //F新的对象 6 7 return new F(); 8 9 } 10 11 var obj = { 12 13 name:"张三", 14 age:187 15 16 }; 17 obj1.aa = "李四"; 18 obj2.bb = "你好js"; 19 20 var obj1 = fn(obj); 21 var obj2 = fn(obj); 22 alert(obj1.name);