JavaScript 中哪个对象没有 `hasOwnProperty`?
Which object does not have `hasOwnProperty` in JavaScript?
对于某些值,调用 hasOwnProperty
会引发错误。
让我们检查以下代码:
null.hasOwnProperty('bar') // Error
undefined.hasOwnProperty('bar') // Error
(0).hasOwnProperty('bar') // Returns false
是否有任何其他变量而不是 null
和 undefined
在使用 .hasOwnProperty
调用时抛出错误?
同题设置对象的属性:
null.bar // Error
undefined.bar // Error
(0).bar === undefined // Returns true
=========
它在我的 Node.js 环境中引发错误的另一种情况:
在浏览器中
'use strict';
(0).bar = 0; // Nothing happens
在 Node.js v.10.3.0 中:
(0).bar = 0; // Nothing
'use' strict';
(0).bar === undefined; // Returns true
true.bar === undefined; // Returns true
''.bar = '';// STILL NOTHING HAPPENS
(0).bar = 0; //TypeError: Cannot create property 'bar' on number '0'
(true).bar = true; // TypeError: Cannot create property 'bar' on boolean 'true'
========
最终,我找到了Check if a value is an object in JavaScript:
if (obj instanceof Object) obj.hasOwnProperty(...) // Or set a property on it
这个解决方案完全满足我的需求。
Using hasOwnProperty as a property name:
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
还要注意最新的draft:
When the hasOwnProperty method is called with argument V, the following steps are taken:
- Let P be ? ToPropertyKey(V).
- Let O be ? ToObject(this value).
- Return ? HasOwnProperty(O, P).
NOTE
The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.
我认为您可以在任何不是 undefined
或 null
.
的变量上调用它
console.log([1].hasOwnProperty(0)); // true
console.log([1,2].hasOwnProperty(1)); // true
console.log([1,2].hasOwnProperty(2)); // false
console.log({ a: 's'}.hasOwnProperty('a')); // true
console.log({ b: 's'}.hasOwnProperty('a')); // false
console.log({}.hasOwnProperty('a')); // false
console.log((555).hasOwnProperty('a')); // false
console.log((false).hasOwnProperty('a')); // false
console.log((true).hasOwnProperty('a')); // false
console.log(("skjhkdasj").hasOwnProperty('a')); // false
console.log((1.045).hasOwnProperty('a')); // false
// console.log((null).hasOwnProperty('a')); // error
// console.log((undefined).hasOwnProperty('a')); // error
你是对的。它存在于除了未定义和 NULL
之外的所有事物上
class Vehicle {
constructor(name, type) {
this.name = name;
this.type = type;
}
}
class Car extends Vehicle {
constructor(color) {
super()
this.color = color
}
}
console.log(new Car().hasOwnProperty('color'))
console.log(new Car().hasOwnProperty('name'))
console.log(new Vehicle().hasOwnProperty('color'))
console.log(new Vehicle().hasOwnProperty('name'))
function foo() {}
foo.hasOwnProperty('bar')
true.hasOwnProperty('bar')
const symbol = Symbol();
Symbol.hasOwnProperty('bar')
symbol.hasOwnProperty('bar')
Boolean.hasOwnProperty('bar')
String.hasOwnProperty('bar')
Array.hasOwnProperty('bar')
Number.hasOwnProperty('bar')
Object.hasOwnProperty('bar')
Car.hasOwnProperty('bar');
[].hasOwnProperty('bar');
"".hasOwnProperty('bar');
(1).hasOwnProperty('bar');
//null.hasOwnProperty('bar')
//undefined.hasOwnProperty('bar')
如果您只想检查属性是否存在,而不一定要检查它们的值可能是多少,那么您有两个安全的选择:hasOwnProperty() 和 in 运算符。如果您只想检测自己的属性,则应使用 hasOwnProperty() 属性 方法。如果你想测试 属性 是否存在,而不关心它是一个自己的 属性 还是一个对象 属性,那么 in 运算符就是要使用的。
TLDR;
Object.prototype.hasOwnProperty
可以直接在
上调用
Object.prototype
,
在其继承链中具有 Object.prototype
且未在继承链或对象上重新定义 hasOwnProperty
的对象子集,并且
BigInt、Boolean、Number、String 和 Symbol 原始值。在原始值上调用它通常是多余的,但是
(primitiveValue).hasOwnProperty(propertyName)
总是返回 false
- 原始值没有自己的属性。
数据类型
JavaScript目前在ECMAScript 2020规范中支持八种不同的数据类型:
BigInt (introduced in ECMAScript 2020), Boolean, Null, Undefined, Number, String, Symbol (new in ECMAScript 2015)
and Object.
其中前七个是原始值而不是对象值 - 包括数据类型为 Null 的 null
。 (是的,typeof null
return 的“对象”而不是“空”,但这是早期 JavaScript 引擎设计的产物,无法修复,因为它会破坏网络。 )
数字、布尔值和字符串
Number、Boolean 和 String 类型的值在与 [=180= 一起使用时分别自动转换为全局构造函数 Number
、Boolean
和 String
的“包装”对象实例] 值查找语法。
因此
(1).hasOwnProperty("MAX_SAFE_INTEGER")
returns false 因为 属性 继承自 Number.prototype
。类似地,hasOwnProperty
调用布尔值 return false,因为布尔包装对象本身没有任何固有的属性。但是
("hello folks").hasOwnProperty("length");
returnstrue
因为“长度”是 String 包装器对象自己的 属性。
未定义且为空
数据类型未定义 (undefined
) 或 Null (null
) 的原始值不会转换为包装器对象,并且在尝试对它们调用 hasOwnProperty
时会生成语法错误方法:
(undefined).hasOwnProperty("example") // TypeError
(null).hasOwnProperty("example") // TypeError
符号和 BigInt
Symbol 和 BigInt 数据类型值有不同的处理 - 它们都是在 ECMAScript 中的新数据类型没有对象包装器的决定之后引入的。
实际上这意味着 JavaScript 引擎在内部实现了将 Symbol.prototype
和 BigInt.prototype
方法分别应用于 symbol
和 bigint
数据类型的语法,但只允许对原型方法和属性进行读取访问 - 任何在 symbol
或 bigint
数据类型上设置 属性 的尝试都会产生错误。
Symbol
和 BigInt
全局函数都不允许在调用它们之前使用 new
。
Symbol
充当工厂函数并且 return 是一个新的符号值。
BigInt
是一个类型转换函数,将字符串和数字转换为bigint
数据类型。
与 boolean
、number
和 string
数据类型的旧对象包装器不同,尝试 设置 属性symbol
或 bigint
数据类型永远不会成功。
对象
对象(数据类型为 Object)通常从 Object.prototype
继承 hasOwnProperty
。如果 hasOwnProperty
在继承链的后面某处重新定义( 不是一个好主意),或者如果对象是在其对象中使用 null
创建的,则此继承可能会失败到达 Object.prototype
.
之前的继承链
在其继承链的开头创建具有 null
的对象的最简单方法是调用
Object.create( null);
扩展这样的对象也会创建不继承自 Object.prototype
的对象,因此不能使用 hasOwnProperty
.
请注意,将instanceof Object
应用于原型链不包含Object.prototype
returns false
的对象。不要使用 instanceof
来确定对象数据类型。
包装器对象和严格模式。
在 JavaScript 的早期版本中,在从原始值自动创建的包装器对象上设置属性在语法上是正确的,并且不会产生错误。 但是,一旦包装对象表达式被求值,包装对象就被丢弃了。尝试在后面的代码中查找自定义 属性 失败,因为缺少自定义 属性 的新的不同包装对象用于查找。
如果尝试将 属性 值分配给任何原始值,严格模式会产生错误。
可能的检查功能
const checkOwnProperty = (obj, propertyName) =>
(obj && (typeof obj == "object" || typeof obj == "function") &&
Object.prototype.hasOwnProperty.call( obj, propertyName))
? true : false;
// Test:
var o = {name: "foo"};
console.log ( "name " + checkOwnProperty( o, "name"))
console.log ( "foo " + checkOwnProperty( o, "foo"))
console.log ( "0 " + checkOwnProperty( 0, "foo"))
CheckOwnProperty
returns 一个布尔值,反映第一个参数是否为 Object 数据类型 并且 有自己的同名 属性作为第二个参数。对于所有原始值,它 return 都是假的。
对于某些值,调用 hasOwnProperty
会引发错误。
让我们检查以下代码:
null.hasOwnProperty('bar') // Error
undefined.hasOwnProperty('bar') // Error
(0).hasOwnProperty('bar') // Returns false
是否有任何其他变量而不是 null
和 undefined
在使用 .hasOwnProperty
调用时抛出错误?
同题设置对象的属性:
null.bar // Error
undefined.bar // Error
(0).bar === undefined // Returns true
=========
它在我的 Node.js 环境中引发错误的另一种情况:
在浏览器中
'use strict';
(0).bar = 0; // Nothing happens
在 Node.js v.10.3.0 中:
(0).bar = 0; // Nothing
'use' strict';
(0).bar === undefined; // Returns true
true.bar === undefined; // Returns true
''.bar = '';// STILL NOTHING HAPPENS
(0).bar = 0; //TypeError: Cannot create property 'bar' on number '0'
(true).bar = true; // TypeError: Cannot create property 'bar' on boolean 'true'
========
最终,我找到了Check if a value is an object in JavaScript:
if (obj instanceof Object) obj.hasOwnProperty(...) // Or set a property on it
这个解决方案完全满足我的需求。
Using hasOwnProperty as a property name:
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
还要注意最新的draft:
When the hasOwnProperty method is called with argument V, the following steps are taken:
- Let P be ? ToPropertyKey(V).
- Let O be ? ToObject(this value).
- Return ? HasOwnProperty(O, P).
NOTE
The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.
我认为您可以在任何不是 undefined
或 null
.
console.log([1].hasOwnProperty(0)); // true
console.log([1,2].hasOwnProperty(1)); // true
console.log([1,2].hasOwnProperty(2)); // false
console.log({ a: 's'}.hasOwnProperty('a')); // true
console.log({ b: 's'}.hasOwnProperty('a')); // false
console.log({}.hasOwnProperty('a')); // false
console.log((555).hasOwnProperty('a')); // false
console.log((false).hasOwnProperty('a')); // false
console.log((true).hasOwnProperty('a')); // false
console.log(("skjhkdasj").hasOwnProperty('a')); // false
console.log((1.045).hasOwnProperty('a')); // false
// console.log((null).hasOwnProperty('a')); // error
// console.log((undefined).hasOwnProperty('a')); // error
你是对的。它存在于除了未定义和 NULL
之外的所有事物上class Vehicle {
constructor(name, type) {
this.name = name;
this.type = type;
}
}
class Car extends Vehicle {
constructor(color) {
super()
this.color = color
}
}
console.log(new Car().hasOwnProperty('color'))
console.log(new Car().hasOwnProperty('name'))
console.log(new Vehicle().hasOwnProperty('color'))
console.log(new Vehicle().hasOwnProperty('name'))
function foo() {}
foo.hasOwnProperty('bar')
true.hasOwnProperty('bar')
const symbol = Symbol();
Symbol.hasOwnProperty('bar')
symbol.hasOwnProperty('bar')
Boolean.hasOwnProperty('bar')
String.hasOwnProperty('bar')
Array.hasOwnProperty('bar')
Number.hasOwnProperty('bar')
Object.hasOwnProperty('bar')
Car.hasOwnProperty('bar');
[].hasOwnProperty('bar');
"".hasOwnProperty('bar');
(1).hasOwnProperty('bar');
//null.hasOwnProperty('bar')
//undefined.hasOwnProperty('bar')
如果您只想检查属性是否存在,而不一定要检查它们的值可能是多少,那么您有两个安全的选择:hasOwnProperty() 和 in 运算符。如果您只想检测自己的属性,则应使用 hasOwnProperty() 属性 方法。如果你想测试 属性 是否存在,而不关心它是一个自己的 属性 还是一个对象 属性,那么 in 运算符就是要使用的。
TLDR;
Object.prototype.hasOwnProperty
可以直接在
Object.prototype
,在其继承链中具有
Object.prototype
且未在继承链或对象上重新定义hasOwnProperty
的对象子集,并且BigInt、Boolean、Number、String 和 Symbol 原始值。在原始值上调用它通常是多余的,但是
(primitiveValue).hasOwnProperty(propertyName)
总是返回
false
- 原始值没有自己的属性。
数据类型
JavaScript目前在ECMAScript 2020规范中支持八种不同的数据类型:
BigInt (introduced in ECMAScript 2020), Boolean, Null, Undefined, Number, String, Symbol (new in ECMAScript 2015)
and Object.
其中前七个是原始值而不是对象值 - 包括数据类型为 Null 的 null
。 (是的,typeof null
return 的“对象”而不是“空”,但这是早期 JavaScript 引擎设计的产物,无法修复,因为它会破坏网络。 )
数字、布尔值和字符串
Number、Boolean 和 String 类型的值在与 [=180= 一起使用时分别自动转换为全局构造函数 Number
、Boolean
和 String
的“包装”对象实例] 值查找语法。
因此
(1).hasOwnProperty("MAX_SAFE_INTEGER")
returns false 因为 属性 继承自 Number.prototype
。类似地,hasOwnProperty
调用布尔值 return false,因为布尔包装对象本身没有任何固有的属性。但是
("hello folks").hasOwnProperty("length");
returnstrue
因为“长度”是 String 包装器对象自己的 属性。
未定义且为空
数据类型未定义 (undefined
) 或 Null (null
) 的原始值不会转换为包装器对象,并且在尝试对它们调用 hasOwnProperty
时会生成语法错误方法:
(undefined).hasOwnProperty("example") // TypeError
(null).hasOwnProperty("example") // TypeError
符号和 BigInt
Symbol 和 BigInt 数据类型值有不同的处理 - 它们都是在 ECMAScript 中的新数据类型没有对象包装器的决定之后引入的。
实际上这意味着 JavaScript 引擎在内部实现了将 Symbol.prototype
和 BigInt.prototype
方法分别应用于 symbol
和 bigint
数据类型的语法,但只允许对原型方法和属性进行读取访问 - 任何在 symbol
或 bigint
数据类型上设置 属性 的尝试都会产生错误。
Symbol
和BigInt
全局函数都不允许在调用它们之前使用new
。Symbol
充当工厂函数并且 return 是一个新的符号值。BigInt
是一个类型转换函数,将字符串和数字转换为bigint
数据类型。与
boolean
、number
和string
数据类型的旧对象包装器不同,尝试 设置 属性symbol
或bigint
数据类型永远不会成功。
对象
对象(数据类型为 Object)通常从 Object.prototype
继承 hasOwnProperty
。如果 hasOwnProperty
在继承链的后面某处重新定义( 不是一个好主意),或者如果对象是在其对象中使用 null
创建的,则此继承可能会失败到达 Object.prototype
.
在其继承链的开头创建具有 null
的对象的最简单方法是调用
Object.create( null);
扩展这样的对象也会创建不继承自 Object.prototype
的对象,因此不能使用 hasOwnProperty
.
请注意,将instanceof Object
应用于原型链不包含Object.prototype
returns false
的对象。不要使用 instanceof
来确定对象数据类型。
包装器对象和严格模式。
在 JavaScript 的早期版本中,在从原始值自动创建的包装器对象上设置属性在语法上是正确的,并且不会产生错误。 但是,一旦包装对象表达式被求值,包装对象就被丢弃了。尝试在后面的代码中查找自定义 属性 失败,因为缺少自定义 属性 的新的不同包装对象用于查找。
如果尝试将 属性 值分配给任何原始值,严格模式会产生错误。
可能的检查功能
const checkOwnProperty = (obj, propertyName) =>
(obj && (typeof obj == "object" || typeof obj == "function") &&
Object.prototype.hasOwnProperty.call( obj, propertyName))
? true : false;
// Test:
var o = {name: "foo"};
console.log ( "name " + checkOwnProperty( o, "name"))
console.log ( "foo " + checkOwnProperty( o, "foo"))
console.log ( "0 " + checkOwnProperty( 0, "foo"))
CheckOwnProperty
returns 一个布尔值,反映第一个参数是否为 Object 数据类型 并且 有自己的同名 属性作为第二个参数。对于所有原始值,它 return 都是假的。