《JS高程(3)》原型链继承模式 -第6章笔记(04)
2017-01-12 15:39
393 查看
继承模式
原型链实现继承时,将对象实例视作一个子类原型创建对象实例时,其本身从构造函数中继承的实例属性,此时成为了原型属性,原型属性中包含了”引用类型值”,导致子类原型的属性会被所有实例共享。function SuperType(){ this.color = ['red', 'blue' , 'yellow']; } function SubType(){} SubType.prototype = new SuperType() var instance1 = new SubType(); instance1.color.push ('white'); alert(instance1.color); // red,blue,yellow,white var instance2 = new SubType(); alert(instance2.color); // red,blue,yellow,white
单独借用构造函数也并未解决这问题
1. 组合继承
模式:原型链+借用构造函数使用原型链实现对原型属性和方法的继承;
借用构造函数来实现对实例属性的继承。
function SuperType(name){ this.name = name; this.color = ['red', 'blue' , 'yellow']; } SuperType.prototype.sayName = function(){ alert(this.name); } function SubType(name, age){ //继承属性 超类 //获得name和color属性 SuperType.call(this, name); this.age= age; } //继承方法 SubType.prototype = new SuperType(); SubType.prototype.sayAge = function(){ alert(this.age) } var instance1 = new SubType("Nicholas", 29); instance1.color.push("black"); console.log(instance1.color); //["red", "blue", "yellow", "black"] instance1.sayName(); instance1.sayAge(); var instance2 = new SubType("Greg", 27); console.log(instance2.color); //["red", "blue", "yellow"] instance2.sayName(); instance2.sayAge();
SubType构造函数,通过call()方法调用SuperType构造函数是传入name参数,此时获得name与color属性;(借用构造函数)
将SuperType的实例赋值给SubType的原型;(原型链)
instanceof 和 isPrototypeof()能够识别基于组合继承创建的对象。
2.原型式继承
借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。多用于让一个对象与另一对象保持类型的情况,不必在创建构造函数。function object (o) { // 创建临时构造函数 function F(){} // 将传入的对象作为构造函数的原型 F.prototype = o; // 返回临时构造函数的实例 return new F(); } //基础对象 var person = { name : "Nicholas", friends : ["Shelby", "Count", "Van"] }; // 返回新对象,以person为原型 var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); console.log(anotherPerson.friends); //["Shelby", "Count", "Van", "Rob"] var yetAnotherPerson = object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(yetAnotherPerson.friends); //["Shelby", "Count", "Van", "Rob", "Barbie"] console.log(person.friends); //["Shelby", "Count", "Van", "Rob", "Barbie"]
基本类型值 :
Undefined、Null、Boolean、Number和String
引用时是对实际原型进行了一次复制,通过引用值对基本类型值进行修改的结果,并不会被共享。每次引用就像对实际值进行了一次克隆,但克隆值得修改并不会影响被克隆原型。
引用类型值 :Object 、 Array 、 Date 和 RegExp
对象实例中的引用类型属性是一个指向对象实际位置的指针,所有实例都指向同一个位置,当其中一个实例对指针地址中的属性进行修改后,会影响之后所创建的变量。
//判断对象类型 function isArray(o) { return Object.prototype.toString.call(o) === '[object Array]'; //Array可以换成其它类应用以验证 } var str = "string"; alert(isArray(str)); //false
ES5新增: Object.create( ) 原型式继承
Object.create() 方法接收两个参数:
用作新对象原型的对象(必选) ,仅一个参数时与Object( )方法类似;
为新对象定义额外属性的对象(可选),第二参数与Object.defineProperties(obj, props)方法第二参数格式相同:每个属性都是通过自己的描述符定义的。
var person = { name : "Nicholas", friends : ["Shelby", "Count", "Van"] }; var anotherPerson = Object.create(person,{ name:{ value:"Grey" }, age:{ value:15 } }); console.log(anotherPerson.name ); // Grey console.log(anotherPerson.age); // 15
3.寄生式继承
创建一个用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回该对象。// 寄生式构造函数 function createAnother(o){ // Object()函数可换成其他返回新对象的函数 var clone = Object(o); clone.sayName = function(){ alert('name'); }; return o; } var o = { name:'Grey', age:16 }; // 返回的新对象,具有基础对象的方法和属性,并拥有自己的sayName方法 var person =createAnother(o); person.sayName();
寄生式继承为对象添加的函数不能复用
4.寄生组合式继承
JavaScript最常用的继承模式通过创建一个过渡对象,作为超类型和子类型的桥梁,减少超类的调用次数,
// 组合继承实例 function SuperType(name){ this.name = name; this.color = {"red", "blue", "green"}; }; SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age) = function(){ // 第二次调用SuperType() SuperType.call(this, name); this.age = age; } // 第一次调用SuperType() SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); }
inheritPrototype()函数接受两个参数: 子类型构造函数和超类型构造函数。
创建步骤:① 创建超类型原型的副本;
② 为副本指定constructor属性方向;
③ 将副本赋值给子类型的原型。
// 寄生组合式继承的最简单形式 function inheritPrototype(subType, superType){ // 创建对象 作为超类原型的副本 var prototype = object (superType.prototype); // 修改副本的constructor属性的指向 prototype.constructor = superType; // 将prototype中存放的副本赋值给子类的原型 subType.prototype = prototype; } function SuperType(name){ this.name = name; this.color = {"red", "blue", "green"}; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ //调用了一次SuperType SuperType.call(this.name); this.age = age; }; //替换前面为子类型原型赋值的语句 inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ alert(this.age); };
避免了在SubType.prototype上面创建不必要的、多余的属性;
原型链保持不变,能够正常使用instanceof 和isPrototypeOf();
寄生组合式继承是引用类型最理想的继承范式。
相关文章推荐
- js:语言精髓笔记7----原型继承
- 【09-23】js原型继承学习笔记
- #笔记#圣思园 JavaWeb 第57讲——JS继承:对象冒充、call方法、apply方法、原型链方式、混合方式
- 【MDNjs笔记】——入门——第三章——对象.构造函数.原型链.继承
- 【学习笔记六】 - js中 创建对象的模式与继承 及 js中实现块级作用域和函数私有变量 《js高程》6-7笔记
- 2016.06.15廖雪峰JS__学习笔记(原型继承)__P9
- js创建对象的构造函数模式+原型模式和组合继承\Hybrid Pattern & combination inheritance
- 《JS高程(3)》-第6章笔记(01)
- 【js设计模式笔记---继承】
- js 组合继承(使用原型模式和构造函数模式)和原型式继承
- 《JS高程(3)》BOM-04(screen)-第8章笔记(09)
- HTML5学习笔记(十六):原型、类和继承【JS核心知识点】
- JS高程第六章笔记(下)- 继承
- js面向对象小结(工厂模式,构造函数,原型方法,继承)
- 《JS高程(3)》-第6章笔记(02)
- 【js设计模式笔记---继承】
- js原生设计模式——2面向对象编程之继承—原型继承(类式继承的封装)
- JavaScript高级程序设计(第2版) 学习笔记:(六)js基于构造函数与原型的继承
- 浅谈js函数继承模式之三:共享原型模式
- 原型继承(js秘密花园,抄录笔记)