假设我有这个代码:
// 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);Run Code Online (Sandbox Code Playgroud)
然后,我想对代码进行一些测试
Human.isPrototypeOf(albert); // I expect it to return TRUE
Run Code Online (Sandbox Code Playgroud)
但它返回FALSE,为什么呢?
并且,对于以下测试
Human.hasOwnProperty("age"); // /i expect it to return TRUE
Run Code Online (Sandbox Code Playgroud)
但它返回FALSE,为什么呢?
谢谢,
编辑 我的问题与其他问题略有不同,因为它也谈论原型链.
该Human功能是不是在albert的原型链.引用的对象Human.prototype是:
Human.prototype.isPrototypeOf(albert); // true
Run Code Online (Sandbox Code Playgroud)
Human.hasOwnProperty( "时代"); //我希望它返回TRUE
该Human函数没有age属性.用它创建的实例new:
new Human().hasOwnProperty("age"); // true
Run Code Online (Sandbox Code Playgroud)
旁注:您设置继承链的方式很常见,并在很多示例中显示,但在两个方面不正确:
你不想new Human用来创建Male.prototype.
你也想打电话Human从Male:
所以:
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;
Run Code Online (Sandbox Code Playgroud)
你不用new Human来创建原型的原因Male很简单:Human期望参数,但你没有任何给它.
这是更新的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")); // trueRun Code Online (Sandbox Code Playgroud)
或者当然,使用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")); // trueRun Code Online (Sandbox Code Playgroud)
你已经说过你正试图看看连锁店是如何运作的.这是我们在创建后在内存中的图表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]]以上是规范用于包含对其原型对象的引用的对象的"内部槽"的名称.相反,prototype函数(例如Human.prototype)上的属性只是函数的一个普通属性,它指向new将[[Prototype]]使用该函数时将创建的新对象的对象new.
该图表上的一些注释:
[[Prototype]]指向对象Function.prototype指向的内部插槽(为简单起见,上面省略了).Human,该函数,有一个name属性:"Human"Male,该函数,有一个name属性:"Male"albert指的是具有以下name属性:"Albert"albert的[[Prototype]]是Male.prototype; Male.prototype的[[Prototype]]是Human.prototype(和Human.prototype的[[Prototype]],未示出,是`Object.prototype中).你在评论中说过:
我只是无法理解为什么在继承语句之后我们可以
Male.prototype.isPrototypeOf(albert)返回true而不是Human.isPrototypeOf(albert)(它返回false)因为Male.prototype是一个实例Human
因为Human,这个功能,在albert原型链中是无处可去的.让我们看看albert原型链:
albert的[[Prototype]]是Male.prototypeMale.prototype的[[Prototype]]是Human.prototypeHuman.prototype的[[Prototype]]是Object.prototypeObject.prototype的[[Prototype]]是null如图:
+???????????????+ +????????????????+ +?????????????????+ +?????????????????????+ | albert | | Male.prototype | | Human.prototype | | Object.prototype | +???????????????+ +????????????????+ +?????????????????+ +?????????????????????+ | [[Prototype]] |???>| [[Prototype]] |???>| [[Prototype]] |???>| [[Prototype]]: null | +???????????????+ +????????????????+ +?????????????????+ +?????????????????????+
因此Human,该功能在该链中无处可去.
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |