[英].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: 旁注:您设置继承链的方式很常见,并在很多示例中显示,但在两个方面不正确:
You don't want to use new Human
to create Male.prototype
. 您不想使用
new Human
来创建Male.prototype
。
You do want to call Human
from Male
: 你想叫
Human
从Male
:
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 Human
为Male
创建原型的原因很简单: 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: 该图表上的一些注释:
[[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"
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)
returntrue
but not inHuman.isPrototypeOf(albert)
(it returnfalse
) sinceMale.prototype
is an instance ofHuman
我只是无法理解为什么继承语句后我们可以做
Male.prototype.isPrototypeOf(albert)
返回true
而不是Human.isPrototypeOf(albert)
(它返回false
)因为Male.prototype
是Human
一个实例
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.