简体   繁体   English

.isPrototypeOf()和.hasOwnProperty()方法混淆

[英].isPrototypeOf() and .hasOwnProperty() method confusion

Let say i have this code: 假设我有这个代码:

 // Male will inherit ALL of the Human properties function Human(x, y) { // Following properties will be inherited this.name = x; this.age = y; this.test = "Test 1"; } // Following properties will ALSO be inherited Human.prototype.citizen = "USA"; Human.prototype.employer = "Google"; Human.prototype.test = "Test 2"; function Male(x, y) { // Following properties will be the own properties of Male instances this.name = x; this.age = y; this.gender = "Male"; } // Inheritance - Connecting Male object with Human object Male.prototype = new Human(); // no arguments are passed Male.prototype.constructor = Male; // correcting constructor property var albert = new Male("Albert", 25); 

Then, i want to do some testing on the code 然后,我想对代码进行一些测试

Human.isPrototypeOf(albert); // I expect it to return TRUE

But it return FALSE, why is that? 但它返回FALSE,为什么呢?

and, for the following test 并且,对于以下测试

Human.hasOwnProperty("age"); // /i expect it to return TRUE

But it return FALSE, why is that? 但它返回FALSE,为什么呢?

Thanks, 谢谢,

Edit My questions are slightly different with the other question since it's also talk about prototype chain. 编辑我的问题与其他问题略有不同,因为它也谈论原型链。

The Human function isn't in albert 's prototype chain. Human功能不在 albert的原型链中。 The object referenced by Human.prototype is: Human.prototype引用的对象是:

Human.prototype.isPrototypeOf(albert); // true

Human.hasOwnProperty("age"); Human.hasOwnProperty( “时代”); // /i expect it to return TRUE //我希望它返回TRUE

The Human function doesn't have an age property. Human函数没有age属性。 Instances created with it by new do: new创建的实例:

new Human().hasOwnProperty("age"); // true

Side note: The way you're setting up the inheritance chain is common and shown in a lot of examples, but incorrect in two ways: 旁注:您设置继承链的方式很常见,并在很多示例中显示,但在两个方面不正确:

  1. You don't want to use new Human to create Male.prototype . 您不想使用new Human来创建Male.prototype

  2. You do want to call Human from Male : 想叫HumanMale

So: 所以:

function Male(x, y) {
    // Give Human its chance to initialize the object (#2)
    Human.call(this, x, y);
    // ...
}

// Don't use new Human to create the prototype (#1)
Male.prototype = Object.create(Human.prototype);
Male.prototype.constructor = Male;

The reason you don't use new Human to create the prototype for Male is simple: Human expects arguments, but you don't have any to give it. 你不使用new HumanMale创建原型的原因很简单: Human期望参数,但你没有任何东西可以给它。

