Because the modern JavaScript engine optimizes the characteristics brought by attribute access, changing the [[Prototype]] of the object is__ proto__ It is a very slow operation on various browsers and JavaScript engines.
An Object prototype method
1 Object.setPrototypeOf(obj, proto)
- Use this method instead of modifying it directly__ proto__
- The return value is the obj of the prototype, that is, the first parameter
- If the first parameter is not an object, the operation has no effect. Take the prototype of the first parameter constructor as the prototype of obj
const n = new Number(1) console.log(n) console.log(Object.getPrototypeOf(n)) const obj = Object.setPrototypeOf(1, { a: 100 }) console.log(obj) console.log(Object.getPrototypeOf(obj)) // Check whether the prototype is set up
- If the first parameter is undefined / null (no wrapper class), an error is reported
2 Object.getPrototypeOf()
- When the parameter is the original value, the prototype of its wrapper class constructor is returned
3 Object.keys()
- Returns enumerable properties without inherited properties
- for in can get the inherited properties
4 Object.values()
- Returns an enumerable property value
5 Object.entries()
const obj = { a: 1 } Object.defineProperties(obj, { b: { value: 2, enumerable: true }, c: { value: 3 } }) const p = { d: 4 } Object.setPrototypeOf(obj, p) console.log(obj) console.log('keys', Object.keys(obj)) console.log('values', Object.values(obj)) console.log('entries', Object.entries(obj))
super
- Prototype object pointing to object
- Usage restriction: super can only be accessed when it is a method of an object and is abbreviated
let proto = { y: 20, z: 40 } let obj = { x: 10, foo() { console.log(super.y) } } Object.setPrototypeOf(obj, proto) obj.foo() // 20
Symbol
- Solve the problem of duplicate object attribute names
- Is the original value type
- Symbol is a constructor, and new will report an error
- Generate unique values
- typeof returns symbol
- Property not attached
Is the wrapper class such an attribute
let s1 = Symbol() s1.a = 1; console.log(s1.a) // undefined
console.log(Symbol()) // Symbol() console.log(Symbol(undefined)) // Symbol() console.log(Symbol(null)) // Symbol(null) console.log(Symbol(1)) // Symbol(1) console.log(Symbol(true)) // Symbol(true) console.log(Symbol('1')) // Symbol(1) console.log(Symbol({})) // Symbol([object Object]) console.log(Symbol(function () { })) // Symbol(function(){}) console.log(Symbol([])) // Symbol() console.log(Symbol([1, 2, 3])) // Symbol(1,2,3) console.log(String(Symbol('character string'))) // Symbol (string) console.log(Boolean(Symbol(1))) // true console.log(Boolean(Symbol(null))) // Note that there are six types of true and false const s1 = Symbol() console.log(Object.getPrototypeOf(s1)) // Symbol.prototype // Cannot convert a Symbol value to a number console.log(Number(Symbol(1))) // report errors console.log(Symbol() + 1) // report errors
Obviously, when generating a Symbol, the toString method of the corresponding variable is used in parentheses, and the return values of arrays, objects and methods are different
- Symbol has its own toString method
- Only Number cannot be converted to explicit conversion, and Boolean and String can
- Implicit conversions are Boolean only
Symbol as object attribute
- obj[s1] = xx
- const obj = { [s1]: xxx }
- Object.defineProperty(obj, s1, { value: xxx })
Symbol method
- Symbol.for('foo ') gets the same symbol value
- Pass the same key
- Symbol.keyFor(s1) gets the symbol key value specified by for
const s1 = Symbol.for('foo') const s2 = Symbol.for('foo') console.log(s1 === s2) // true console.log(Symbol.keyFor(s1)) // foo const s22 = Symbol() const s3 = Symbol(null) const s4 = Symbol(1) console.log(Symbol.keyFor(s22)) // undefined they didn't use symbol For specifies the key console.log(Symbol.keyFor(s3)) // undefined console.log(Symbol.keyFor(s4)) // undefined
Symbol property traversal
- for in cannot traverse a property of type Symbol
- for of cannot traverse a property of type Symbol
- Unique API object Getownpropertysymbols (obj) only traverses the properties of Symbol type of obj
The for... In statement traverses the enumerable properties (including inheritance) of an object other than Symbol in any order.
Object. The keys () method will return an array composed of the enumerable attributes of a given object. The order of the attribute names in the array is consistent with the order returned when the object is traversed in a normal loop.
An array of all Symbol properties found on the given object itself. (not related to enumeration)
const obj = { c: 1, d: 2 } let a = Symbol('a') let b = Symbol('b') let _a = Symbol('_a') let _b = Symbol('_b') obj[a] = 'hello' obj[b] = 'world' Object.defineProperties(obj, { e: { value: 5, enumerable: true, }, f: { value: 6, enumerable: false, }, [_a]: { value: -1, enumerable: true, }, [_b]: { value: -2, enumerable: false, }, }) let h = Symbol('h') let i = Symbol('i') let j = Symbol('j') const obj1 = { g: 7, [h]: 8 } Object.defineProperties(obj1, { [i]: { value: 9, enumerable: true, }, [j]: { value: 10, }, k: { value: 11 } }) Object.setPrototypeOf(obj, obj1) console.log(obj) for (let i in obj) { console.log(i) // c d e g } console.log(Object.keys(obj)) // ["c", "d", "e"] console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(a), Symbol(b), Symbol(_a), Symbol(_b)] console.log(Object.assign(obj)) // Copy only its enumerable genera