- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有这段代码:
// 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);
然后,我想对代码做一些测试
Human.isPrototypeOf(albert); // I expect it to return TRUE
但它返回 FALSE,这是为什么?
并且,对于下面的测试
Human.hasOwnProperty("age"); // /i expect it to return TRUE
但它返回 FALSE,这是为什么?
谢谢,
编辑我的问题与另一个问题略有不同,因为它也是在谈论原型(prototype)链。
最佳答案
Human
albert
中的函数不的原型(prototype)链。 Human.prototype
引用的对象是:
Human.prototype.isPrototypeOf(albert); // true
Human.hasOwnProperty("age"); // /i expect it to return TRUE
Human
函数没有 age
属性(property)。 new
用它创建的实例做:
new Human().hasOwnProperty("age"); // true
旁注:您设置继承链的方式很常见,并且在很多示例中都有展示,但有两个地方不正确:
您不想使用 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;
您不使用 new Human
的原因为 Male
创建原型(prototype)很简单: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")); // true
当然,也可以使用 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
您说过您正在尝试查看链条的工作原理。这是创建 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 是规范用于对象“内部插槽”的名称,该对象包含对其原型(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)。在您的评论中:
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
因为 Human
,函数,在 albert
中无处可寻的原型(prototype)链。让我们看看albert
的原型(prototype)链:
albert
的 [[Prototype]]
是Male.prototype
Male.prototype
的 [[Prototype]]
是Human.prototype
Human.prototype
的 [[Prototype]]
是Object.prototype
Object.prototype
的 [[Prototype]]
是null
如图:
+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+ | albert | | Male.prototype | | Human.prototype | | Object.prototype |+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+ | [[Prototype]] |−−−>| [[Prototype]] |−−−>| [[Prototype]] |−−−>| [[Prototype]]: null |+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+
所以 Human
,该函数不在该链中。
关于javascript - .isPrototypeOf() 和 .hasOwnProperty() 方法混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39433397/
对版主的澄清由于一些版主在扫描问题时速度有点快,我必须强调我不是在问为什么要使用 Object.prototype.hasOwnProperty.call 而不是 myObject.hasOwnPro
代码一: obj.hasOwnProperty(prop); 代码二: const hasOwnProperty = Object.prototype; hasOwnProperty.call(obj
这个问题在这里已经有了答案: Why use Object.prototype.hasOwnProperty.call(myObj, prop) instead of myObj.hasOwnPro
也许这是一个新手问题,但我找不到或想不出解释。 启动 Node.js 控制台,然后: > global.hasOwnProperty === hasOwnProperty true 那为什么 > gl
在eslint规则中guard-for-in ,直接使用for in是不正确的。好的做法是 for (key in foo) { if (Object.prototype.hasOwnProp
如果我理解正确的话,JavaScript 中的每个对象都继承自 Object 原型(prototype),这意味着 JavaScript 中的每个对象都可以通过其原型(prototype)链访问 ha
我正在尝试让我的某些类型具有某种多重“继承”,如下所示: UIControls.ClickableMesh.prototype = Object.create(THREE.Mesh.prototype
我试图发现一个对象是否具有某些属性并且我在使用 hasOwnProperty 方法时遇到了问题。 我在数组上使用该方法(我知道文档说明了一个字符串)。 以下行返回 true: { "a": 1, "b
谁能解释一下空对象上调用的 hasOwnProperty 的作用?为什么要使用它? __hasProp = {}.hasOwnProperty 我在开始使用 coffescript 进行开发时发现了这
我想使用ES6代理来捕获以下常见代码: for (let key in trapped) { if (!Object.prototype.hasOwnProperty.call(obj, ke
使用 angularjs 和 firebase 编写一个函数,该函数应该检查是否可以在数据库中找到 currentUser。目前“attendings”属性仅包含一个用户,即“Peter Pan” 服
我有一个非常简单的问题。访问对象的属性(例如object[property])和属性的数量是否有任何性能关系?是否存在一些内部循环或其他问题,关于 hasOwnProperty - 任何循环或只是像
我试图理解为什么当我调用下面的函数时结果是“否”,因为属性 c 应该存在。有谁知道为什么?谢谢!!! var letters = function() { this.a = 5; th
在 Javascript 中查找散列中的所有值我看到了以下代码: var myHash = {}; myHash['one'] = 1; myHash['two'] = 2; for (var key
我有以下数据: trace = { "name":"foo", "dataref": { "xdata":"n", "ydata":"m" } }; 我想检查对象是否具有
通过某些值,hasOwnProperty调用将引发错误。 让我们检查以下代码 null.hasOwnProperty('bar') //error undefined.hasOwnProperty('
为什么是真的?对象中的方法foo怎么写? Object.prototype.foo = function(obj) { for(var i in obj) this[i] = obj[i];
这个问题在这里已经有了答案: JavaScript object detection: dot syntax versus 'in' keyword (5 个答案) 关闭 7 年前。 假设有一个对象
问题陈述: 如果对象具有与 JavaScript 预定义的 方法 相同的 property 名称。它无法执行并给出以下错误。 Uncaught TypeError: obj.hasOwnPropert
为什么此函数返回“No Contact”而不是“Akira”? function lookUpProfile(firstName, prop){ for(i=0;i
我是一名优秀的程序员,十分优秀!