JavaScript中的动态类型,扩展本机和hasOwnProperty()

时间:2015-09-23 11:28:41

标签: javascript

我偶然发现了一本书中的段落,

  

hasOwnProperty() 技术还需要 属性名称   作为 字符串 ,并检查 对象 是否直接具有 属性   那个实例 (而 因此不仅仅是一个继承的原型属性 )。

很好,上面的行没有问题。

在同一章后面几行,

由于JavaScript是一种动态语言,我们可能会发现修改原生对象的原型非常有用,虽然有点危险。

  

这里应说明一个非常重要的警告。实践   扩展 原生对象的原型 既有用又有用   的 危险 即可。例如,通常禁止扩展 原生   对象原型 所有其他对象继承 ),非常有用   这可能听起来,因为这样做会导致 那些属性/方法   在没有正确过滤的for-in循环中看到   hasOwnProperty()。

当他提出这条线时,他实际上是什么意思,

  

...导致 *那些属性/方法   在没有正确过滤的for-in循环中看到   *** hasOwnProperty()* ...

因为,在上面显示的一点上,他说

  

hasOwnProperty() - 将检查 对象 是否具有 属性   直接在该实例上

他们如何( 在原型 上定义的属性)无法正确过滤 的 hasOwnProperty()

这两个陈述似乎不相矛盾吗?

为了您的插图,您可以选择这个,

String.prototype.getThirdChar = function() {
return this.charAt(2);
};

然后,

var c = "Example".getThirdChar(); // c set to "a"

2 个答案:

答案 0 :(得分:1)

此示例说明了问题:

// in some file far far away
Object.prototype.foo = function() {};

// in your own code
var obj = { bar: 'bar' };
for (var i in obj) {
  console.log(i);
}

记录器将显示两个属性:bar(预期)和foo(可能不会,因为修改Object.prototype的代码通常隐藏在某个实用程序模块中的任何合理度量之外)。原因?在这里:

  

Object等内置构造函数创建的对象   从Object.prototype继承了非可枚举的属性。循环将遍历对象本身的所有可枚举属性以及对象从其构造函数原型继承的属性(属性更接近于   原型链中的对象覆盖原型'属性)。

因此,如果您想迭代对象自己的属性,您只需要重新检查该属性的所有权:

for (var i in obj) if (obj.hasOwnProperty(i)) {
  console.log(i); // just 'bar', nothing weird to see here, move along
}

注意与以下内容的区别:

答案 1 :(得分:0)

有值和原型。

o = {
    string: "is found by hasOwnProperty",
    fn: function(){}
}

Object.prototype.foo = function() {};

for(var prop in o){
    console.log(prop)
}

for(var prop in o){
    if(o.hasOwnProperty(prop){
        console.log(prop)
    }
}

首先会导致" string,fn,foo" 第二个是"字符串,fn"

但是我通常会使用很多原型扩展。有一种方法可以扩展原型而不会乱用于循环。

Object.defineProperty(Object,'boo',{
    value: function(arg){
        ...
    },
    enumerable: false // not findable in for-in
})

for(var prop in o){
    console.log(prop)
}

Object.defineProperty是键https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty