老师您好!由于昨天晚上我是用手机看的视频,所以没有用电脑进行尝试,我今天尝试了一下,这个思路是行得通的。
在父类 Super 中,有一个实例属性 friend ,在子类中指定了 this 上下文后,会为子类的实例创建一个 名为 friend 的数组 ['William', 'Janny'];
在父类的原型上,有属性 name 和方法 say,这两个在子类中执行父类函数时,不会重新创建,在子类的实例上使用 this.name 或者 this.say 时,会从子类的原型上去获得, 在子类实例上,调用 this.name = 'Sub2',this.say = function(){},后,不会影响到原型上的属性和方法,所以sub3可以正常使用这两个属性和方法。
这样做的话,我们就节省了 name 属性, say 方法的内存空间。
如果不用这种方法,每个实例都会创建一个独立的 name 和 say,占用独立的内存空间,如果有100个实例,就是200个内存空间。
如果用了这个方法,只有在子类实例需要重载的地方,会重新创建对象,否则全部引用子类原型对象上的方法和属性。
请看如下代码:
function Super(){
this.friend = ['William', 'Janny'];
}
//值类型、以及方法,可以放在父类的原型中,这样在创建子类实例时,不会直接复制这些属性和方法,节省内存空间
Super.prototype.name = 'Super';
Super.prototype.say = function(){console.log(this.name, this.friend)}
//调用父类构造函数,继承父类属性
function Sub(){
Super.call(this);
this.age = '18';
}
//以父类的实例为原型,创建子类的原型对象
Sub.prototype = Object.create(new Super());
Sub.prototype.constructor = Sub;
const sub1 = new Sub();
sub1.friend.push('Rosy');
sub1.say(); // Super ["William", "Janny", "Rosy"]
const sub2 = new Sub();
sub2.name = 'Sub2';
sub2.say = function(){console.log('hello, I\'am ' + this.name + ', my friends are ' + this.friend)};
sub2.say(); // hello, I'am Sub2, my friends are William,Janny
const sub3 = new Sub();
sub3.say(); //Super ["William", "Janny"],sub3的 name 属性,来自原型对象,但是不受 sub2 的 name 属性影响
console.log(sub2.name === sub2.__proto__.name); // false
console.log(sub3.name === sub3.__proto__.name); // true
console.log(sub3.say === sub1.say); //true
console.log(sub3.say === sub1.__proto__.say); //true