toString
method, checking for the presence of a key with the same name using the in
operator will lead to a false positive result: var map = {}; 'toString' in map; // true
in
operator, not finding a property in an object instance, looks further along the chain of prototypes in search of inherited values. In our case, this is the toString
method. To solve this problem, there is a method hasOwnProperty
, which was designed specifically to check the presence of properties only in the current object: var map = {}; map.hasOwnProperty('toString'); // false
var map = {}; map.hasOwnProperty = 'foo'; map.hasOwnProperty('hasOwnProperty'); // TypeError
hasOwnProperty
method in the context of our object: var map = {}; map.hasOwnProperty = 'foo'; {}.hasOwnProperty.call(map, 'hasOwnproperty'); // true
for ... in
, you have to filter out all the inherited stuff: var map = {}; var has = {}.hasOwnProperty; for(var key in map){ if(has.call(map, key)){ // do something } }
Object.create
method provided in ES5 . The uniqueness of this method is that you can clearly define the prototype of a new object. For example, create a normal object a little more clearly: var obj = {}; // : var obj = Object.create(Object.prototype);
null
instead: var map = Object.create(null); map instanceof Object; // false Object.prototype.isPrototypeOf(map); // false Object.getPrototypeOf(map); // null
[[Prototype]]
removes the risk of stumbling upon name conflicts. And even better! After we have deprived the object of all inherited methods and properties, any attempts to use it for purposes other than its intended purpose (repository) will result in errors: var map = Object.create(null); map + ""; // TypeError: Cannot convert object to primitive value
hasOwnProperty
method hasOwnProperty
also no longer there, and it is not needed, since the in
operator now works fine without any checks. var map = Object.create(null); 'toString' in map; // false
for ... in
cycles are now much easier. Finally, we can safely write them the way they should look like: var map = Object.create(null); for(var key in map){ // do something }
Object.prototype
: var map = Object.create(null); Object.defineProperties(map, { 'foo': { value: 1, enumerable: true }, 'bar': { value: 2, enumerable: false } }); map.foo; // 1 map['bar']; // 2 JSON.stringify(map); // {"foo":1} {}.hasOwnProperty.call(map, 'foo'); // true {}.propertyIsEnumerable.call(map, 'bar'); // false
var map = Object.create(null); typeof map; // object {}.toString.call(map); // [object Object] {}.valueOf.call(map); // Object {}
Source: https://habr.com/ru/post/259529/
All Articles