使用某些值,hasOwnProperty
调用会引发错误。
让我们检查以下代码
null.hasOwnProperty('bar') //error
undefined.hasOwnProperty('bar') //error
(0).hasOwnProperty('bar') //return false
使用null
进行调用时,除了undefined
和.hasOwnProperty
之外还有其他变量会引发错误吗?
设置对象属性的相同问题。
null.bar //error
undefined.bar //error
(0).bar === undefined //return true
谢谢
=========
编辑:
让我再加上1种情况,因为它会在我的节点环境中引发错误
在浏览器中
'use strict';
(0).bar = 0; //no thing happen
在节点v.10.3.0
(0).bar = 0; //nothing
'use' strict';
(0).bar === undefined; // return true
true.bar === undefined; // return true
''.bar = '';// STILL NOTHING HAPPEN
(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 property on it
此解决方案完全可以满足我的需求
答案 0 :(得分:2)
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:
使用参数V调用hasOwnProperty方法时,将执行以下步骤:
- 让P成为? ToPropertyKey(V)。
- 让我们成为吗? ToObject(此值)。
- 返回? HasOwnProperty(O,P)。
注意
选择步骤1和2的顺序以确保即使此值未定义或为null,也将继续抛出本规范先前版本中由步骤1引发的任何异常。
答案 1 :(得分:2)
TLDR;
Object.prototype.hasOwnProperty
可以直接在
Object.prototype
,
在其继承链中具有Object.prototype
而在继承链或对象中均未重新定义hasOwnProperty
的对象的子集,并且
布尔值,数字,字符串和符号原始值。通常,在原始值上调用它是多余的。
数据类型
JavaScript当前支持7种不同的数据类型:
布尔值,空值,未定义,数字,字符串,符号(ECMAScript 6中的新增功能)
和对象(MDN ref)
其中的前六个是原始值,而不是对象值-包括数据类型为Null的null
。 (是的,typeof null
返回“对象”,但这是早期JavaScript引擎设计的产物,无法修复,因为它会破坏网络。)
数字,布尔值和字符串
与属性值查找语法一起使用时,类型Number,布尔值和字符串类型的值分别自动转换为全局构造函数Number
,Boolean
和String
的“包装”对象实例。 / p>
因此
(1).getOwnProperty("MAX_SAFE_INTEGER")
返回false,因为该属性是从Number.prototype
继承的。类似地,对布尔值的hasOwnProperty
调用返回false,因为布尔包装器对象本身没有任何固有的属性。但是
("hello folks").hasOwnProperty("length");
返回true
,因为“ length”是字符串包装对象的专有属性。
未定义且为空
数据类型为Undefined(undefined
)或Null(null
)的原始值在尝试作为方法调用它们上的hasOwnProperty
时,不会转换为包装对象并生成语法错误:
(undefined).hasOwnProperty("example") // TypeError
(null).hasOwnProperty("example") // TypeError
符号
符号数据类型值分别处理:
通过调用Symbol()
Symbol
是一个工厂函数,具有原型属性,该属性是Object的实例。
Symbol
不能用new
运算符调用,因为它不能用作构造函数且不返回对象。
尝试获取符号值的属性或方法会有效地调用一个用于在Symbol.prototype
中查找属性/方法名称的吸气剂。
Symbol.prototype
继承自Object.prototype
,因此getter可以返回hasOwnProperty
作为方法函数。
但是,在Symbol数据类型上调用hasOwnProperty
总是返回false,因为原始类型不支持属性。
尝试设置的Symbol值的属性永远不会悄然成功。与Null和Undefined类型相同,它在严格和非严格模式下都会生成TypeError。
对象
对象(数据类型为对象)通常从hasOwnProperty
继承Object.prototype
。如果hasOwnProperty
在继承链的后面某个位置重新定义(不是个好主意),或者如果对象在继承链中是用null
创建的,则继承失败到达Object.prototype
。
在null
的继承链开始处创建对象的最简单方法是调用
Object.create( null);
扩展此类对象还会创建不继承自Object.prototype
的对象,因此不能使用hasOwnProperty
。
请注意,将instanceof Object
应用于其原型链不包含Object.prototype
的对象将返回false
。不要使用instanceof
来确定对象数据类型。
在JavaScript的早期版本中,在从原始值自动创建的包装对象上设置属性在语法上是正确的,并且不会产生错误。 但是,只要评估了包装器对象表达式,包装器对象就会被丢弃。尝试在以后的代码中查找自定义属性失败,因为没有新的包装对象(缺少该自定义属性)用于查找。
如果尝试将属性值分配给所有原始值,则严格模式会产生错误。请重新检查OP中显示的''.bar = '';
大小写-在Firefox严格模式下会引发错误。我尚未检查使用V8引擎。
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
返回一个布尔值,该布尔值反映了第一个参数是否为Object数据类型并且具有与第二个参数同名的自己的属性。对于所有原始值,它将返回false。
答案 2 :(得分:0)
我认为您可以在不是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
答案 3 :(得分:0)
您是正确的。它存在于所有未定义和为空的
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')
答案 4 :(得分:0)
如果只想检查属性的存在,而不一定要检查它们的值,那么您有两个安全的选择:hasOwnProperty()和in运算符。如果只想检测自己的属性,则应使用hasOwnProperty()属性方法。如果您想测试属性的存在而不必关心它是一个自己的属性还是一个对象属性,那么in运算符就是要使用的运算符。