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