对象字面量的增强
对象是 ECMAScript 中最常用的数据结构,ECMAScript2015 升级了对象字面量的语法。在 ECMAScript2015 之前使用字面量方式定义一个对象,如下代码所示:
const bar = '前端课湛'
const obj = {
foo: 100,
bar: bar
}
从上述代码可以看到,即使 obj
对象的 bar
属性名和 bar
变量名相同,也需要按照对象字面量的方式进行定义。如下图所示:
在 ECMAScript2015 之后,如果变量名与属性名一致的话,只需要定义属性名即可。如下代码所示:
const bar = '前端课湛'
const obj = {
foo: 100,
bar
}
除此之外,如果想为对象添加一个方法的话,在 ECMAScript2015 之前如下代码所示:
const bar = '前端课湛'
const obj = {
foo: 100,
bar: bar,
sayHi: function () {
console.log(`hi, ${this.bar}`)
}
}
而 ECMAScript2015 之后允许省略 function 关键字,如下代码所示:
const bar = '前端课湛'
const obj = {
foo: 100,
bar,
sayHi() {
console.log(`hi, ${this.bar}`)
}
}
需要注意的是,这种用法就是普通函数,所以该方法中的 this
依旧是指向当前对象的。
另外,ECMAScript2015 中的对象字面量还有一个变化,就是可以使用表达式的返回值作为对象的属性名。在 ECMAScript2015 之前想要为对象添加一个动态的属性名,只能在对象声明之后通过索引值的方式进行添加。如下代码所示:
const bar = '前端课湛'
const obj = {
foo: 100,
bar: bar,
sayHi: function () {
console.log(`hi, ${this.bar}`)
}
}
obj[Math.random()] = 99
而在 ECMAScript2015 之后允许在定义对象时,直接使用表达式的返回值作为属性名。如下代码所示:
const bar = '前端课湛'
const obj = {
foo: 100,
bar,
sayHi() {
console.log(`hi, ${this.bar}`)
},
[Math.random()]: 99
}
ECMAScript2015 的这一特性叫做计算属性名。
对象的扩展方法
ECMAScript2015 中为 Object
对象提供了一些扩展方法,这里来看几个最主要的方法。
Object.assign()
方法
首先,是 assign()
方法,这个方法可以将多个源对象中的属性复制到一个目标对象中。如果对象之间存在相同的属性,那么源对象中的属性会覆盖目标对象中的属性。而这里所说的源对象和目标对象其实就是普通的对象,只不过用途不同罢了。如下代码所示:
const source = {
a: 123,
b: 456
}
const target = {
a: 789,
c: 111
}
const result = Object.assign(target, source)
console.log(target)
console.log(result === target)
assign()
方法接收任意个数的参数,第一个参数传递的是目标对象,剩余的参数是作为源对象的。其语法结构如下:
Object.assign(target, ...sources)
该方法的返回值为目标对象。该方法的参数列表:
target
:表示目标对象sources
:表示源对象
上述代码的运行结果如下:
{ a: 123, c: 111, b: 456 }
true
从打印结果可以看到,源对象和目标对象同时存在 a
属性,最终源对象的 a
属性的值覆盖了目标对象的 a
属性的值。再有,assign()
方法的返回值就是目标对象。
assign()
方法其实特别常用,很多时候可以使用这个方法来复制一个对象。如下代码所示:
function func(obj) {
obj.name = 'func obj'
console.log(obj)
}
const obj = {
name: 'gloabl obj'
}
func(obj)
console.log(obj)
上述代码定义了一个函数,通过这个函数改变一个对象的属性,那外部的这个对象同样也会发生变化,因为它们是指向同一个内存地址的。
如果只需要希望在函数内部修改对象,但不影响外部的对象的话,就可以通过 assign()
方法将这个对象复制到一个全新的空对象。如下代码所示:
function func(obj) {
const funcObj = Object.assign({}, obj)
funcObj.name = 'func obj'
console.log(funcObj)
}
const obj = {
name: 'gloabl obj'
}
func(obj)
console.log(obj)
另外,利用 assign()
方法为函数的对象参数设置默认值也是一个非常常见的业务场景。
Object.is()
方法
ECMAScript2015 还为 Object
对象新增了一个 is()
方法,这个方法可以用来判断两个值是否相等。
在 ECMAScript2015 之前判断两个值是否相等基本上都是使用相等运算符或者全等运算符。如下代码所示:
console.log(0 == false)
相等运算符在比较两个值之前会自动转换值的类型,这就导致上述代码中的 0
和 false
比较的结果为 true
。而全等运算符是同时比较两个值的值和类型,如下代码所示:
console.log(0 === false)
上述代码的运行结果为 false
。但是全等运算符存在两个特殊情况,首先是数字 0 的正负是无法区分的。如下代码所示:
console.log(+0 === -0)
上述代码的运行结果为 true
。当然了,对于应用开发来讲,这个问题是不需要关心的,只有在处理一些数学问题时才可能会出现。
其次是 NaN
,使用全等运算符比较 NaN
的话是不相等的。之前认为 NaN 是一个非数字值,存在无限种可能性,所以说两个 NaN
是不相等的。如下代码所示:
console.log(NaN === NaN)
上述代码的运行结果为 false
。但在今天来看,NaN
实际上就是一个特别的值,所以说两个 NaN
应该是完全相等的。在 ECMAScript2015 中新增了全新的同值比较的算法,就是 Object
对象的 is()
方法。如下代码所示:
console.log(
Object.is(+0, -0),
Object.is(NaN, NaN)
)
上述代码的运行结果如下:
false true
不过,一般情况下很少用到 Object
对象的 is()
方法,大多时候还是建议使用相等运算符和全等运算符。