object
A plain object, or just an object.
literal
let user = new Object(a);// Constructor syntax
let user = {}; // The syntax for "literal"
Copy the code
Text and attributes
An object property consists of a key value
let user = { // An object
name: "John".// key "name", value "John"
age: 30 // key "age", value 30
};
Copy the code
Properties can be deleted by delete
delete user.age;
Copy the code
The square brackets
To access attributes
let user = {};
user["likes birds"] = true;
alert(user["likes birds"]); // true
Copy the code
Dot notation
let user = {};
user["likes"] = true;
alert(user.likes); // true
Copy the code
Calculate attribute
let fruit = prompt("Which fruit to buy?"."apple");
let bag = {
[fruit]: 5.// The attribute name is derived from the fruit variable
};
alert( bag.apple ); // 5 如果 fruit="apple"
Copy the code
// Attributes are not fixed, but randomly specified.
let fruit = prompt("Which fruit to buy?"."apple");
let bag = {};
// Get the value from the fruit variable
bag[fruit] = 5;
Copy the code
Short for property value
function makeUser(name, age) {
return {
name: name,
age: age,
};
}
Copy the code
Abbreviated as
function makeUser(name, age) {
return {
name, // Same as name: name
age, // Same as age: age
};
}
Copy the code
Attribute name restriction
Object properties are not affected by system reserved keywords.
// These attributes are ok
let obj = {
for: 1.let: 2.return: 3
};
alert( obj.for + obj.let + obj.return ); / / 6
Copy the code
Even if the variable is int 0, the system will automatically convert it to “0”
let obj = {
0: "test" // equivalent to "0": "test"
};
alert( obj["0"]);// test
alert( obj[0]);// test (same property)
obj. 0 // This will fail
Copy the code
Attribute presence judgment
- Direct judgment undefined
let user = {};
alert( user.aaa === undefined ); // true means there is no such attribute.
Copy the code
- The in operator
let user = { name: "John".age: 30 }; alert( "age" in user ); // true, user.age exists alert( "blabla" in user ); // false, user.blabla does not exist. // Can be a variable judgment let user = { age: 30 }; let key = "age"; alert( key in user ); // true, the attribute "age" exists Copy the code
Note that both undefined and in return true if the property is undefined
For in iterates over all the keys
let user = {
name: "John".age: 30.isAdmin: true
};
for (let key in user) {
// keys
alert( key ); // name, age, isAdmin
// Attribute key value
alert( user[key] ); // John, 30, true
}
Copy the code
Property traversal sort
- Integer attributes are sorted
- Other properties are displayed in the order they were created
Sort by integer type
let codes = {
"49": "Germany"."41": "Switzerland"."44": "Great Britain"./ /.. .
"1": "USA"
};
for(let code in codes) {
alert(code); // 1, 41, 44, 49
}
Copy the code
In order of creation
let user = {
name: "John".surname: "Smith"
};
user.age = 25; // Add one
// Non-integer attributes are sorted in the order they were created
for (let prop in user) {
alert( prop ); // name, surname, age
}
Copy the code
conclusion
Objects are associative arrays with some special properties. They store attributes (key-value pairs), where:
- The key of the property must be a string or symbol (usually a string).
- Values can be of any type.
We can access attributes as follows:
- Dot notation:
obj.property
. - The square brackets
obj["property"]
Square brackets allow you to retrieve keys from variables, for exampleobj[varWithKey]
.
Other operations:
- Delete attributes:
delete obj.prop
. - Check for the presence of a given key attribute:
"key" in obj
. - Traversal object:
for(let key in obj)
Cycle.
Object reference and copy
Objects are stored and copied by referencing addresses, whereas primitive types are stored directly as actual strings, numbers, or true false.
Object replication
It’s just a simple reference copy, and everything is still the same object
let user = { name: "John" };
let admin = user; // Copy the reference
// The user and admin operations are equivalent
Copy the code
Reference to compare
let a = {};
let b = a; // Copy the reference
alert( a == b ); // true, both reference the same object
alert( a === b ); // true
// Objects defined by literals are two independent reference addresses
let a = {};
let b = {}; // Two independent objects
alert( a == b ); // false
Copy the code
Object copy/merge
Loop assignment by iterating through key values
let user = {
name: "John".age: 30
};
let clone = {}; // New empty object
// Copy all attributes from user to it
for (let key in user) {
clone[key] = user[key];
}
// Clone is now a completely separate object with the same content
clone.name = "Pete"; // Change the data in it
alert( user.name ); // The name attribute in the original object is still John
Copy the code
The use of the Object. Assgin
Object.assign(dest, [src1, src2, src3…] )
Merging multiple attributes
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
// Copy all the attributes in permissions1 and permissions2 to user
Object.assign(user, permissions1, permissions2);
// Now user = {name: "John", canView: true, canEdit: true}
Copy the code
Object.assign Clone an Object
let user = {
name: "John",
age: 30
};
let clone = Object.assign({}, user);
Copy the code
Note that objects that are likely to be copied are nested objects, which is where deep copying is required.
The garbage collection
accessibility
“Reachable” values are those that are accessible or available in some way. They must be stored in memory.
- Here is a basic set of inherently reachable values that obviously cannot be released.
- Global variables.
- Local variables and arguments to the current function.
- When a nested call is made, the variables and arguments of all functions on the current call chain are called.
- These values are called
The root
roots
- A value is considered reachable if any other value can be accessed from the root through a reference or chain of references.
In the JavaScript engine there is something called the garbage collector that executes in the background. It monitors the status of all objects and removes those that are no longer reachable.
Scenario 1
// User is the object referenced below the root
let user = {
name: "John"
};
user = null;// When null is set, the original {name: "John"} object is no longer referred to, and will be recycled
Copy the code
Scenario 2 is correlated
function marry(man, woman) {
woman.husband = man;
man.wife = woman;
return {
father: man,
mother: woman
}
}
let family = marry({
name: "John"
}, {
name: "Ann"
});
Copy the code
// When executing the following code
delete family.father;
delete family.mother.husband;
Copy the code
The following results
Since John is no longer referenced, although he points to Ann, the garbage collection principle is reachable. So John will be recycled.
- Family = null;
- All objects will be reclaimed.
Recovery algorithm
The Mark-and-sweep garbage collector is optimized by periodically marking and cleaning:
- Generational collection
- Incremental collection
- Spare time to collect
conclusion
Main contents to master:
- Garbage collection is automatic and cannot be enforced or prevented.
- When an object is reachable, it must exist in memory.
- Being referenced is not the same as being accessible (from a root) : a set of interconnected objects may not be reachable as a whole.
Object methods
Functions that assign values to object properties through function expressions are called methods.
let user = {
name: "John".age: 30
};
1 / / way
user.sayHi = function() {
alert("Hello!");
};
user.sayHi(); // Hello!
// Mode 2 can also be declared first and then assigned
function sayHi() {
alert("Hello!");
};
user.sayHi = sayHi;
Copy the code
Methods shorthand
1 / / way
user = {
sayHi: function() {
alert("Hello"); }};2 / / way
let user = {
sayHi() {
alert("Hello"); }};Copy the code
Methods in the “this”
This is the object on which the method is called. What is the object “before the dot sign”
let user = {
name: "John".age: 30.sayHi() {
alert(this.name);// The current object
/ / equivalent to thealert(user.name); }};Copy the code
This can be used for any function, even if it is not a method of an object.
function sayHi() { alert( this); }// No error here, output window
Copy the code
- The value of this in strict mode is undefined
- The value of this in non-strict mode is window
This determines the content of the value through the code context. It’s calculated at runtime,
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
user.f = sayHi;
admin.f = sayHi;
user.f(); // John (this == user)
admin.f(); // Admin (this == Admin)
Copy the code
Arrow functions don’t have this
let user = {
a: "a".sayHi() {
let fn = () = > alert(this.a); fn(); }}; user.sayHi();// a
Copy the code
this
The value of is obtained while the program is running.- A function may be used when it is declared
this
But thisthis
It has a value only when the function is called. - You can copy functions between objects.
The constructor
Create an object through a constructor, equivalent to a literal {… }
- Suggested name: Start with a capital letter.
- They can only be made
"new"
Operator to execute.
Create a process
- A new empty object is created and assigned to
this
. - The function body executes. Usually it will modify
this
Add a new attribute to it. - return
this
The value of the.
function User(name) {
// this = {}; (Implicitly created)
// Add attributes to this
this.name = name;
this.isAdmin = false;
// return this; (Implicit return)
}
let user = new User("Jack")
// equivalent to a literal
let user = {
name: "Jack".isAdmin: false
};
Copy the code
Any function (except the arrow function) can be used as a constructor. That is, you can run the constructor through new. The main implementation: reusable object creation code
The new function () {… }
- Execute the function immediately anonymously
- Code for creating a single complex object,
let user = new function() {
this.name = "John";
this.isAdmin = false;
};
Copy the code
Constructor pattern test: new.target
function User() {
alert(new.target);
}
// no "new" :
User(); // undefined just calls the method
/ / with "new" :
new User(); // function User { ... } here an object is instantiated
Copy the code
Constructor return
- if
return
If an object is returned, the object is returned instead ofthis
.
function BigUser() {
this.name = "aaa";
return { name: "bbb" }; // <-- returns this object
}
alert( new BigUser().name ); // aaa gets that object
// Return normal
function SmallUser() {
this.name = "John";
return; // <-- returns this
}
alert( new SmallUser().name ); // John
Copy the code
Omit the parentheses
let user = new User; // <-- no arguments
/ / is equivalent to
let user = new User();
Copy the code
Methods in the constructor
function User(name) {
this.name = name;
this.sayHi = function() {
alert( "My name is: " + this.name );
};
}
let john = new User("John");
john.sayHi(); // My name is: John
Copy the code
Optional chain “? .”
If? . If the left part is not present, the operation will stop immediately (” short-circuit effect “)
let user = {}; // User has no address attributealert( user? .address? .street );// undefined (no error)
let user = null; alert( user? .address );// undefinedalert( user? .address.street );// undefined
Copy the code
? Variables before. Must be declared
// ReferenceError: user is not defineduser? .address;Copy the code
? The.() method call has a judgment
let userAdmin = {
admin() {
alert("I am admin"); }};letuserGuest = {}; userAdmin.admin? . ();// I am adminuserGuest.admin? . ();// There is no such method.
Copy the code
? .[] Attribute access exists judgment
let user1 = {
firstName: "John"
};
let user2 = null; // Suppose we cannot authorize this user
let key = "firstName"; alert( user1? .[key] );// Johnalert( user2? .[key] );// undefinedalert( user1? .[key]? .something? .not? .existing);// undefined
// Optimize the delete attribute
deleteuser? .name;Copy the code
? .Cannot be used for assignment
let user = null; user? .name ="John"; // Error, no effect
// undefined = "John"
Copy the code
conclusion
Optional chain? There are three forms of grammar:
obj? .prop
– ifobj
If it exists, returnobj.prop
Otherwise returnundefined
.obj? .[prop]
– ifobj
If it exists, returnobj[prop]
Otherwise returnundefined
.obj.method? . ()
– ifobj.method
If exist, callobj.method()
Otherwise returnundefined
.
Symbol type
- The property key of an object can only be of type string or Symbol
- The “Symbol” value represents a unique identifier. Used to implicitly protect variables, much like the Concept of private modifiers in Java.
- The advantage is that when using a third-party library, you want to define new attributes, if the original third-party library has for.. In, will not be iterated, does not affect the original code.
// id is an instantiated object of symbol
let id = Symbol(a);// id is a Symbol described as "id"
let id = Symbol("id");
Copy the code
Symbol is not automatically converted to a string
let id = Symbol("id");
alert(id); // Type error: unable to convert Symbol value to string.
//.description or.tostring () should be used
let id = Symbol("id");
alert(id.description); // id
Copy the code
You can set attributes dynamically and cannot access variables directly in user.id mode. You can only access variables through user[ID]
let user = { // Belongs to another code
name: "John"
};
let id = Symbol("id");
user[id] = 1;
alert( user[id] ); // We can use Symbol as the key to access data
Copy the code
Symbol in object literals
let id = Symbol("id");
let user = {
name: "John",
[id]: 123 // Instead of "id" : 123
};
Copy the code
In the for… In will be skipped
The Symbol attribute does not participate in for.. In circulation. Keys (user) is also not supported
let id = Symbol("id");
let user = {
name: "John".age: 30,
[id]: 123
};
for (let key in user) alert(key); // name, age (no symbols)
// Use the Symbol task to access directly
alert( "Direct: " + user[id] );
Copy the code
Object.assign can copy related information
let id = Symbol("id");
let user = {
[id]: 123
};
let clone = Object.assign({}, user);
alert( clone[id] ); / / 123
Copy the code
A global symbol
Global access, unified storage in the registry. Unified management
// Read from the global registry
let id = Symbol.for("id"); // If the Symbol does not exist, create it
// Read again (possibly in a different location in the code)
let idAgain = Symbol.for("id");
// Same Symbol
alert( id === idAgain ); // true
Copy the code
Symbol.keyFor
As long as the symbol is global, the name can be obtained from the symbol
// Get Symbol by name
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");
// Get the name from Symbol
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
Copy the code
Non-global symbols can access names using description
let globalSymbol = Symbol.for("name");
let localSymbol = Symbol("name");
alert( Symbol.keyFor(globalSymbol) ); // name, global Symbol
alert( Symbol.keyFor(localSymbol) ); // undefined, not global
alert( localSymbol.description ); // name
Copy the code
Object-raw value conversion
Automatically called by many built-in functions and operators that expect raw values as values.Copy the code
There are three types of hints:
"string"
(foralert
And other operations that require strings.)"number"
(For mathematical operations)"default"
(A few operators)
Call logic press
- objSymbol.toPrimitive
- Hint is a string call
obj.toString()
和obj.valueOf()
- Hint is the number/default call
obj.valueOf()
和obj.toString()
ToPrimitive
Symbol. ToPrimitive’s built-in Symbol, which is used to name the conversion method
obj[Symbol.toPrimitive] = function(hint) {
// Return a raw value
// hint = one of "string", "number", and "default"
}
/ / case
let user = {
name: "John".money: 1000[Symbol.toPrimitive](hint) { alert(hint); }};// Convert demo:
alert(user); // string
alert(+user); // number
alert(user + 500); // default
Copy the code
toString/valueOf
If there is no 'symbol.toprimitive', JavaScript will try to find them and do so in the following order:Copy the code
- For “String” hint,
toString -> valueOf
. - In other cases,
valueOf -> toString
.
let user = {
name: "John".money: 1000./ / to hint = "string"
toString() {
return "string"
},
// For hint="number" or "default"
valueOf() {
return "number/default"}}; alert(user);// string
alert(+user); // number/default
alert(user + 500); // number/default
Copy the code
There’s only one way to do this, and that’s toString
let user = {
name: "John".toString() {
return this.name; }}; alert(user);// toString -> John
alert(user + 500); // toString -> John500
Copy the code
Note the return value: you must return a raw value, not an object.
Advanced use:
let obj = {
// toString handles all conversions without other methods
toString() {
return "2"; }}; alert(obj *2); // 4, the object is converted to the original value string "2", which is then multiplied to the number 2.
Copy the code