简体   繁体   English

JavaScript 中哪个对象没有 `hasOwnProperty`?

[英]Which object does not have `hasOwnProperty` in JavaScript?

With some values, calling hasOwnProperty throws an error.对于某些值,调用hasOwnProperty会引发错误。

Let's check the following code:让我们检查以下代码:

null.hasOwnProperty('bar') // Error
undefined.hasOwnProperty('bar') // Error
(0).hasOwnProperty('bar') // Returns false

Are there any other variables rather than null and undefined that throws an error when calling with .hasOwnProperty ?在使用.hasOwnProperty调用时,是否还有其他变量而不是nullundefined会引发错误?

The same question for setting an object's property:设置对象属性的相同问题:

null.bar // Error
undefined.bar // Error
(0).bar === undefined // Returns true

========= ==========

Another case where it throws an error in my Node.js environment:在我的 Node.js 环境中抛出错误的另一种情况:

In a browser在浏览器中

'use strict';
(0).bar = 0; // Nothing happens

In Node.js v.10.3.0:在 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'

======== ========

Eventually, I found Check if a value is an object in JavaScript :最后,我发现在 JavaScript 中检查一个值是否是一个对象

if (obj instanceof Object) obj.hasOwnProperty(...) // Or set a property on it

This solution totally fulfills my needs.该解决方案完全满足我的需求。

Using hasOwnProperty as a property name : 使用 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

Also take care to the latest draft :还要注意最新的草稿

When the hasOwnProperty method is called with argument V, the following steps are taken:当使用参数 V 调用 hasOwnProperty 方法时,将采取以下步骤:

  1. Let P be ?让 P ? ToPropertyKey(V). ToPropertyKey(V)。
  2. Let O be ?让 O 成为? ToObject(this value). ToObject(这个值)。
  3. Return ?返回 ? HasOwnProperty(O, P). 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.选择第 1 步和第 2 步的顺序是为了确保即使 this 值为 undefined 或 null,本规范先前版本中第 1 步会抛出的任何异常仍将继续抛出。

TLDR; TLDR;

Object.prototype.hasOwnProperty can be called directly on Object.prototype.hasOwnProperty可以直接调用

  • Object.prototype , Object.prototype

  • The subset of objects which have Object.prototype in their inheritance chain and don't redefine hasOwnProperty in either the inheritance chain or on the object, and在继承链中具有Object.prototype并且不在继承链或对象上重新定义hasOwnProperty的对象子集,以及

  • BigInt, Boolean, Number, String and Symbol primitive values. BigInt、Boolean、Number、String 和 Symbol 原始值。 Calling it on primitive values is generally superfluous however as然而,在原始值上调用它通常是多余的

     (primitiveValue).hasOwnProperty(propertyName)

    always rerturns false - primitive values do not have own properties.总是返回false - 原始值没有自己的属性。


Data Types数据类型

JavaScript currently supports eight different data types in the ECMAScript 2020 specification: JavaScript 目前在ECMAScript 2020规范中支持八种不同的数据类型:

BigInt (introduced in ECMAScript 2020), Boolean, Null, Undefined, Number, String, Symbol (new in ECMAScript 2015) BigInt(在 ECMAScript 2020 中引入)、Boolean、Null、Undefined、Number、String、Symbol(ECMAScript 2015 中的新功能)
and Object.和对象。

