object:(string) key/value pair, with a private property which holds a link to another object called its prototype.
Objects can be created:
单个对象:
1.using the Object() constructor
2.or the object initializer / literal syntax.
3.Object.create(null)
批量生产:
constructor function + prototype
Objects are key/value pairs. The most common way to create an object is with curly braces {} and you add properties and methods to an object using dot notation.
let animal={}
animal.name='Leo'
animal.energy=10
animal.eat=function(amount){
console.log(`${this.name} is eating.`)
this.energy+=amount
}
animal.sleep=function(length){
console.log(`${this.name} is sleeping.`)
this.energy+=length
}
animal.play=function(length){
console.log(`${this.name} is playing.`)
this.energy-=length
}
Simple. Now odds are in our application we'll need to create more than one animal. Naturally the next step for this would be to encapsulate that logic inside of a function that we can invoke whenever we needed to create a new animal. We'll call this pattern Functional Instantiation and we'll call the function itself a "constructor function" since it's responsible for "constructing" a new object.
Nearly all objects in JavaScript are instances of Object; a typical object inherits properties (including methods) from Object.prototype, although these properties may be shadowed (a.k.a. overridden). The only objects that don't inherit from Object.prototype are those with null prototype, or descended from other null prototype objects.
Changes to the Object.prototype object are seen by all objects through prototype chaining, unless the properties and methods subject to those changes are overridden further along the prototype chain. This provides a very powerful although potentially dangerous mechanism to override or extend object behavior. To make it more secure, Object.prototype is the only object in the core JavaScript language that has immutable prototype — the prototype of Object.prototype is always null and not changeable.
The __proto__ property is deprecated and should not be used. The Object.getPrototypeOf() and Object.setPrototypeOf() alternatives are static methods.
The propertyIsEnumerable() and hasOwnProperty() methods can be replaced with the Object.getOwnPropertyDescriptor() and Object.hasOwn() static methods, respectively.
The isPrototypeOf() method can usually be replaced with instanceof, if you are checking the prototype property of a constructor.
null-prototype objects: The term "null-prototype object" often also includes any object without Object.prototype in its prototype chain. Such objects can be created with extends null when using classes.
Almost all objects in JavaScript ultimately inherit from Object.prototype (see inheritance and the prototype chain). However, you may create null-prototype objects using Object.create(null) or the object initializer syntax with __proto__: null. You can also change the prototype of an existing object to null by calling Object.setPrototypeOf(obj, null).
const obj = Object.create(null);
Object.setPrototypeOf(obj, null);
const obj2 = { __proto__: null };
An object with a null prototype can behave in unexpected ways, because it doesn't inherit any object methods from Object.prototype. This is especially true when debugging, since common object-property converting/detecting utility functions may generate errors, or lose information (especially if using silent error-traps that ignore errors).
For example, the lack of Object.prototype.toString() often makes debugging intractable:
const normalObj = {}; // create a normal object
const nullProtoObj = Object.create(null); // create an object with "null" prototype
console.log(`normalObj is: ${normalObj}`); // shows "normalObj is: [object Object]"
console.log(`nullProtoObj is: ${nullProtoObj}`); // throws error: Cannot convert object to primitive value
alert(normalObj); // shows [object Object]
alert(nullProtoObj); // throws error: Cannot convert object to primitive value
In practice, objects with null prototype are usually used as a cheap substitute for maps. The presence of Object.prototype properties will cause some bugs:
const ages = { alice: 18, bob: 27 };
function hasPerson(name) {
return name in ages;
}
function getAge(name) {
return ages[name];
}
hasPerson("hasOwnProperty"); // true
getAge("toString"); // [Function: toString]
Using a null-prototype object removes this hazard without introducing too much complexity to the hasPerson and getAge functions:
const ages = Object.create(null, {
alice: { value: 18, enumerable: true },
bob: { value: 27, enumerable: true },
});
hasPerson("hasOwnProperty"); // false
getAge("toString"); // undefined