Javascript学习笔记2 继承 原型链
2018-03-13 18:07
633 查看
原型链
使某个原型对象成为另一个类型的实例,该原型对象将包含一个指向另一个原型的指针,如此层层递进,就构成了实例与原型的链条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(); alert(instance.getSuperValue()); //true
当子类型需要覆盖超类型中的某个方法或添加超类型没有的方法时,给原型添加的方法的代码一定要放在替换原型的语句之后
通过原型链实现继承时,不能使用对象字面量的方式创建原型方法,否则会重写原型,从而切断了原型链
不足:包含引用类型值的原型会被所有实例共享
关系如下:
原型搜索机制:首先在实例中搜索该属性,如果没有找到,则会继续在实例的原型中搜索,若还未找到,则在原型链实现继承的情况下,会继续向上搜索原型对象的原型对象,直达搜索到原型链的末端。
所有引用类型都默认继承了Oject对象,因此所有默认原型的
__proto__属性都会指向Object.prototype。关于
__proto__、prototype、constructor的关系,以及js中所有对象都继承于Object这点可以用这张图说明
实例对象是构造函数创建的,实例对象的
__proto__属性指向其原型对象,构造函数的prototype指向原型对象,原型对象的constructor指向构造函数
构造函数也是实例对象,其是由function这个构造函数创建的,同时function的原型对象(
function.prototype)也是对象,其是由Object这个构造函数创造的,原型对象是Object.prototype。换句话说,即
function.prototype.__proto__等于Object.prototype
更详细的讲解,请参考这篇博客,这张图也是引用他的 https://www.cnblogs.com/xiaohuochai/p/5721552.html
借用构造函数
为解决原型链中引用值类型共享及参数传递问题,在子类型的构造函数的内部调用超类型的构造函数function SuperType(name){ this.name = name; } function SubType(){ SuperType.call(this,"zjw"); //执行超类的构造函数,传入SubType的环境对象和参数, //执行代码后,name属性就创建在了SubType的实例上 this.age = 28; } var instance = new SubType(); alert(instance.name) //"zjw" alert(instance.age) //28
不足:构造函数无法解决函数复用问题,每次都要重新创造实例方法
组合继承
将原型链和借用构造函数组合到一块,使用原型链实现对原型属性和方法的继承,而构造函数实现对实例属性的继承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); //调用超类的构造函数,使每个实例都具有colors属性的副本 //从而没有直接继承超类的引用型属性 this.age = age; } SubType.prototype = new SuperType(); //继承超类 SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ //给子类的原型添加方法 alert(this.age); }; var instance1 = new SubType("zjw",29); //创建子类型 instance1.colors.push("black"); alert(instance1.colors); //"red","blue","green","black" instance1.sayName(); //"zjw" instance1.sayAge(); //29 var instance2 = new SubType("bob",27); alert(instance1.colors); //"red","blue","green" instance1.sayName(); //"bob" instance1.sayAge(); //27
原型式继承
基于已有对象创建新对象(浅复制,引用类型属性仍然共享)直接使用
Object.create()方法,接受两个参数:要复制的对象和新添属性的对象
var anotherPerson = Object.create(Person,{ name:{ value:"zjw" } });
寄生式继承
创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回对象,与工厂模式类似function createAnother(o){ var clone = object(o) //创建新对象 clone.sayHi = function(){ //添加新方法 alert("hi"); } return clone; //返回新对象 } var person = {name:"zjw"}; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //hi
跟构造函数一样不能做到函数复用
寄生组合式继承
解决传统的组合继承调用两次超类型构造函数问题,该方法用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型function inheritProperty(SubType,SuperType){ var prototype = object(SuperType.prototype); //创建超类原型的副本 SubType.prototype = prototype; //继承超类副本 SubType.prototype.constructor = SubType; //弥补重写原型而丢失的constructor属性 } 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; } inheritProperty(SubType,SuperType); //调用自定义的继承函数 SubType.prototype.sayAge = function(){ alert(this.age); };
其避免了
SubType.prototype = new SuperType();调用超类的构造函数
该种继承模式最有效,结合了组合继承和寄生式继承的优点
相关文章推荐
- JavaScript学习笔记-原型继承
- Javascript学习笔记九——prototype封装继承
- javascript面向对象学习笔记(一)——继承
- Javascript学习笔记之类与继承(一)
- 【Javascript学习笔记】由JavaScript中call()方法引发的对面向对象继承机制call的思考
- Javascript学习笔记7——原型链的原理
- javascript 学习笔记之面向对象编程(二):继承&多态
- JavaScript 学习笔记八 继承与引用
- javascript面向对象学习笔记(三)——继承
- JavaScript学习笔记3-JavaScript中的继承
- JavaScript学习笔记(三十二) 经典继承模式二-借用构造方法
- <深入理解JavaScript>学习笔记(5)_强大的原型和原型链
- Javascript 笔记(4)----继承与原型链
- javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
- JavaScript学习笔记(5)---继承
- JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)
- JavaScript继承学习笔记
- JavaScript继承学习笔记【新手必看】
- javascript 学习笔记(5)---继承
- JavaScript学习笔记——继承