hasOwnProperty(" foo")总是返回true,即使我将foo指定为undefined - 为什么?

时间:2017-07-19 04:28:12

标签: javascript conditional-operator

如果条件为真,我想将对象的属性设置为某些东西,否则什么都不做。

我试图通过

使用?运算符
obj.prop = (...)?sth:null;

obj.prop = (...)?sth:undefined;

但事实证明,其中一个人可以执行我想要的任务。

鉴于条件是假的,当我打电话给obj.hasOwnProperty(prop)时,它总是给我真实的。

有办法吗?

我知道我可以使用if语法来实现,但我只想知道是否可以使用?运算符执行相同的操作。

2 个答案:

答案 0 :(得分:1)

分配如下属性时:

var obj = {
    a : undefined // or any other value
};

根据ECMAScript规范发生这种情况:

  

11.1.5对象初始化

     

[...]

     

生产PropertyNameAndValueList:PropertyAssignment的计算方法如下:

     
      
  1. 让obj成为创建新对象的结果,就好像通过表达式new Object()一样,其中Object是具有该名称的标准内置构造函数。
  2.   
  3. 让propId成为评估PropertyAssignment的结果。
  4.   
  5. 使用参数propId.name,propId.descriptor和false调用obj的[[DefineOwnProperty]]内部方法。
  6.   
  7. 返回obj。
  8.   

分配如下属性时:

obj.a = undefined;

根据ECMAScript规范发生这种情况:

  

8.12.5 [[Put]](P,V,Throw)

     

[...]

     
      
  1. 否则,在对象O上创建名为P的命名数据属性,如下所示   一个。让newDesc成为属性描述符       {[[Value]]:V,[[Writable]]:true,[[Enumerable]]:true,[[Configurable]]:true}。    湾调用O的[[DefineOwnProperty]]内部方法,将P,newDesc和Throw作为参数传递。
  2.   

在任何一种情况下,由于undefinednull都是legimite值,因此只会使用此值定义属性。

最后,hasOwnProperty()只会检查是否创建了属性描述符,值无关紧要:

  

15.2.4.5 Object.prototype.hasOwnProperty(V)

     

[...]

     
      
  1. 设desc是调用O的[[GetOwnProperty]]内部方法传递P作为参数的结果。
  2.   
  3. 如果未定义desc,则返回false。
  4.   
  5. 返回true。
  6.   

但是,根据ECMAScript规范,设置为undefined的属性和未设置属性,如果您访问它们将返回undefined

  

8.12.3 [[Get]](P)

     

[...]

     
      
  1. 如果未定义desc,请返回undefined。
  2.   
  3. 如果IsDataDescriptor(desc)为true,则返回desc。[[Value]]。
  4.   
  5. 否则,IsAccessorDescriptor(desc)必须为true,所以让getter为desc。[[Get]]。
  6.   
  7. 如果未定义getter,请返回undefined。
  8.   
  9. 返回调用getter的[[Call]]内部方法的结果,提供O作为该值并且不提供参数。
  10.   

证明:

var obj = {
  a : undefined
}

console.log(typeof obj.a); // undefined
console.log(typeof obj.b); // undefined
obj.hasOwnProperty('a') // true
obj.hasOwnProperty('b') // false

只有delete才会删除该属性。

var obj = {
  a : null,
  b : undefined
}

obj.hasOwnProperty('a') // true
obj.hasOwnProperty('b') // true

delete obj.a;
delete obj.b;

obj.hasOwnProperty('a') // false
obj.hasOwnProperty('b') // false

阅读delete上的ECMAScript规范留待读者阅读。

答案 1 :(得分:0)

假设你的病情结果是虚假的,那么这样的事情应该有效。 All falsey values in JavaScript

var obj = {

  a: true,
  b: false,

}

obj.prop1 = obj.a ? true : false;
obj.prop2 = obj.b ? true : false;

console.log(obj);