ES6 对象扩展详解:简洁表示、属性名与 Object.is/assign

作者:纸飞机

时间:2026-10-22

浏览:529

本文详解 ES6 中对象的六大扩展特性,包括属性与方法的简洁表示法、属性名表达式、方法 name 属性、Object.is 严格相等比较、Object.assign 浅拷贝机制,以及对象的可枚举性与六种遍历方法。涵盖属性遍历顺序、proto 访问及 ES7 扩展运算符用法,帮助开发者深入理解对象操作。

文章目录

属性简洁表示法

一、属性的简洁表示法

ES6 允许在对象字面量中直接写入变量名或函数名作为属性名或方法名。这意味着在定义对象时,可以省略属性值,此时属性值自动等于同名的外部变量。以下通过具体示例进行说明:

属性简洁表示示例:


function getPoint(){
 var x = 1 ;
 var y = 2;
 return {x,y}
}

上述代码等价于:


fucntion getPoint(x,y){
 var x = 1 ;
 var y = 2;
 return {x:x,y:y}
}

测试验证:


getPoint();//{x:1,y:10}

方法简洁表示示例:


var obj = {
 fun(){
 return "simply function";
 }
};

上述代码等价于:


var obj = {
 fun: function(){
 return "simply function";
 }
}

测试验证:


obj.fun();//simply function

属性名表达式

二、属性名表达式

在 ES6 中,定义对象时可以使用表达式作为属性名或方法名,只需将表达式置于方括号 [] 内即可。

属性名表达式示例:


let propKey = 'foo';

let obj = {
 [propKey] : true,
 ['a'+'bc'] : 123
}

测试验证:


obj.foo; //true
obj.abc ; //123

方法名表达式示例:


let obj = {
 ['h'+'ello'](){
 return "hello world";
 }
}

测试验证:


obj.hello();//hello world

注意事项:

属性名表达式与简洁表示法不能同时使用。若尝试混合使用,如将变量名置于方括号内但未提供属性值,会引发语法错误。正确做法是提供明确的属性值。


//错误的
var foo = 'bar';
var bar = 'abc';
var baz = { [foo] };

//正确
var foo = 'bar';
var baz = { [foo] : 'abc'}

方法的 name 属性

三、方法的 name 属性

此部分主要阐述函数 name 属性的返回规则。

函数的 name 属性返回函数名。由于对象方法本质上是函数,因此方法也具备 name 属性。

  • 一般情况下,方法的 name 属性直接返回函数名。
  • 如果是取值函数(getter),name 属性会在函数名前添加“get”前缀。
  • 如果是存值函数(setter),name 属性会在函数名前添加“set”前缀。
  • 如果使用 bind 方法创建的函数,name 属性会在函数名前添加“bound”前缀。
  • 如果使用 Function 构造函数创建的函数,name 属性会返回“anonymous”。
  • 如果对象的方法名是一个 Symbol 值,那么 name 属性返回该 Symbol 值的描述字符串。

Object.is 方法

四、Object.is()

Object.is() 用于比较两个值是否严格相等,其行为与严格相等运算符(===)基本一致。主要区别在于两点:一是 +0 不等于 -0,二是 NaN 等于自身。


+0 === -0 //true
NaN === NaN //false

Object.is(+0,-0);//false
Object.is(NaN,NaN);//true

Object.assign 方法

五、Object.assign()

Object.assign() 方法用于将源对象的可枚举属性复制到目标对象。该函数至少需要两个参数,第一个参数为目标对象,后续所有参数均为源对象。

注意事项:

  • 每个参数必须是对象,否则将抛出 TypeError 错误。
  • 如果目标对象与源对象存在同名属性,或者多个源对象之间存在同名属性,后出现的属性值将覆盖先前的属性值。
  • Object.assign 仅复制对象自身的属性,不可枚举的属性和继承自原型的属性不会被复制。
  • 属性名为 Symbol 值的属性,也会被 Object.assign 复制。

示例代码:


var target = {a:1,b:2};

var source1 = {a:2,c:5};
var source2 = {a:3,d:6};

Object.assign(target,source1,source2);
target//{a:3,b:2,c:5,d:6}

Object.assign 该方法可用于处理数组,但会将数组视为对象进行处理。


