温故而知新 XDes6
__proto__
),指向构造函数的原型对象(因此能够在构造函数的 prototype 里存放实例公用的方法)。__proto__
),若找到,则 return 该属性值;若没找到,继续搜索原型的原型...给出父类 Animal,实现子类Cat:函数
function Animal (name) { this.name = name this.brother = 'Tony' } Animal.prototype.eat = function (thing) { console.log(this.name + ' eat ' + thing); }
function Cat (name) { Animal.call(this,name) // 借用构造函数,继承父类属性 this.sister = 'May' } Cat.prototype = new Animal() // 原型链,继承父类方法 /* 在prototype继承了父类实例的所有属性,存在冗余。属性的继承已经在构造函数内经过调用父类构造函数实现。 实际上,子类的prototype须要的只是父类实例中指向父类原型的内部指针: Cat.prototype.__proto__ = Animal.protype */ console.log(Cat.prototype) // {name: undefined(冗余), brother: "Tony"(冗余), constructor: ƒ} Cat.prototype.constructor = Cat // 因为上面 Cat.prototype 进行了赋值,因此须要从新指定其构造函数。 // 这一步对 instanceof 无影响,由于 "instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性" ;影响的是Cat实例的constructor 属性。 // 若是不作这一步:var Tom = new Cat('Tom'); Tom.constructor ==> Animal
function Cat (name) { Animal.call(this,name) this.sister = 'May' } function createObject (obj) { /* 建立一个新对象,使用现有的对象来提供新建立的对象的__proto__ ,至关于 Object.create() */ function F () {} F.prototype = obj return new F() } Cat.prototype = createObject (Animal.prototype) // 至关于 Cat.prototype = Object.create(Animal.prototype) console.log(Cat.prototype) // {constructor: ƒ} Cat.prototype.constructor = Cat
class Animal { constructor(name){ this.name = name this.brother = 'Tony' } eat(thing) { console.log(this.name + ' eat ' + thing); } } class Cat extends Animal { constructor(name) { super(name) /* super()表示调用父类构造函数,this指向子类。只有调用super以后,才可使用this关键字,不然新建实例时会报错。*/ /* 另:super做为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。经过super调用父类方法时,方法内部this指向子类;对super的猴哥属性赋值时,super就是this,赋值的属性会变成子类实例的属性 (不清楚里面是什么魔法)*/ this.sister = 'May' } }