The first seven of these are primitive values rather than object values - including null which is of data type Null.这些前七个是原始值,而不是对象值-包括null这是数据类型为NULL。 (Yes, typeof null returns "object" instead of "null", but this is an artifact of early JavaScript engine design that can't be fixed because it would break the web.) (是的, typeof null返回“object”而不是“null”,但这是早期 JavaScript 引擎设计的产物,无法修复,因为它会破坏网络。)

Number, Boolean and String数字、布尔值和字符串

Values of type Number, Boolean and String are automatically converted into "wrapper" object instances of global constructors Number , Boolean and String respectively when used with property value lookup syntax.当与属性值查找语法一起使用时,Number、Boolean 和 String 类型的值分别自动转换为全局构造函数NumberBooleanString “包装器”对象实例。

Hence因此

(1).hasOwnProperty("MAX_SAFE_INTEGER")

returns false because the property is inherited from Number.prototype .返回 false 因为该属性是从Number.prototype继承的。 Similarly hasOwnProperty calls on Boolean values return false because Boolean wrapper objects don't have any innate own properties themselves.类似地,对布尔值的hasOwnProperty调用返回 false,因为布尔包装对象本身没有任何固有的属性。 But

("hello folks").hasOwnProperty("length");

returns true because "length" is an own property of the String wrapper object.返回true因为“长度”是 String 包装器对象自己的属性。

Undefined and Null未定义和空

Primitive values of data type Undefined ( undefined ) or Null ( null ) are not converted to wrapper objects and generate syntax errors when attempting to call hasOwnProperty on them as a method:数据类型 Undefined ( undefined ) 或 Null ( null ) 的原始值不会转换为包装器对象,并在尝试将其作为方法调用hasOwnProperty时生成语法错误:

    (undefined).hasOwnProperty("example")  // TypeError
    (null).hasOwnProperty("example")       // TypeError

Symbol and BigInt符号和 BigInt

Symbol and BigInt data type values have separate treatment - they were both introduced following a decision that new data types in ECMAScript would not have object wrappers. Symbol 和 BigInt 数据类型值有单独的处理——它们都是在 ECMAScript 中的新数据类型没有对象包装器的决定之后引入的。

Effectively this means that the JavaScript engine internally implements the syntax of applying Symbol.prototype and BigInt.prototype methods to symbol and bigint data types respectively, but only allows read access to prototyped methods and properties - any attempt to set a property on a symbol or bigint data type generates an error.实际上,这意味着 JavaScript 引擎在内部实现了将Symbol.prototypeBigInt.prototype方法分别应用于symbolbigint数据类型的语法,但只允许对原型方法和属性进行读取访问 - 任何尝试在symbol上设置属性或bigint数据类型生成错误。

  • Neither the Symbol nor BigInt global functions allow the use of new before calls to them. SymbolBigInt全局函数都不允许在调用它们之前使用new

  • Symbol acts a factory function and returns a new symbol value. Symbol充当工厂函数并返回一个新的符号值。

  • BigInt is a type conversion function to convert strings and numbers to bigint data type. BigInt是一个类型转换函数,用于将字符串和数字转换为bigint数据类型。

  • Unlike older object wrappers for boolean , number and string data types, attempting to set properties on a symbol or bigint data type never quietly succeeds.booleannumberstring数据类型的旧对象包装器不同,尝试在symbolbigint数据类型上设置属性永远不会悄然成功。

Object目的

Objects ( of data type Object) generally inherit hasOwnProperty from Object.prototype .对象(数据类型为 Object)通常从Object.prototype继承hasOwnProperty This inheritance can fail if either hasOwnProperty is redefined somewhere later in the inheritance chain ( not a good idea ), or if the object was created with null in its inheritance chain before reaching Object.prototype .如果hasOwnProperty在继承链后面的某个地方重新定义(不是一个好主意),或者如果在到达Object.prototype之前在其继承链中使用null创建对象,则此继承可能会失败。

The easiest way to create an object with null at the start of its inheritance chain is by calling在继承链的开头创建一个null对象的最简单方法是调用

Object.create( null);

Extending such an object will also create objects which don't inherit from Object.prototype and so can't use hasOwnProperty .扩展这样的对象也会创建不从Object.prototype继承的对象,因此不能使用hasOwnProperty

Note that applying instanceof Object to an object whose prototype chain does not include Object.prototype returns false .请注意,将instanceof Object应用于原型链不包含Object.prototype的对象返回false Do not use instanceof to determine Object data type.不要使用instanceof来确定 Object 数据类型。

Wrapper objects and strict mode.包装对象和严格模式。

In early versions of JavaScript, setting properties on wrapper objects automatically created from primitive values was syntactically correct and did not generate errors.在 JavaScript 的早期版本中,在从原始值自动创建的包装器对象上设置属性在语法上是正确的,并且不会产生错误。 However , the wrapper object was discarded as soon as the wrapper object expression was evaluated.但是,包装器对象表达式一被求值,包装器对象就被丢弃了。 Trying to look up a custom property in later code fails because a new, different wrapper object, lacking the custom property, is used for the lookup.尝试在后面的代码中查找自定义属性失败,因为查找时使用了缺少自定义属性的新的不同包装对象。

Strict mode generates an error if an attempt is made to assign a property value to any primitive value.如果尝试将属性值分配给任何原始值,则严格模式会生成错误。

Possible Check Function可能的检查功能

 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 a boolean reflecting if the first argument is of Object data type and has an own property with the same name as the second argument. CheckOwnProperty返回一个布尔值,反映第一个参数是否为 Object 数据类型并且是否具有与第二个参数同名的自己的属性。 It returns false for all primitive values.它为所有原始值返回 false。

I think you can call it on any variable which is not undefined nor null .我认为你可以在任何不是undefinednull变量上调用它。

 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

YOU ARE CORRECT.你是对的。 IT EXIST ON EVERYTHING BUT UNDEFINED AND 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')

If you just want to check for the existence of properties, and not necessarily what their value might be, then you have two safe options: hasOwnProperty() and the in operator.如果您只想检查属性是否存在,而不一定是它们的值可能是什么,那么您有两个安全选项:hasOwnProperty() 和 in 运算符。 The hasOwnProperty() property method should be used if you want to detect own properties only.如果您只想检测自己的属性,则应使用 hasOwnProperty() 属性方法。 If you want to test property existence and don't care if it's an own property or an object property, then the in operator is the one to use.如果您想测试属性是否存在并且不关心它是自己的属性还是对象属性,那么可以使用 in 运算符。

reference for more information click here 有关更多信息的参考,请单击此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM