3.6对象的扩展
3.6.1属性的简洁表示法
- ES6允许直接写入变量和函数,作为对象的属性和方法。
var foo = 'bar';
var baz = {foo};
console.log( baz ) // { foo: 'bar' }
//等同于
var foo = 'bar';
var baz={ foo:foo};
console.log( baz ) // { foo: 'bar' }
var func= {
method() {
return "这里是ES6方法简写!";
}
};
// 等同于
var func= {
method: function() {
return "这里是ES6以前的方法!";
}
};
3.6.2属性名表达式
- 定义对象属性的两种方法
- 直接用标识符作为属性名
- 用表达式作为属性名,要将表达式放在方括号之内
- ES6 允许字面量定义对象(使用大括号)时,用方法二(表达式)作为对象的属性名,即把表达式放在方括号内。
- 注意,属性名表达式与简洁表示法,不能同时使用,会报错。
// 方法一 obj.foo = true; // 方法二 obj['a' + 'bc'] = 123; let propKey = 'foo'; let obj = { [propKey]: true, ['a' + 'bc']: 123 // ES5使用大括号时不能这样定义 } let obj = { ['f' + 'unc']() { return '欢迎来到w3cschool'; } }; obj.func() // 欢迎来到w3cschool
3.6.3属性的遍历
? ES6一共有5种方法可以遍历对象的属性
- for...in
for...in循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)。
- Object.keys(obj)
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)
- Object.getOwnPropertyNames(obj)
? 返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。
- Object.getOwnPropertySymbols(obj)
? 返回一个数组,包含对象自身的所有Symbol属性。
- Reflect.ownKeys(obj)
返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。
总结:同样的属性遍历次序规则:
- 首先遍历所有属性名为数值的属性,按照数字排序。
- 其次遍历所有属性名为字符串的属性,按照生成时间排序。
- 最后遍历所有属性名为Symbol值的属性,按照生成时间排序。
3.6.4Object.assign() 对象的合并
- 用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
- 第一个参数是目标对象,后面的参数都是源对象。
- 如果目标对象和源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性。
- 如果该函数只有一个参数,
- 当参数为对象时,直接返回该对象;
- 当参数不是对象时,会先将参数转为对象然后返回。
- 由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
3.6.5Object.assign()常见用途
- (1)为对象添加属性
//将x属性和y属性添加到Person 类的对象实例。 class Person { constructor(x, y) { Object.assign(this, {x, y}); } }
- (2)为对象添加方法
Object.assign(Person.prototype, { method1(arg1, arg2) { ··· }, method2() { ··· } }); // 等同于下面的写法 Person.prototype.method1 = function (arg1, arg2) { ··· }; Person.prototype.method2 = function () { ··· };
- (3)克隆对象
//将原始对象拷贝到一个空对象,就得到了原始对象的克隆。
//此方法为浅拷贝,不能克隆它继承的值。
function clone(origin) {
return Object.assign({}, origin);
}
- (4)合并多个对象
//将多个对象合并到某个对象。 const merge =function(target, ...sources){ Object.assign(target, ...sources); }
- (5)为属性指定默认值
//DEFAULTS对象是默认值,options对象是用户提供的参数。 //Object.assign方法将DEFAULTS和options合并成一个新对象, //如果两者有同名属性,则option的属性值会覆盖DEFAULTS的属性值。 const DEFAULTS = { logLevel: 0, outputFormat: 'html' }; function processContent(options) { options = Object.assign({}, DEFAULTS, options); }
3.6.6Object.is()
- ES5比较两个值是否相等
- 相等运算符(==) 缺点:会自动转换数据类型
- 严格相等运算符(===) 缺点:NaN不等于自身,以及+0等于-0
+0 === -0 //true NaN === NaN // false
- Object.is 同值相等算法
- 用来比较两个值是否严格相等
- 不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
Object.is(+0, -0) // false Object.is(NaN, NaN) // true
- 补充:+0与-0的用处:更多应用在实际业务,例如负号代表运动的方向
3.6.7对象的解构赋值
- 对象的解构赋值用于从一个对象取值,相当于将所有可遍历的、但尚未被读取的属性,分配到指定的对象上面。
- 解构赋值必须是最后一个参数,否则会报错。
- 由于解构赋值要求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象。
- 解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。
var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
//解构赋值必须是最后一个参数
let { ...x, y, z } = obj; // 句法错误
let { x, ...y, ...z } = obj; // 句法错误
//解构赋值拷贝的是这个值的**引用
let obj = { a: { b: 1 } };
let { ...x } = obj; // 解构赋值
obj.a.b = 2;
x.a.b // 2
3.6.8扩展运算符...
- 扩展运算符( ... )用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
-
扩展运算符可以用于合并两个对象。
- 如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。
-
let z = { a: 3, b: 4 }; let n = { ...z }; // n的值 { a: 3, b: 4 } // 相当于Object.assign方法 let m = Object.assign( {}, z ); // m的值 { a: 3, b: 4 } let ab = { ...a, ...b }; // 等同于 let ab = Object.assign({}, a, b); let newobj= { ...obj, x: 1, y: 2 }; // 等同于 let newobj= Object.assign({}, obj, { x: 1, y: 2 });
3.6.9属性的可枚举性
- 对象的每个属性都有一个描述对象,用来控制该属性的行为。
- Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
- 描述对象的enumerable属性,称为”可枚举性“,如果该属性为false,就表示某些操作会忽略当前属性。
- ES5有三个操作会忽略enumerable为false的属性。
- for...in循环:只遍历对象自身的和继承的可枚举的属性。
- Object.keys():返回对象自身的所有可枚举的属性的键名。
- JSON.stringify():只串行化对象自身的可枚举的属性。
- ES6新增了Object.assign(),会忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
原文地址:https://www.cnblogs.com/xuzhengguo/p/12041169.html
时间: 2024-10-02 21:20:32