JS 继承(二)组合继承

JS 继承(二)组合继承

JS 继承(一)说明了一下简单的原型链继承,并且说明了它的两个缺点,现在解决它们。

function Person (name,age) {
  this.name = name;
  this.age = age;
  this.friends = ['LiLei','HanMeiMei'];
}


function Man (name, age) {
  this.name = name;
  Person.call(this,name, age);
}


let m1 = new Man('tom', 12);
m1.friends.push('Green');

console.log("m1:", m1);
console.log("m1.__proto__:",m1.__proto__);

let m2 = new Man('LiLei',13);

console.log("m2:", m2);
console.log("m2.__proto__:",m2.__proto__);

运行结果:


JS 继承(二)组合继承_第1张图片
image.png

看结果,简单原型链的那种继承方式的两个缺点都解决了,既可以给父类构造函数传参,父类构造函数里面的属性friends,name,age也私有化了,不再被共享,从而导致被其他实例影响了。

在Man构造函数中,Person.call(this,name, age)这句代码,非常重要,new操作的时候,除了会指向构造函数里面的代码并返回一个实例对象this外,还会把构造函数的作用域赋值给创建的实例对象,所以构造函数里面的this.xx = ‘xxx' 都是给实例对象添加属性并赋值,好比这样:

function PersonFn () {
let o = new Object();
o.a = 'aaa';
o.b = 'bbb';
return o;
}

每次执行PersonFn 都会生成一个全新的对象o;

ok, 说到这里,上面的那种继承写法,看起来似乎挺完美。

哦,对了,上面的运行结果中,m1.proto指向的原型对象因为当前并没有继承谁,所以是空的,但是每一个构造函数的原型对象都会有两个默认的属性constructor和proto,而proto默认继承Object原型对象。

回归正传,上面的代码好像没有写方法,下面把方法添加上:

function Person (name,age) {
  this.name = name;
  this.age = age;
  this.friends = ['LiLei','HanMeiMei'];
}

Person.prototype.sayWords = function(des) {
  console.log(des+' say words:', this.name,this.age, this.friends.toString());
}

function Man (name, age) {
  this.name = name;
  Person.call(this,name, age);
}

Man.prototype = new Person();

let m1 = new Man('tom', 12);
m1.friends.push('Green');

m1.sayWords("Person -> tom 1");

console.log("m1:", m1);
console.log("m1.__proto__:",m1.__proto__);

let m2 = new Man('LiLei',13);
m2.sayWords("Person -> LiLei 2");

console.log("m2:", m2);
console.log("m2.__proto__:",m2.__proto__);

运行结果:


JS 继承(二)组合继承_第2张图片
image.png

Ok,现在看起来真的不错了。
这种继承方法就叫组合继承,是最常用的继承模式。

有时候真搞不懂,网上继承的方法一搜,好家伙,6,7种继承方式,取了一大堆的名字,各种概念,真的逼死人了,据科学家研究(我是道听途说),人脑的容量只有200M左右,这么小的容量,用来记那写莫名其妙的概念真他妈浪费,码农何必为难码农呢?呵呵...

你可能感兴趣的:(JS 继承(二)组合继承)