Object.assign([1,2,3],[4,5]);
//[4,5,3]

其他常见用途:

  • 为对象添加属性
  • 为对象添加方法
  • 克隆对象
  • 合并多个对象
  • 为属性指定默认值

属性可枚举性与遍历

六、属性的可枚举性

对象的每个属性都关联一个描述对象(Descriptor),可通过 Object.getOwnPropertyDescriptor(object,prop) 获取,其中 object 表示对象,prop 表示对象内的一个属性,使用时需加引号。描述对象中包含 enumerable(可枚举性)属性,用于描述该属性是否可枚举。

在 ES5 中,enumerable 为 false 的属性会被某些遍历方法忽略。

  • for…in 循环:只遍历对象自身和继承的可枚举属性(包含继承)。
  • Object.keys() 方法:返回对象自身的所有可枚举属性的键名。
  • Json.stringify() 方法:只串行化对象自身的可枚举属性。

ES6 新增的操作:

  • Object.assign() 方法:只复制对象自身的可枚举属性。
  • Reflect.enumerate() 方法:返回所有 for…in 循环会遍历的属性(包含继承)。

七、属性的遍历

ES6 中提供了六种方法可以遍历对象的属性。

  • for…in 循环:遍历对象自身和继承的可枚举属性(不含 Symbol 属性)。
  • Object.keys(obj) 方法:返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性,但包含不可枚举属性)。
  • Object.getOwnPropertySymbols(obj) 方法:返回一个数组,包含对象自身的所有 Symbol 属性。
  • Relect.ownKeys(obj) 方法:返回一个数组,包含对象的所有属性,无论属性名是 Symbol 还是字符串,也不管是否可枚举。
  • Reflect.enumerate(obj) 方法:返回一个 Iterator 对象,遍历对象自身的和继承的所有可枚举属性(不含 Symbol),行为与 for...in 相同。

以上六种方法遍历对象的属性均遵守相同的属性遍历次序规则:

  • 首先遍历所有属性名为数值的属性,按照数字排序。
  • 其次遍历所有属性名为字符串的属性,按照生成时间排序。
  • 最后遍历所有属性名为 Symbol 值的属性,按照生成时间排序。

Reflect.ownkeys({[Symbol()]:0,b:0,10:0,2:0,a:0})
//[‘2','10','b','a',Symbol()]

原型访问与扩展运算符

八、proto 属性,Object.setPrototypeOf(),Object.getPrototypeOf()

proto 属性

(前后应该有两个下划线,这里没显示出来)。用来读取或者设置当前对象的 prototype 对象。但是一般不直接对这个属性进行操作,而是通过 Object.setProtortypeOf() (写操作)、Object.getPrototypeOf()(读操作)或者 Object.create() (生成操作)代替。

Object.setProtortypeOf()


let proto = {};
let obj = { x : 10};
Object.setProtortypeOf(obj,proto);

proto.y = 20;
proto.z = 40;

obj.x //10
obj.y //20
obj.z //40

Object.getProtortypeOf()


function Rectangle(){}

var rec = new Rectangle();

Object.getPrototypeOf(rec) === Rectangele.prototype // true

九、对象的扩展运算符

ES7 中的提案,将 rest 参数/扩展运算符(…)引入对象。

Rest 参数

Rest 参数用于从一个对象取值,相当于将所有可遍历尚未被读取的属性,分配到指定的对象上。所有的键及其值都会复制到新对象上。需要注意的是 rest 参数的复制是浅复制,并且也不会复制继承自原型对象的属性。

简单的 demo


 let {x,y,...k} = {x:2, y:3,z:4,a:5};
x //2
y //3
k //{z:4,a:5}

扩展运算符

扩展运算符用于取出参数对象的所有可遍历属性,复制到当前对象中。


let z = {a:3 ,b:4};
let n = {...z};
n //{a:3,b:4}

扩展运算符还可以合并两个对象。


let a = { c:5,d:6 };
let b = { e:7,f:8 };
let ab = {...a,...b};
ab //{c:5,d:6,e:7,f:7}

扩展运算符还可以自定义属性,会在新对象中覆盖掉原有参数。


let a = {x:1,y:2};
let aWithOverides = {...a,x:3,y:4};
aWithOverides //{x:4,y:4}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对本站的支持。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章