javascript - let o1.prototype = Object.create(o2.prototype) 和 o1.prototype = o2.prototype 有什么区别?

标签 javascript inheritance assign

所以我试图理解 o1.prototype = Object.create(o2.prototype) 之间的区别和o1.prototype = o2.prototype .

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

以下面的代码为例:

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的原型(prototype)为Object.create(o1.prototype)

另外,如果我理解正确的话,根据链接问题中的答案,如果 o1为空(在本例中就是这样)然后设置 o2 = o1与设置 o2 = Object.create(o1) 相同这也与

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

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

最佳答案

如果您直接将 Parent.prototype 分配给子级的原型(prototype),它们将指向同一个对象。因此,如果您添加一个仅适用于子类的方法,则父对象也可以访问它们,因为 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 对象下查找。如果没有找到,将在其原型(prototype) Human.prototype 中搜索。

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

由于在那里找不到 Eat 方法,因此该方法将在 Human.prototype 的原型(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 的方法,该方法将被执行

关于javascript - let o1.prototype = Object.create(o2.prototype) 和 o1.prototype = o2.prototype 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57127249/

相关文章:

c++ - 尽管覆盖仍编译错误

c++ - 错误 : class "" has no member named ""? 是否可以解决此特定情况?

python - 如何分配给字典中的列表

javascript - Mongo findOne 在数组里面

javascript - 将运营转换库与 Meteor 集成

Javascript 规范项目?

c++ - 从外部定义的类继承时无效使用不完整类型类错误

c++ - std::map 中的智能指针

c++ - 将多维数组分配给另一个

javascript - TinyMCE onPaste 不设置内容,使用上下文菜单粘贴不会触发更改事件