简体   繁体   English

JavaScript 覆盖原型方法

[英]JavaScript overwrite prototype method

Consider the following code:考虑以下代码:

class X {
  pop() { return 'ORIGINAL'; }
}

const x = new X();

x.pop(); // 'ORIGINAL' via prototype lookup

x.pop = () => 'NEW'; // install a new pop()

x.pop(); // 'NEW' calls x's pop()

Object.getOwnPropertyDescriptors(x); // has NEW pop
Object.getOwnPropertyDescriptors(Object.getPrototypeOf(x)); // has ORIGINAL pop

When calling pop , prototype lookup finds the ORIGINAL pop .调用pop时,原型查找会找到 ORIGINAL pop Why does assignment not overwrite that one instead of installing NEW pop on x ?为什么 assignment 不覆盖那个而不是在x上安装 NEW pop

It works if I do X.prototype.pop = () => 'NEW';如果我这样做X.prototype.pop = () => 'NEW'; explicitly.明确地。

When you assign a method to an object, the method is put on the precise object that you specified in the assignment.当您将方法分配给 object 时,该方法将放在您在分配中指定的精确 object 上。 So, when you do:所以,当你这样做时:

x.pop = () => 'NEW';

You're assigning a property to the object instance x whose value is a function.您将属性分配给 object 实例x ,其值为 function。 The prototype of that object is not affected at all by this assignment. object 的原型完全不受此分配的影响。

When you execute a method on an object, the interpreter has a lookup sequence to find that method.当您在 object 上执行方法时,解释器有一个查找序列来查找该方法。 First, it looks directly on the object to see if that property exists.首先,它直接查看 object 以查看该属性是否存在。 If it finds it, that is what is executed.如果它找到它,那就是执行的。

So, when you then do:所以,当你这样做时:

x.pop()

After the previous assignment, the interpreter finds the method that assigned to the actual object and executes that one.在上一次分配之后,解释器找到分配给实际 object 的方法并执行该方法。

Before you did that method assignment, when you did x.pop() , no method/property by that name was found on the actual object instance so the interpreter, then looks to see if there is a prototype and, if there is, it then searches the prototype chain.在您执行该方法分配之前,当您x.pop()时,在实际 object 实例上没有找到该名称的方法/属性,因此解释器然后查看是否有原型,如果有,它然后搜索原型链。 That's where it found the .pop() from the class definition and executed that one.这就是它从class定义中找到.pop()并执行该定义的地方。

These are separate definitions, stored in separate places and changing one does not change the other definition.这些是单独的定义,存储在不同的位置,更改一个不会更改另一个定义。 Though assigning a definition for a specific property to the object instance itself tends to "hide" the one on the prototype just because the only way you can get access to the one on the prototype after that assignment is by directly referencing the prototype because any reference to that property through an object instance itself will just find the one on the object instance itself first (thus making it so the one on the prototype is not automatically found any more).尽管将特定属性的定义分配给 object 实例本身往往会“隐藏”原型上的属性,因为在分配后访问原型上的属性的唯一方法是直接引用原型,因为任何引用通过 object 实例本身到该属性将首先在 object 实例本身上找到一个(因此使其不再自动找到原型上的那个)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM