共计 1329 个字符,预计需要花费 4 分钟才能阅读完成。
首先要明确两点:
一、非办法属性每个子类实例须要独立
二、办法属性每个子类实例须要共享
为什么?
如果非办法属性为援用类型,且非办法属性共享,在一个实例中扭转,其余实例中就会做出扭转,这样每个实例就会相互影响,而办法属性个别是不须要进行扭转的,只是对办法调用。
1. 基于原型链的继承
每个函数都有个 prototype
属性, 每个对象都有 __proto__
属性(在 chrome 中体现如此,prototype 也是如此) 如图,属性的查找会从以后层级顺次向原型链上查找,直到查找到原型链的顶端 null,具体可参考 js proto
既然属性的查找是依照原型链向上查找的,且继承就是继承父类的属性跟办法,那么就能够利用这个个性,进行继承。
function SuperType() {this.property = true;}
SuperType.prototype.getSuperValue = function () {return this.property;};
function SubType() {this.subproperty = false;}
// 继承 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function () {return this.subproperty;};
let instance = new SubType();
console.log(instance.getSuperValue()); // true 能够正确调用父类的办法,拿到父类的属性
原型尽管实现了继承,然而还是有毛病的
劣势:
1. 子类或者父类的属性为援用类型时,扭转一个实例的援用类型属性,其余实例的该援用类型属性也会产生扭转,这样其实例就会互相净化了。
function SuperType() {this.colors = ["red", "blue", "green"];
}
function SubType() {} // 继承 SuperType
SubType.prototype = new SuperType();
let instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);
// "red,blue,green,black";
let instance2 = new SubType();
console.log(instance2.colors);
// "red,blue,green,black";
为什么非办法属性不写在 prototype 上?
因为 prototype 上的属性的共享的,在一个实例上改了该属性,其余实例的该属性也会被改掉。
为什么办法不写在构造函数外部?
办法写在子类外部:每次实例化构造函数,办法都是新的;办法只是用来调用,不须要批改,所以实例共享就行了。
办法写在父类外部:不同的子类继承父类都须要实例化父类;办法只是用来调用,不须要做批改,所以实例共享就行了,包含子类实例。如果子类须要批改父类办法,间接在子类中定义雷同办法名,进行笼罩就行了。
2. 子类在实例化时不能给父类的构造函数传参,因为父类的实例化是在后面,而不是结构函数调用的时候。
正文完
发表至: javascript
2020-10-11