【问题标题】:What is the difference let o1.prototype = Object.create(o2.prototype) and o1.prototype = o2.prototype? [duplicate]let o1.prototype = Object.create(o2.prototype) 和 o1.prototype = o2.prototype 有什么区别? [复制]
【发布时间】:2019-11-29 07:42:58
【问题描述】:

所以我想了解o1.prototype = Object.create(o2.prototype)o1.prototype = o2.prototype 之间的区别。

根据this question 的回答,前者将 obj2.prototype 设置为 obj1.prototype 的原型,但我很难理解你为什么想要那个(例如新原型的原型只是 Object.prototype 因为原型是一个没有进一步继承的对象)。此外,它似乎并不像该问题的答案一直暗示的那样有效。

以如下代码为例:

function o1(){}
o1.prototype.test = "test";
function o2(){}
o2.prototype = Object.create(o1.prototype);
let instance1 = Object.create(o1);
console.log(o2.prototype.test, instance1.prototype.test);

o2.prototype.testinstance1.prototype.test 都打印 "test"。因此,将o2 直接分配给Object.create(o1.prototype) 或将o2 的原型设置为Object.create(o1.prototype) 似乎无关紧要。

另外,如果我正确理解这一点,根据链接问题中的答案,如果o1 为空(在这种情况下就是这样),那么设置o2 = o1 将与设置@987654334 相同@ 也与

相同
function o1(){};
function o2(){};
o2.prototype = o1.prototype;

这三者之间有什么显着差异吗?另外,如果o2.prototype = Object.create(o1.prototype)创建了一个empty对象,以o1.prototype的原型作为自己的原型,如果o1的原型不为空,那么o1的成员怎么办? s原型被导入o2的原型?

【问题讨论】:

  • 我很难理解你为什么想要那个”——你不会想要它,没错 :-)
  • 你可能打算使用instance1 = new o1();Object.create(o1.prototype))而不是instance1 = Object.create(o1);

标签: javascript inheritance assign


【解决方案1】:

如果您直接将Parent.prototype 分配给孩子的原型,那么它们都将指向同一个对象。所以,如果你添加一个只适用于子类的方法,Parent 对象也可以访问它们,因为Parent.prototype === Child.prototype

例子:

function Animal() {};
Animal.prototype.Eat = function() {
  console.log("Eating")
}

function Human() {};
Human.prototype = Animal.prototype; // both point to the same object

Human.prototype.Drive = function() {
  console.log("Driving")
}

var animal = new Animal();
var human = new Human();

animal.Eat();
human.Eat();

animal.Drive(); // Animals shouldn't be driving
human.Drive();

console.log("animal instanceof Human: ", animal instanceof Human) // true

如果您改用Object.create(Animal.prototype),它会创建一个新对象,其中[[Prototype]](同样,但不推荐使用__proto__)设置为Anima.prototype。因此,如果在Human.prototype 上找不到任何方法,它将回退Animal.prototype(在这种情况下为Eat

function Animal() {};
Animal.prototype.Eat = function() {
  console.log("Eating")
}

function Human() {};
Human.prototype = Object.create(Animal.prototype)
Human.prototype.constructor = Human; // update the constrcutor

Human.prototype.Drive = function() {
  console.log("Driving")
}

var animal = new Animal;
var human = new Human;

animal.Eat();
human.Eat();
human.Drive();

try {
   // This will throw an error because Animal.prototype doesn't have a Drive method
  animal.Drive();
} catch {
  console.log("Animals can't drive")
}

console.log("animal instanceof Animal: ", animal instanceof Animal) // true
console.log("animal instanceof Human: ", animal instanceof Human) // false
console.log("human instanceof Animal: ", human instanceof Animal) // true
console.log("human instanceof Human: ", human instanceof Human) // true

console.log(animal.constructor)
console.log(human.constructor)

当您访问human.Eat() 时,首先该方法将直接在human 对象下查找。如果没有找到,将在其原型Human.prototype 中进行搜索。

Object.getPrototypeOf(human) === Human.prototype;

由于那里没有找到Eat 方法,所以将在Human.prototype 的原型中查找该方法,即Animal.prototype

Object.getPrototypeOf(Human.prototype) === Animal.prototype

方法在这里找到,它将被执行。


假设您想使用human.hasOwnProperty('eyes')。它通过与上述类似的链。如果在human 对象、Human.prototypeAnimal.prototype 上找不到hasOwnProperty,它将检查Object.prototpye 内部,因为

Object.getPrototypeOf(Animal.prototype) === Object.prototype

Object.prototype 有一个名为 hasOwnProperty 的方法,它将被执行

【讨论】:

  • 也就是说对象是js中的引用类型?
  • @TaraStahler 是的。我添加了更多关于原型链逻辑的信息。
  • 好吧,这样比较有道理,在自己做了一些测试之后,如果我有误解,请纠正我,原型的原型也是原始对象原型的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
  • 2021-03-02
  • 2021-11-29
  • 2011-04-16
  • 1970-01-01
相关资源
最近更新 更多