为什么hasOwnProperty无法识别对象原型上的函数?

时间:2014-03-17 00:56:50

标签: javascript prototype hasownproperty

我知道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

这里的范围是什么?如果没有连接BobsayHello()属性,我无法创建sayGoodbye()类型的实例,那么为什么原型方法成为第二类公民{{1} } 被关注到? hasOwnProperty是一种独立于Bob.prototype类型存在的类型,Bob是否继承了所有类型?

2 个答案:

答案 0 :(得分:12)

我认为你在这里混淆了一些概念。让我们从MDN

中引用这句话
  

来自Object的每个对象都继承了hasOwnProperty方法。   此方法可用于确定对象是否具有   指定属性为该对象的直接属性;与in不同   运算符,此方法不会检查对象的原型   链

这就是关键所在。当您使用new时,JavaScript会将一个全新的对象分配给this并返回它,这就是一个实例。在构造函数中声明的任何属性都是自己的属性。在prototype上声明的属性不是,因为它们与同一对象的其他实例共享。

prototype也是Object,例如:

Bob.prototype.hasOwnProperty("sayHello"); //=> true

myBob.constructor.prototype.hasOwnProperty("sayHello"); //=> true

答案 1 :(得分:3)

  

据我所知,JavaScript中的hasOwnProperty方法仅用于识别当前类型的属性

这是不正确的。 hasOwnProperty标识对象的自己的属性,即对象本身的属性。它不考虑对象的[[Prototype]]链上的继承属性。

e.g。

var foo = {name: 'foo'};

// Check for an own property
foo.hasOwnProperty('name'); // true

对象 foo 还从Object.prototype继承了 toString 方法,但它不是“自己的”属性:

typeof foo.toString             // function
foo.hasOwnProperty('toString'); // false