【发布时间】:2014-04-22 02:53:59
【问题描述】:
我知道 JavaScript 中的 hasOwnProperty 方法仅用于识别当前类型的属性,但这里的原型链中有一些东西让我感到困惑。
假设我定义了一个名为 Bob 的类型,并以两种不同的方式将两个子函数分配给我的 Bob 类型:
function Bob()
{
this.name="Bob";
this.sayGoodbye=function()
{
console.log("goodbye");
}
}
Bob.prototype.sayHello= function()
{
console.log("hello");
}
现在除了在sayGoodbye 的情况下可以访问闭包范围之外,在我看来,属于Bob 类的两个函数应该或多或少相等。但是,当我使用 hasOwnProperty 查找它们时,就 JavaScript 而言,它们并不相同:
var myBob = new Bob();
console.log( myBob.name ); // Bob, obviously
console.log( myBob.hasOwnProperty("sayHello")); // false
console.log( myBob.hasOwnProperty("sayGoodbye")); // true
console.log( "sayHello" in myBob ); // true
就范围而言,这里发生了什么?如果没有连接sayHello() 和sayGoodbye() 属性,我无法创建Bob 类型的实例,那么就hasOwnProperty 而言,为什么原型方法是二等公民呢? Bob.prototype 是一种以某种方式独立于 Bob 类型而存在的类型,Bob 从中继承了一切吗?
【问题讨论】:
-
hasOwnProperty的存在只是为了检查对象本身的属性,它明确地不会沿着原型链向上走,因为这会破坏目的。 -
我想要澄清的是为什么
hasOwnProperty无法识别类型自己原型上的属性。 -
属性访问与范围无关,完全不同。
-
@glenatron - 真正的答案是因为
hasOwnProperty()就是这样设计的。它只直接检查对象的属性,而不是原型链中的任何地方。我可以看到一个不同函数的基本原理,它告诉你属性是在对象上还是在它自己的原型中,但这不是.hasOwnProperty()的目的。你可以写一个这样的函数。 -
@glenatron — 第一步是认识到范围与属性访问无关。第一个与lexical environment 中的变量解析有关,另一个与对象及其
[[Prototype]]链上的property name 解析有关。
标签: javascript prototype hasownproperty