【问题标题】:How to check if object property exists with a variable holding the property name?如何使用包含属性名称的变量检查对象属性是否存在?
【发布时间】:2012-06-17 22:06:55
【问题描述】:

我正在检查一个对象属性是否存在,其中一个变量包含有问题的属性名称。

var myObj;
myObj.prop = "exists";
var myProp = "p"+"r"+"o"+"p";

if(myObj.myProp){
    alert("yes, i have that property");
};

这是undefined,因为它正在寻找myObj.myProp,但我希望它检查myObj.prop

【问题讨论】:

  • 可能有用:来自 Pablo Cabrera 在NCZOnline 的评论:“我认为值得注意的是,如果hasOwnProperty 方法被覆盖,您可以依赖Object.prototype.hasOwnProperty.call(object, property)。”
  • stackoverflow.com/questions/4244896/… 这个问题的副本吗?那个怎么样? “检查存在”和“访问价值”是不同的东西吗?如果我错了,请纠正我......
  • 这不是重复的。
  • @HumanInDisguise cmets 不应用于提供解决建议。您的评论本来可以更好地作为包含静态引用建议和指向其来源的链接的答案。既然@adnan2d 已经发布了这个建议,你的评论可以安全地删除了。

标签: javascript object


【解决方案1】:
var myProp = 'prop';
if(myObj.hasOwnProperty(myProp)){
    alert("yes, i have that property");
}

或者

var myProp = 'prop';
if(myProp in myObj){
    alert("yes, i have that property");
}

或者

if('prop' in myObj){
    alert("yes, i have that property");
}

请注意,hasOwnProperty 不检查继承的属性,而 in 会。例如'constructor' in myObj 是真的,但myObj.hasOwnProperty('constructor') 不是。

【讨论】:

  • hasOwnProperty()myObj[myProp] 更好(来自其他答案),因为即使myProp 的值为0,它也可以工作
  • “in”运算符不适用于字符串。例如'qqq'中的'length'会产生异常。因此,如果您想要进行通用检查,则需要使用 hasOwnProperty。
  • @Jacob 当您说“in”运算符不适用于字符串时,您是什么意思?使用 "in"' 运算符,左表达式必须是字符串或可以转换为字符串的值。是的,你不能在'qqq'中写'length',但你也不能写'qqq'.hasOwnProperty('length')
  • @Wachburn: 'qqq'.hasOwnProperty('length')true,你可以这样做。
  • 为了避免破坏 eslint no-prototype-builtins 规则,你应该使用 Object.prototype.hasOwnProperty.call(myObj, myProp) 而不是 myObj.hasOwnProperty(myProp)
【解决方案2】:

感谢大家的帮助和推动摆脱 eval 语句。 变量需要放在括号中,而不是点符号。这有效并且是干净,正确的代码。

其中每一个都是变量:appChoice、underI、underObstr。

if(typeof tData.tonicdata[appChoice][underI][underObstr] !== "undefined"){
    //enter code here
}

【讨论】:

  • 这对我来说似乎是个问题。如果tData.tonicdata[appChoice] 生成的值没有与underI 匹配的属性/索引,那么这将导致TypeError 被抛出。
  • 尽管您最初发帖的意图是,但您实际上提出的问题与您提供此答案的问题不同。你想检查一个属性的存在,你没有提到如何访问它。这使得这个答案与实际问题无关。
【解决方案3】:

你可以使用hasOwnProperty,但是根据引用你在使用这个方法时需要quotes

if (myObj.hasOwnProperty('myProp')) {
    // do something
}

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

另一种方法是使用 in 运算符,但这里也需要 引号

