JavaScript原型继承和“new”关键字

javascript prototypal inheritance and the 'new' keyword

本文关键字:new 关键字 原型 继承 JavaScript      更新时间:2023-09-26

我一直在 JavaScript 中玩原型继承,并对 new 关键字的行为感到困惑。我不明白为什么继承对象的[[prototype]]属性指向Function.prototype而不是继承对象的原型。考虑 2 个构造函数(如下(:

function Animal(name) {
    this.name = name;
}
function Cat(name) {
    Animal.call(this, name);
}
Cat.prototype = new Animal();

查询构造函数的原型Cat,我得到了一些有趣的结果:

Cat.__proto__ === Animal.prototype; //returns false -- shouldn't this be true?
Cat.__proto__ === Function.prototype; //returns true
Cat.prototype instanceof Animal; //returns true, as expected

我的理解是,当我们将其原型属性设置为新的Animal实例时,应该更新Cat[[prototype]]以指向Animal.prototype,这本质上应该

  1. 基于 Animal.prototype 创建新对象 和
  2. 内部设置Cat.[[prototype]] Animal的外部原型属性?

我已经在Chrome和FF中尝试过这个,结果相同。什么给?

另外,当我们将Cat.prototype分配给new Animal()时,Cat.prototype应该是什么?即:

//if Cat.prototype = new Animal();
//then
Cat.prototype === Animal.prototype; //get false. Should this be true?
Cat.__proto__ === Animal.prototype; //returns false -- shouldn't this be true?
Cat.__proto__ === Function.prototype; //returns true

构造函数Cat是一个函数。因此,它继承自Function.prototype而又继承自Object.prototype .对于Animal构造函数和所有其他函数对象也是如此。

仅仅因为您分配给Cat.prototype不会更改Cat构造函数本身的继承链接(继承链接无论如何都是不可变的(。

请注意,Cat实例不是从 Cat 继承,而是从 Cat.prototype 继承。因此,无论如何,您都不关心Cat构造函数的原型链接。

[[prototype]] 属性由 Object 而不是构造函数拥有。所以在你的例子中,你会发现

Cat.prototype.__proto__ === Animal.prototype; //Return true

常说

Instance.__proto__ === Constructor.prototype; //Retrun true

Cat 是一个构造函数,它是函数类型的实例,所以你看到了这个结果

Cat.__proto__ === Function.prototype; //Return true 

我的英语太糟糕了,但我希望我已经解释了一些事情。