ECMAScript学习笔记(七)——继承
栏目: JavaScript · 发布时间: 6年前
内容简介:ECMAScript依靠原型链来实现继承;原型链,是利用原型让一个引用类型继承另一个引用类型的属性和方法。如果,一个原型又是另一个原型的实例,那么上述关系依旧成立,如此层层递进,就构成了实例和原型的链条,就是所谓的
ECMAScript依靠原型链来实现继承;
原型链
原型链,是利用原型让一个引用类型继承另一个引用类型的属性和方法。
每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
如果,一个原型又是另一个原型的实例,那么上述关系依旧成立,如此层层递进,就构成了实例和原型的链条,就是所谓的 原型链
eg:
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function SubType() { this.subproperty = false; } SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function() { return this.subproperty; }; var instance = new SubType();
以上代码定义了两个类型:SuperType和SubType。SubType继承了SuperType。 这个继承是通过:创建一个SuperType的实例,然后将这个实例赋值给SubType.prototype实现的。
实现的本质是:重写原型对象,代之以一个新类型的实例。
所有的引用类型都默认几成了Object。这个继承也是通过原型链实现的。
原型和实例的关系:可以通过instanceof操作符和isPrototypeOf()方法来确认。
给原型添加方法的代码,一定要放在替换原型的语句之后。
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function SubType() { this.subproperty = false; } SubType.prototype = new SubperType(); SubType.prototype.getSubValue = function() { return this.subproperty; } SubType.prototype.getSuperValue = function() { return false; } var instance = new SubType(); alert(instance.getSuperType()); // false
以上代码,添加了getSubValue()方法到SubType中,而重写了SubType中的getSubType()方法,将SuperType中的getSuperValue()覆盖了。
原型链的问题
1.在通过原型实现继承时,原型会变成另一个类型的实例。于是,原先的实例属性就会变成现在的原型属性了。
eg:
function SuperType() { this.color = {"red", "blue", "green"}; } function SubType() { } SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); // red, blue, green, black var instance2 = new SubType(); alert(instance2.colors); // red, blue, green, black
2.创建子类型的实例时,不能向超类型的构造函数中传递参数。
借用构造函数
为了解决原型中包含引用类型值,所带来的问题。人们开始使用一种叫 借用构造函数
的技术(伪造对象,或者经典继承)。
这种方法:在子类型构造器的内部调用超类型的构造函数。
eg:
function SuperType() { this.colors = ["red", "blue", "green"]; } function SubType() { SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push("black"); // red, blue, green, black var instance2 = new SubTyp(); instance2.colors // red, blue, green
上述代码,在构造函数中,调用了超类型的构造函数。等于说是在这个构造函数中,执行了一边超类型的构造函数的代码。
另外,这个方式还可以像超类型的构造函数传递参数:
function SuperType(name) { this.name = name; } function SubType() { SuperType.call(this, "Nicholas"); this.age = 29; } var instance = new SubType(); alert(instance.name); // "Nicholas" alert(instance.age); // 29
这种方式存在的问题:这种方式的继承,方法都在构造函数中定义,所以就没办法做函数复用了。
组合继承
组合继承,是指将原型链和借用构造函数组合。
eg:
function SuperType(name) { this.name = name; this.colors = {"red", "blue", "green"}; } SuperType.prototype.sayName = function() { alert(this.name); }; function SubType(name, age) { 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.colors.push("black"); // red, blue, green, black instance1.sayName(); // Nicholas instance1.sayAge(); // 29 var instance2 = new SubType("Gred", 27); instance2.colors; // red, blue, green instance2.sayName(); // Gred instance2.sayAge(); // 27
这是JavaScript中最常用的继承模式了。
原型式继承
基于原有的对象创建新对象,就不必创建自定义类型了。
function object(o) { function F(){} F.prototype = o; return new F(); }
var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnothorPerson = object(person); yetAnothorPerson.name = "Linda"; yetAnothorPerson.friends.push("Barbie"); alert(person.friends); // "Shelby", "Court", "Van", "Rob", "Barbie"
这种原型式继承,要求必须有一个对象可以作为另一个对象的基础。
ECMAScript 5新增的Object.create()方法,规范了原型式继承:
var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = Objcet.create(person); var yetAnothorPerson = Objcet.create(person, { name: { value: "Greg" } });
这种方式,适用于只想让一个对象和另一个对象保持相思的情况。
寄生式继承
function createAnther(original) { var clone = object(original); clone.sayHi = function() { alert("Hi"); }; return clone; }
以上所述就是小编给大家介绍的《ECMAScript学习笔记(七)——继承》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- JS笔记(12): 对象的继承
- 【读书笔记】Effective C++(06)继承与面向对象
- 读书笔记-es6Class的继承
- 【 python 学习笔记 -- OOP】在实例中学习继承(inheritance)和组合(composition)
- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
CLR via C#
Jeffrey Richter / 周靖 / 清华大学出版社 / 2015-1-1 / CNY 109.00
《CLR via C#(第4版)》针对CLR和.NET Framework 4.5进行深入、全面的探讨,并结合实例介绍了如何利用它们进行设计、开发和调试。全书5部分共29章。第Ⅰ部分介绍CLR基础,第Ⅱ部分解释如何设计类型,第Ⅲ部分介绍基本类型,第Ⅳ部分以核心机制为主题,第Ⅴ部分重点介绍线程处理。 通过本书的阅读,读者可以掌握CLR和.NET Framework的精髓,轻松、高效地创建高性能......一起来看看 《CLR via C#》 这本书的介绍吧!