企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 属性的简洁表示法 ES6允许直接写入变量和函数作为对象的属性和方法,这样书写更加简洁 ```js let foo = 'bar' let obj = { foo } obj // { foo: 'bar' } ``` ES6允许在对象中只写属性名,不写属性值,这时,属性值等于属性名所代表的变量 ### 属性名表达式 ES6允许字面量定义对象时使用表达式,即把表达式放在方括号内 ```js obj['a' + 'bc'] = 123 ``` ### 方法的name属性 函数的`name`属性返回函数名。对象的方法也是函数,因此也有`name`属性 ```js const person = { sayName () { console.log('hello') } } person.sayName.name // 'sayName' ``` 如果对象的方法使用了取值函数(`getter`)和存值函数(`setter`),则`name`属性不是在该方法上,而是在该方法属性的描述对象的`get`和`set`属性上。 ### Object.is() 在ES5中,比较两个值是否相等,可以使用`==`和`===`,相等运算符会自动转换数据类型,而严格相等运算符会认为`NaN`不等于自身,以及`+0`等于`-0`。 ES6新增了`Object.is()`方法来解决这个问题。它用来比较两个值是否严格相等,与`===`的行为基本一致。 ```js Object.is('foo', 'foo') //true Object.is({}, {}) //false ``` ```js +0 === -0 // true NaN === NaN //false Object.is(+0, -0) // false Object.is(NaN, NaN) // true ``` ### Object.assign `Object.assign`方法用于将源对象的所有可枚举属性复制到目标对象 ```js let target = { a: 1 } let source1 = { b: 2 } let source2 = { c: 3 } Object.assing(target, source1, source2) target // { a: 1, b: 2, c: 3 } ``` `Object.assign`方法的第一个参数是目标对象,后面的都是源对象 `Object.assign`方法实行的是浅复制,而不是深复制,也就是说,如果源对象某个属性的值是对象,那么目标对爱那个复制得到的是这个对象的引用。 ```js let obj1 = { a: { b: 1 } } let obj2 = Object.assign({}, obj1) obj1.a.b = 2 obj2.a.b // 2 ``` `Object.assign`方法的常见用途: #### 为对爱那个添加属性 ```js class Point { constructor (x, y) { Object.assign(this, { x, y }) } } ``` #### 为对象添加方法 ```js Object.assign(SomeClass.prototype, { someMethod (arg1, arg2) { ... } }) ``` #### 克隆对象 ```js function clone (origin) { return Object.assign({}, origin) } ``` 上面的方法不能克隆继承值,只能克隆自身的值。 #### 合并多个对象 ```js const merge= (target, ...sources) => Object.assign(target, ...sources) ``` ### 属性的可枚举性 对象的每一个属性都具有一个描述对象(Descriptor),用于控制该属性的行为。 `Object.getOwnPropertyDescriptor` 方法可以获取该属性的描述对象 ```js let obj = { foo: 123 } Object.getOwnPropertyDescriptor(obj, 'foo') // { // value: 123, // writable: true, // enumerable: true, // configurable: true // } ``` ### 属性的遍历 ES6一共有5中方法可以遍历对象的属性 - `for...in` 它遍历对象自身和继承的可枚举属性 - `Object.keys(obj)` 它返回一个数组,包含对象自身的,不包含继承的,所有可枚举属性 - `Object.getOwnPropertyNames(obj)` 返回一个数组,包含对象自身的所有属性,包含不可枚举属性 - `Object.getOwnPropertySymbols(obj)` 返回一个数组,包含对象自身所有Symbol属性 - `Reflect.ownKeys(obj)` 返回一个数组,包含对象自身所有属性,包括Symobl,不管是否可枚举 ### __proto__属性、Object.setPrototpyeOf()、Object.getPrototypeOf() #### __proto__属性 `__proto__`属性用来读取和设置当前对象的 `prototype`对象 ```js let obj = { method: function () { ... } } obj.__proto__ = someOtherObj ``` 最佳实践证明,无论从那个角度上来讲,请都不要使用这个属性,而是使用`Object.setPrototpyeOf()`来执行写操作,`Object.getPrototypeOf()`来执行读操作,`Object.create()`来执行生成操作。 #### Object.setPrototypeOf() ES6推荐使用 `Object.setPrototypeOf()` 方法来设置原型对象,它返回对象本身。 ```js // 用法 let o = Object.setPrototypeOf({}, null) ``` ```js let proto = {} let obj = { x: 10 } Object.setPrototypeOf(obj, proto) proto.y = 20 proto.z = 40 obj.x // 10 obj.y // 20 obj.z // 40 ``` #### Object.getPrototypeOf() `Object.gfetPrototpyeOf()`方法用于读取一个对象的`prototype`对象 ```js function Rectangle () {} let rec = new Rectangle() Object.getPrototypeOf(rec) === Rectangle.prototype // true ``` ### Object.keys()、Object.values()、Object.entries() #### Object.keys() `Object.keys()`方法返回一个数组,成员是参数对象自身的,不包含继承的,所有可遍历属性的键名 ```js let obj = { foo: 'bar', baz: 42 } Object.keys(obj) // ['foo', 'baz'] ``` #### Object.values() `Object.values()`方法返回一个数组,成员是参数对象自身的,不包含继承的,所有可遍历属性的键值 ```js let obj = { foo: 'baz', bar: 42 } Object.values(obj) // ['baz', 42] ``` #### Object.entries() `Object.entries()`方法返回一个数组,成员是参数对象自身的,不包含继承的,所有可遍历属性的键值对数组 ```js let obj = { foo: 'bar', baz: 42 } Object.entries(obj) // [ ['foo', 'baz'], ['bar', 42] ] ``` ### 对象的扩展运算符 前面我们介绍了扩展运算符 ```js const [a, ...b] = [1, 2, 3] a // 1 b // [2, 3] ``` ES2017将这个特性引入到了对象之中。 对象的解构赋值用于从一个对象取值,相当于将所有可遍历、但未被读取的属性分配到指定的对象上面。 ```js let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 } x // 1 y // 2 z // { a: 3, b: 4 } ``` 扩展运算符(...)用于取出参数对象的所有可遍历属性,并将其复制到当前对象中 ```js let z = { a: 3, b: 4 } let n = { ...z } n // { a: 3, b: 4 } ``` ### Object.getOwnPropertyDescriptors() ES5的`Object.getOwnPropertyDescriptor()`方法用来返回某个对象属性的描述对象。ES2017引入了`Object.getOwnPropertyDescriptors()`方法,返回指定对象所有自身属性(非继承属性)的描述对象。