继承二字不如扩展来的直接。
A继承了B,则A可以访问B属性和方法,并可以覆盖。
function Animal(name,age){
this.name = name;
this.age = age;
}
Animal.prototype.name = "( 没有填写 )";
Animal.prototype.sex = '男'
Animal.prototype.info = function(){
console.log(`我叫${this.name},今年${this.age},性别${this.sex}`);
}
var animal = new Animal('小遁','24');
animal.info();
输出:我叫小遁,今年24,性别男
可以看做animal 对Animal.prototype的继承。
先在实例中找,如果未定义再到Animal.prototype中找。
所以 new Animal('小遁','24');不传第一个参数,调用animal.info,Animal.prototype.name起不到作用,因为定义了this.name
继承泛化一些,是A如何访问B的属性和方法,于是乎,就有了各种耳熟能详的版本了。
原型链继承
我觉得上一种应该叫原型链继承...
function Cat(name){
this.name = name;
}
Cat.prototype = new Animal('小遁','24');
Cat.prototype.sound = function(){
console.log('喵喵喵')
}
var cat = new Cat('小花猫');
cat.info();
cat.sound();
var cat1 = new Cat('小白猫');
cat.info();
输出
我叫小花猫,今年24,性别男
喵喵喵
我叫小花猫,今年24,性别男
这里 new Animal('小遁','24');传入参数只是起到默认值的作用。
Cat.prototype 是所有Cat 实例共享的哦!
这时 Cat.prototype实际上是 Animal的一个实例
Cat.prototype = new Animal('小遁','24'); 所起到的作用一目了然。
这也是以下输出都为true的原因
console.log(cat instanceof Cat)
console.log(cat instanceof Animal)
console.log(cat instanceof Object)
proto 为隐性原型链,prototype为显性原型链 instanceof 会以 Cat.prototype === cat.proto为准,
不断递归cat.proto 直到返回为null为止
构造继承
function Cat(name){
Animal.call(this,name);
}
var cat = new Cat("小遁");
console.log(cat.info);
console.log(cat.name)
undefined
小遁
不能访问Animal.prototype
Animal.call(this,name); 相当于调用了Animal(name),只不过this的指向根据环境决定,在上例中相当于为cat添加了name、age属性。
如果Animal.call(this)放在全局作用域下,则会增加到windows下!
剩下不一一列举了。
至于extends,Object.create等以与上文多有出入,也不列举了。
网友评论