if ('myProp' in myObj) {
    // do something
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in

【讨论】:

  • 这就是nothasOwnProperty()是如何实现的。
  • 这是不正确的。通过在名称 myProp 周围加上引号,您不再引用 myProp 的值,而是声明了“myProp”的新 String(),并且 myObj 中没有“myProp”的此类属性。
  • TriumpST:来自上面链接的 MDN,“prop - 表示属性名称或数组索引的字符串或符号(非符号将被强制转换为字符串)。”
  • 这是正确的。如果您不想使用变量,但如果存在特定的“myProp”,则需要引号。
  • 'hasOwnProperty' 不等同于使用 'in' 运算符,正如 Rocket Hazmat 的回答所解释的那样。
【解决方案4】:

您可以使用hasOwnProperty() 以及in 运算符。

【讨论】:

  • 所有这些 ^ 是我讨厌 javascript 的原因
  • @pwaterz 不要讨厌player ?
  • 'hasOwnProperty' 不等同于使用 'in' 运算符,正如 Rocket Hazmat 的回答所解释的那样。
  • 也许你可以试着解释一下什么时候使用任何一个选项都不重要,但接受的答案很清楚
【解决方案5】:

检查对象上是否存在属性的更安全的方法是使用空对象或对象原型调用hasOwnProperty()

var foo = {
  hasOwnProperty: function() {
    return false;
  },
  bar: 'Here be dragons'
};

foo.hasOwnProperty('bar'); // always returns false

// Use another Object's hasOwnProperty and call it with 'this' set to foo
({}).hasOwnProperty.call(foo, 'bar'); // true

// It's also possible to use the hasOwnProperty property from the Object
// prototype for this purpose
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true

来自MDN Web Docs - Object.prototype.hasOwnProperty()的参考

【讨论】:

  • 如果你正在合并可能会做一些邪恶的事情的 JavaScript,比如覆盖 hasOwnProperty,那么再多的保护也不会让你的代码安全。
  • @meustrus 我知道你来自哪里,但从业务角度来看,很有可能会收到一个没有经验的开发人员会使用这个属性名称,这并不一定意味着他们是在故意做坏事。跨度>
【解决方案6】:

对于自己的财产:

var loan = { amount: 150 };
if(Object.prototype.hasOwnProperty.call(loan, "amount")) 
{ 
   //will execute
}

注意:使用Object.prototype.hasOwnProperty优于loan.hasOwnProperty(..),以防在原型链中定义了自定义hasOwnProperty(此处不是这种情况),例如

var foo = {
      hasOwnProperty: function() {
        return false;
      },
      bar: 'Here be dragons'
    };

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

要在查找结果中包含继承的属性,请使用 in 运算符:(但您必须在 'in' 的右侧放置一个对象,原始值会引发错误,例如 'length ' in 'home' 会抛出错误,但 'length' in new String('home') 不会)

const yoshi = { skulk: true };
const hattori = { sneak: true };
const kuma = { creep: true };
if ("skulk" in yoshi) 
    console.log("Yoshi can skulk");

if (!("sneak" in yoshi)) 
    console.log("Yoshi cannot sneak");

if (!("creep" in yoshi)) 
    console.log("Yoshi cannot creep");

Object.setPrototypeOf(yoshi, hattori);

if ("sneak" in yoshi)
    console.log("Yoshi can now sneak");
if (!("creep" in hattori))
    console.log("Hattori cannot creep");

Object.setPrototypeOf(hattori, kuma);

if ("creep" in hattori)
    console.log("Hattori can now creep");
if ("creep" in yoshi)
    console.log("Yoshi can also creep");

//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in

注意:人们可能会想使用 typeof 和 [ ] 属性访问器作为以下代码,这并不总是有效 ...

var loan = { amount: 150 };

loan.installment = undefined;

if("installment" in loan) // correct
{
    // will execute
}

if(typeof loan["installment"] !== "undefined") // incorrect
{
    // will not execute
}

【讨论】:

    【解决方案7】:

    检查对象属性是否存在的几种方法。

    const dog = { name: "Spot" }
    
    if (dog.name) console.log("Yay 1"); // Prints.
    if (dog.sex) console.log("Yay 2"); // Doesn't print. 
    
    if ("name" in dog) console.log("Yay 3"); // Prints.
    if ("sex" in dog) console.log("Yay 4"); // Doesn't print.
    
    if (dog.hasOwnProperty("name")) console.log("Yay 5"); // Prints.
    if (dog.hasOwnProperty("sex")) console.log("Yay 6"); // Doesn't print, but prints undefined.
    

    【讨论】:

      【解决方案8】:

      在答案中我没有看到 !! 运算符

      if (!!myObj.myProp) //Do something
      
      

      【讨论】:

      • 您能否将我链接到有关此!! 运算符的一些文档? google 高低搜索,到处都找不到,只能找到! 运算符
      • 这只是一个双重否定模式。 stackoverflow.com/questions/10467475/…
      【解决方案9】:

      有更简单的解决方案,我看不到您的实际问题的任何答案:

      “它正在寻找 myObj.myProp,但我希望它检查 myObj.prop”

      1. 要从变量中获取属性值,请使用bracket notation
      2. 要测试该属性的真实值,请使用optional chaining
      3. 要返回一个布尔值,使用double-not / bang-bang / (!!)
      4. 如果你确定你有一个对象并且只想检查属性是否存在(true 即使 prop 值未定义),请使用 in operator。或者可能与 nullish coalescing operator ?? 结合使用以避免引发错误。

      var myBadObj = undefined;
      var myGoodObj = {prop:"exists"}
      var myProp = "prop";
      
      //1 use brackets. 
      myGoodObj.myProp && console.log("wrong"); //dot is incorrect here
      //(myBadObj[myProp]) //this would throw because undefined
      myGoodObj[myProp] && console.log("1 - yes, i have that property");
      
      // 2 use optional chaining.  tolerates undefined myBadObj
      myBadObj?.[myProp] && console.log("2 - myBadObj has that");
      myGoodObj?.[myProp] && console.log("2 - myGoodObj has that");
      
      //3 get a boolean from the truthy value
      console.log(3, !!myBadObj?.[myProp]);
      console.log(3, !!myGoodObj?.[myProp]); 
      
      //4 use in operator
      //console.log(4, myProp in myBadObj); // would throw
      console.log(4, myProp in {prop:undefined});
      console.log(4, myProp in myGoodObj);
      console.log(4, myProp in (myBadObj ?? {}));
      
      //5 probably don't use hasOwnProperty()
      myProp = "hasOwnProperty";
      // doesn't catch inherited properties (ex: hasOwnProperty is itself inherited)
      console.log(5, myGoodObj.hasOwnProperty(myProp)); // false :(
      // intolerant of undefined obj
      console.log(5, myBadObj.hasOwnProperty(myProp)); // throws because undefined :(

      【讨论】:

        【解决方案10】:

        使用Object.hasOwn 方法也是一种替代方法,其目的是替换Object.hasOwnProperty 方法。

        如果指定的对象将指定的属性作为自己的属性,则此静态方法返回 true;如果该属性是继承的或该属性不存在于该对象上,则返回 false。

        请注意,在生产中使用它之前,您必须仔细检查浏览器兼容性表,因为它仍被认为是一项实验性技术,尚未得到所有浏览器的完全支持(不过很快)

            var myObj = {};
            myObj.myProp = "exists";
        
            if (Object.hasOwn(myObj, 'myProp')){
                alert("yes, i have that property");
            }

        更多关于Object.hasOwn - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn

        Object.hasOwn 浏览器兼容性 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-02
          • 2011-11-29
          • 1970-01-01
          • 2019-06-27
          • 2015-08-15
          相关资源
          最近更新 更多