ES6 对象的新功能与解构赋值介绍(2)

// demo7 let coder1 = { getName () { console.log("coder1 name: ") Object.getPrototypeOf(this).sayName.call(this) } } // 设置 coder1 对象的原型为 hero(demo6) Object.setPrototypeOf(coder1, hero) coder1.getName() // coder1 name: lee let coder2 = { getName () { console.log("coder2 name: ") super.sayName() } } Object.setPrototypeOf(coder2, hero) coder2.getName() // coder2 name: lee

在 coder1 对象的 getName 方法还需要call(this)保证使用的是原型方法的 this,比较复杂,并且在多重继承会出现递归调用栈溢出错误,而直接使用Super就很简单安全。

注意必须在简写方法中使用Super,要不然会报错,例如以下代码运行语法错误:

let coder4= { getName: function () { // getName () 正确 super.sayName() // SyntaxError: 'super' keyword unexpected here }

因为在例子中 getName 成为了匿名 function 定义的属性,在当前上下问调用Super引用是非法的。如果不理解,可以进一步看下方法的从属对象。

3.2 方法的从属对象

ES6 之前“方法”是具有功能而非数据的对象属性,ES6 正式将方法定义为有 [[HomeObject]]内部属性的函数。

[[HomeObject]]属性存储当前方法的从属对象,例如:

let coder5 = { sayName () { console.log("I have HomeObject") } } function shareName () { console.log("No HomeObject") }

coder5 对象的 sayName( ) 方法的[[HomeObject]]属性值为 coder5,而 function 定义的 shareName( ) 没有将其赋值给对象,所以没有定义其[[HomeObject]]属性,这在使用Super时很重要。

Super就是在[[HomeObject]]属性上调用Object.getPrototypeOf()获得原型的引用,然后搜索原型得到同名函数,最后设置 this 绑定调用相应方法。

四、解构赋值

ES6 为数组和对象字面量提供了新特性——解构,可以简化数据提取的过程,减少同质化的代码。解构的基本语法示例如下:

let user = { name: 'jenny', id: 18 } let {name, id} = user console.log(name, id) // jenny 18

注意在这段代码中,user.name 存储在与对象属性名同名的 name 变量中。

4.1 默认值

如果解构时变量名称与对象属性名不同,即在对象中不存在,那么这个变量会默认为undefined:

let user = { name: 'jenny', id: 18 } let {name, id, job} = user console.log(name, id, job) // jenny 18 undefined

4.2 非同名变量赋值

非同名变量的默认值为undefined,但更多时候是需要为其赋值的,并且会将对象属性值赋值给非同名变量。ES6 为此提供了扩展语法,与对象字面量属性初始化程序很像:

let user = { name: 'jenny', id: 18 } let {name, id = 16, job = 'engineer'} = user console.log(name, id, job) // jenny 18 engineer let {name: localName, id: localId} = user console.log(localName, localId) // jenny 18 let {name: otherName = 'lee', job: otherJob = 'teacher'} = user console.log(otherName, otherJob) // jenny teacher

可以看出这种语法实际与对象字面量相反,赋值名在冒号左,变量名在右,并且解构赋值时,只是更新了默认值,不能覆盖对象原有的属性值。

4.3 嵌套解构

解构嵌套对象的语法仍然类似对象字面量,使用花括号继续查找下层结构:

let user = { name: 'jenny', id: 18, desc: { pos: { lng: 111, lat: 333 } } } let {desc: {pos}} = user console.log(pos) // { lng: 111, lat: 333 } let {desc: {pos: {lng}}} = user console.log(lng) // 111 let {desc: {pos: {lng: longitude}}} = user console.log(longitude) // 111

五、对象类别

ES6 规范定义了对象的类别,特别是针对浏览器这样的执行环境。

普通(Ordinary)对象

具有 JS 对象所有的默认内部行为

特异(Exotic)对象

具有某些与默认行为不符的内部行为

标准(Standard)对象

ES6 规范中定义的对象
可以是普通对象或特异对象,例如 Date、Array 等

内建对象

脚本开始执行时存在于 JS 执行环境中的对象
所有标准对象都是内建对象

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ce293b0678b2950b82d6b535c30f650d.html