Here's an updated ES5 and earlier version of that code: 这是更新的ES5及该代码的早期版本:

 function Human(name, age) { // Argument names should be meaningful this.name = name; this.age = age; this.test = "Test 1"; } Human.prototype.citizen = "USA"; Human.prototype.employer = "Google"; Human.prototype.test = "Test 2"; function Male(name, age) { Human.call(this, name, age); this.gender = "Male"; } Male.prototype = Object.create(Human.prototype); Male.prototype.constructor = Male; var albert = new Male("Albert", 25); console.log(Human.prototype.isPrototypeOf(albert)); // true console.log(new Human().hasOwnProperty("age")); // true 

Or of course, use ES2015+ (transpiling if your target doesn't support it yet): 或者当然,使用ES2015 +(如果您的目标尚不支持,请进行转换):

 // THIS SNIPPET REQUIRES A BROWSER WITH ES2015+ SUPPORT class Human { constructor(name, age) { this.name = name; this.age = age; this.test = "Test 1"; } } Human.prototype.citizen = "USA"; Human.prototype.employer = "Google"; Human.prototype.test = "Test 2"; class Male extends Human { constructor(name, age) { super(name, age); this.gender = "Male"; } } let albert = new Male("Albert", 25); console.log(Human.prototype.isPrototypeOf(albert)); // true console.log(new Human().hasOwnProperty("age")); // true 


You've said you're trying to see how the chain works. 你已经说过你正在试图看看链是如何运作的。 Here's a diagram of what we have in memory after creating albert (with several details removed for simplicity): 这是创建albert后我们在内存中的图表(为简单起见,删除了一些细节):

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
         |                                                                      |
         \ +−−−−−−−−−−−−−−−−+                                                   |
Human−−−−−>|    function    |                                                   |
           +−−−−−−−−−−−−−−−−+                            +−−−−−−−−−−−−−−−−−−−−+ |
           | prototype      |−−−−−−−−−−−−−−−−−−−−−−−−−−−>|       object       | |    
           | name: "Human"  |                          / +−−−−−−−−−−−−−−−−−−−−+ |    
           +−−−−−−−−−−−−−−−−+                          | | constructor        |−+
                                                       | | citizen: "USA"     |
         +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | employer: "Google" |
         |                                           | | | test: "Test 2"     |
         \ +−−−−−−−−−−−−−−−−+                        | | +−−−−−−−−−−−−−−−−−−−−+
Male−−−−−−>|    function    |                        | |
           +−−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−+ | |
           | prototype      |−−−>|     object      | | |
           | name: "Male"   |  / +−−−−−−−−−−−−−−−−−+ | |
           +−−−−−−−−−−−−−−−−+  | | constructor     |−+ |
                               | | [[Prototype]]   |−−−+
           +−−−−−−−−−−−−−−−−+  | +−−−−−−−−−−−−−−−−−+
albert−−−−>|     object     |  |
           +−−−−−−−−−−−−−−−−+  |
           | name: "Albert" |  |
           | age: 25        |  |
           | gender: "Male" |  |
           | [[Prototype]]  |−−+
           +−−−−−−−−−−−−−−−−+

[[Prototype]] above is the name the spec uses for the "internal slot" of an object that contains its reference to its prototype object. [[Prototype]]是规范用于包含对其原型对象的引用的对象的“内部槽”的名称。 In contrast, prototype , the property on functions (eg, Human.prototype ), is just a normal property of functions that points to the object that new will use as the [[Prototype]] of the new object it creates if you use that function with new . 相比之下, prototype ,函数上的属性(例如, Human.prototype ),只是函数的一个普通属性,它指向new将用作它创建的新对象的[[Prototype]]的对象,如果你使用它功能与new

Some notes on that diagram: 该图表上的一些注释:

  • All functions have a [[Prototype]] internal slot that points to the object Function.prototype points to (omitted above for simplicity). 所有函数都有一个[[Prototype]]内部插槽,指向Function.prototype指向的对象(为简单起见,上面省略)。
  • Human , the function, has a name property: "Human" Human ,这个函数,有一个name属性: "Human"
  • Male , the function, has a name property: "Male" Male ,功能,有一个name属性: "Male"
  • The object albert refers to has a name property: "Albert" 对象albert指的是一个name属性: "Albert"
  • albert 's [[Prototype]] is Male.prototype ; albert[[Prototype]]Male.prototype ; Male.prototype 's [[Prototype]] is Human.prototype (and Human.prototype 's [[Prototype]] , not shown, is `Object.prototype). Male.prototype[[Prototype]]Human.prototype (和Human.prototype[[Prototype]] ,未显示,是`Object.prototype)。

In a comment you've said: 你在评论中说过:

I just can't understand why after inheritance statement we can do Male.prototype.isPrototypeOf(albert) return true but not in Human.isPrototypeOf(albert) (it return false ) since Male.prototype is an instance of Human 我只是无法理解为什么继承语句后我们可以做Male.prototype.isPrototypeOf(albert)返回true而不是Human.isPrototypeOf(albert) (它返回false )因为Male.prototypeHuman一个实例

Because Human , the function, is nowhere in albert 's prototype chain. 因为Human ,这个功能,在albert的原型链中是无处可去的。 Lets' look at albert 's prototype chain: 让我们看看albert的原型链:

  • albert 's [[Prototype]] is Male.prototype albert[[Prototype]]Male.prototype
  • Male.prototype 's [[Prototype]] is Human.prototype Male.prototype[[Prototype]]Human.prototype
  • Human.prototype 's [[Prototype]] is Object.prototype Human.prototype[[Prototype]]Object.prototype
  • Object.prototype 's [[Prototype]] is null Object.prototype[[Prototype]]null

As a diagram: 如图:

+−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−−−−−+ 
|    albert     |    | Male.prototype |    | Human.prototype |    |  Object.prototype   |
+−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−−−−−+ 
| [[Prototype]] |−−−>| [[Prototype]]  |−−−>| [[Prototype]]   |−−−>| [[Prototype]]: null |
+−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−+    +−−−−−−−−−−−−−−−−−−−−−+

So Human , the function, is nowhere in that chain. 因此, Human ,这个功能,在这个链条中无处可去。

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

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