What is the difference let o1.prototype = Object.create(o2.prototype) and o1.prototype = o2.prototype? [duplicate]

和自甴很熟 提交于 2021-02-05 06:57:05

问题


So I'm trying to understand the difference between o1.prototype = Object.create(o2.prototype) and o1.prototype = o2.prototype.

According to the answer to this question, the former sets obj2.prototype to by the prototype for obj1.prototype, but I'm having a hard time grasping why you would want that (the prototype of a new prototype for example is just Object.prototype since the prototype IS an Object without further inheritance). Furthermore, it doesn't seem to quite work the way the answer to that question suggests all the time.

In the following code, for example:

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);

both o2.prototype.test and instance1.prototype.test print "test". So it doesn't seem to matter weather you assign the o2 directly to Object.create(o1.prototype) or set the o2's prototype to Object.create(o1.prototype).

Also, if I'm understanding this correctly, according to the answer in the linked question, if o1 is empty (which is it in this case) then setting o2 = o1 would be the same as setting setting o2 = Object.create(o1) which would also be the same as

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

Is there any significant difference between those three? Also, if o2.prototype = Object.create(o1.prototype) creates an empty object with o1.prototype's prototype as it's own prototype, if o1's prototype is not empty, then how do the members of o1's prototype get imported into o2's prototype?


回答1:


If you directly assign Parent.prototype to a child's prototype, they'll both be pointing to the same object. So, if you add a method, which only applies to the child class, Parent objects will also have access to them because Parent.prototype === Child.prototype

Example:

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

If you use Object.create(Animal.prototype) instead, it creates a new object with the [[Prototype]] (also, but deprecated, __proto__) set to Anima.prototype. So, if any methods are not found on Human.prototype, it will fall back to Animal.prototype (In this case 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)

When you access, human.Eat(), first the method will looked up directly under the human object. If not found, this will be searched in its prototype which is Human.prototype.

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

Since, Eat method is not found there, the method will be looked inside the prototype of Human.prototype which is Animal.prototype

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

The method is found here and it will be executed.


Let's say you want to use human.hasOwnProperty('eyes'). It goes through the similar chain as above. If hasOwnProperty is not found on human object, Human.prototype or Animal.prototype, it will check inside Object.prototpye because

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

Object.prototype has a method called hasOwnProperty and that will be executed



来源:https://stackoverflow.com/questions/57127249/what-is-the-difference-let-o1-prototype-object-createo2-prototype-and-o1-pro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!