object:(string) key/value pair, with a private property which holds a link to another object called its?prototype.?
Objects can be created:
單個(gè)對(duì)象:
1.using the?Object()?constructor?
2.or the?object initializer / literal syntax.
3.Object.create(null)
批量生產(chǎn):
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