【问题标题】:When do I need to use hasOwnProperty()?什么时候需要使用 hasOwnProperty()?
【发布时间】:2015-12-02 01:50:30
【问题描述】:

我读到我们应该在循环对象时始终使用 hasOwnProperty,因为对象可以被其他东西修改以包含一些我们不想要的键。

但这总是必需的吗?有没有不需要的情况?局部变量也需要这个吗?

function my(){
  var obj = { ... };
  for(var key in obj){
    if(obj.hasOwnProperty(key)){
      safe
    }
  }
}

我只是不喜欢在不需要的情况下在循环中添加额外的 if

Death to hasOwnProperty

这家伙说我不应该再使用它了。

【问题讨论】:

    标签: javascript loops object


    【解决方案1】:

    Object.hasOwnProperty 确定整个属性是在对象本身中定义还是在原型链中定义。

    换句话说:做所谓的检查,如果你想要的属性(无论是数据还是函数)都来自对象本身。

    例如:

    function A() {
       this.x = "I'm an own property";
    }
    
    A.prototype.y = "I'm not an own property";
    
    var instance = new A();
    var xIsOwnProperty = instance.hasOwnProperty("x"); // true
    var yIsOwnProperty = instance.hasOwnProperty("y"); // false
    

    如果您只想要自己的属性,是否要避免整个检查?

    从 ECMAScript 5.x 开始,Object 有了一个新函数 Object.keys,它返回一个字符串数组,其中的项是给定对象的自身属性

    var instance = new A();
    // This won't contain "y" since it's in the prototype, so
    // it's not an "own object property"
    var ownPropertyNames = Object.keys(instance);
    

    此外,由于 ECMAScript 5.x,Array.prototype 具有 Array.prototype.forEach,让我们流畅地执行 for-each 循环

    Object.keys(instance).forEach(function(ownPropertyName) {
        // This function will be called for each found "own property", and
        // you don't need to do the instance.hasOwnProperty check any more
    });
    

    【讨论】:

    • @elad.chen 谢谢 ;P 简单但仍然高效!
    • 我会考虑添加 Object.keys(obj).forEach(..); 的用法因为这会阻止原型查找..
    • @elad.chen 对,我可以加这个。我担心的是一个简单的问答可以变成整个维基百科页面哈哈
    • 我明白了。无论如何,如果有人看到我的评论,他就会对我的意思有一个基本的了解。
    • 但想象一下我创建了自己的对象:var obj = {a: 'a', b: 'b'},我想循环访问obj。我需要按hasOwnProperty 过滤吗?
    【解决方案2】:

    当您使用for (var key in obj) 时,它将遍历原型链上的给定对象 + 其父对象的属性,直到到达链的末端。由于您只想检查特定对象的属性,因此需要使用hasOwnProperty

    for (var i = 0; i < length; i++)data.forEach() 中不需要。

    【讨论】:

      【解决方案3】:

      hasOwnProperty 期望属性名称为字符串。

      当您调用 Test.hasOwnProperty(name) 时,您将传递 name 变量的值(不存在),就像您编写 alert(name) 时一样。

      从 Object 派生的每个对象都继承hasOwnProperty 方法。该方法可用于判断一个对象是否具有指定属性作为该对象的直接属性;

      【讨论】:

        【解决方案4】:

        是的,总是和 for ... in 一起使用

        这里有一些很好的答案,描述了 hasOwnProperty() 的作用并提供了其他解决方案。
        但没有人能回答这个问题和 cmets 中的 @João 所问的问题。
        这总是需要的吗?

        换句话说, 如果对象是我的,如果我可以控制它,如果对象被定义为我自己的局部变量, 我还需要使用hasOwnProperty()吗?

        这个问题的复杂之处在于,对 Object 类型的变量的控制在这个考虑中并不重要。
        重要的是对 Object 类型本身的控制。

        如果问题稍微改写为:“如果我可以完全控制 JS 脚本、它的使用位置以及它或父范围内的所有内容,是否需要使用 hasOwnProperty()?” 那么不,您不需要使用hasOwnProperty()。 但是完全控制环境并不是你应该指望的。

        考虑这个例子

        var variableCreatedByInocentUser = { amisane: 'yes' };
        for (let key in variableCreatedByInocentUser) {
            console.log(key +'? '+ variableCreatedByInocentUser[key]);
        }
        
        console.log('-----');
        
        Object.prototype.amicrazy = 'yes, you redefined Object type';
        
        for (let key in variableCreatedByInocentUser) {
            console.log(key +'? '+ variableCreatedByInocentUser[key]);
        }
        
        console.log('-----');
        
        for (let key in variableCreatedByInocentUser) {
            if (!variableCreatedByInocentUser.hasOwnProperty(key)) { continue; }
            console.log(key +'? '+ variableCreatedByInocentUser[key]);
        }
        

        只有在某个地方有人重新定义了 Object 类型之前,才可以删除 hasOwnProperty()。 在脚本启动之前甚至之后。
        效果具有追溯力。即使您声明变量“使用原始对象类型”, 它在 JS 中不能按预期工作,重新定义的 Object 类型也会影响之前创建的此类变量。

        尽管不鼓励重新定义基本类型,但在某些框架中已经这样做了。 这样的框架可以包含并引入您的全局范围并破坏您的脚本。
        也可能存在安全问题。该对象可能会被恶意重新定义,从而使您的循环执行额外的任务。

        如果您想遵循良好的做法,您应该始终考虑所有可能的情况,例如您正在编写的代码可以被重复使用或插入,或者与另一个项目相结合。

        使用hasOwnProperty(),即使它看起来没有必要和浪费。

        【讨论】:

          猜你喜欢
          • 2017-05-23
          • 1970-01-01
          • 2012-09-16
          • 1970-01-01
          • 2017-06-17
          • 2012-10-29
          • 2013-03-17
          • 2012-08-03
          相关资源
          最近更新 更多