哪个对象的Javascript中没有`hasOwnProperty`?

时间:2018-08-24 04:31:30

标签: javascript node.js ecmascript-6 strict hasownproperty

使用某些值,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

此解决方案完全可以满足我的需求

5 个答案:

答案 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方法时,将执行以下步骤:

     
      
  1. 让P成为? ToPropertyKey(V)。
  2.   
  3. 让我们成为吗? ToObject(此值)。
  4.   
  5. 返回? HasOwnProperty(O,P)。
  6.   
     

注意

     

选择步骤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,布尔值和字符串类型的值分别自动转换为全局构造函数NumberBooleanString的“包装”对象实例。 / 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运算符就是要使用的运算符。

reference for more information click here