【ES6 笔记】扩展对象的功能性

对象类别

  • 普通( Ordinary )对象:具有JavaScript对象所有的默认内部行为;
  • 特异( Exotic )对象:具有某些与默认行为不符的内部行为;
  • 标准( Standard )对象:ES6规范中定义的对象,例如Array、Date等。标准对象既可以是普通对象,也可以使特异对象。
  • 内建对象:脚本开始执行时存在于JavaScript执行环境中的对象,所有标准对象都是内建对象

对象字面量语法扩展

  • 属性初始值的简写
    在我们传统的JS中,对象字面量只是简单的键值对集合,这意味着初始化属性时会有一些重复,举个例子:
function createPerson( name, age ){
  return {
      name : name,  //name写了两遍,一遍是属性名,一遍是变量
      age : age  //age写了两遍,一遍是属性名,一遍是变量
  }
}

在ES6中我们对上面的属性初始化进行了简化,当一个对象的属性与本地变量同名时,不必再写冒号和值,简单地只写属性名即可:

function createPerson( name, age ){
  return {
      name ,
      age
  }
}
/*
* 当对象字面量里只有一个属性的名称时,JS引擎会在可以访问作用域中查找其同名变量;
* 如果找到,则该变量的值被赋给对象字面量里的同名属性。
* 在本例中,对象字面量属性name被赋予了局部变量name的值。
*/
  • 对象方法的简写语法
    在ES6之前,我们为对象添加方法,必须通过制定名称并完整定义函数:
let person = {
    name : '欧阳不乖',
    sayName : function(){
        console.log(this.name)
  }
}

而在ES6中,语法更简洁,消除了冒号和function关键字,让我们来重写上边的例子:

let person = {
    name : '欧阳不乖',
    sayName(){
        console.log(this.name)
  }
}

这种简洁写法与传统的定义对象方法所具有的特性全部一致,二者唯一的区别是,简写方法可以使用super关键字(稍后讨论)

  • 可计算属性名
    在早期函数中,我们如果想要通过计算得到属性名,只能用方括号代替点的方式:
// 我们想要的效果:
let name = 'unknown';
let person = {};
person[ name ] = '欧阳不乖';
console.log(person);  // {unknown: "欧阳不乖"}
/*
* 这里我们要是换一种写法,就会是不一样的结果了
* let name = 'unknown';
* let person = {
*      name : '欧阳不乖'
*  };
* console.log(person);  // {name: "欧阳不乖"}
* 当属性被包含在一个变量中的时候,这种赋值方式和我们设想的就不一样了
*/

在ES6中,可在对象字面中使用可计算属性名称,其语法与引用对象实例的可计算属性名称相同,也是使用方括号:

let name = 'unknown';
let person = {
    [ name ] :  '欧阳不乖'
};
console.log(person);  // {unknown: "欧阳不乖"}

扩展:

let suffix  = 'name';
let person = {
    ['full-'+suffix ] :  '欧阳不乖',
    [`chinese-${suffix}`] : '欧阳不乖'
};
console.log(person);  //{full-name: "欧阳不乖", chinese-name: "欧阳不乖"}

新增API方法

  • Object.is()方法
    Object.is()方法来弥补全等运算符的不准确运算。这个方法接受两个参数,如果这两个参数类型相同且具有相同的值,则返回true。
    其发部分运行结果与“===”运算符相同,唯一的区别在于+0和-0被识别为不相等且NaN与NaN等价。
console.log( '欧阳不乖'==='欧阳不乖' ); // true
console.log( Object.is('欧阳不乖','欧阳不乖') ); // true

console.log( +0 === -0 ); // true
console.log( Object.is(+0, -0) );  // false

console.log( NaN === NaN ); // false
console.log( Object.is(NaN,NaN) );  // true
/* 具体使用哪一种比较方法,主要取决于业务需要 */
  • Object.assign()方法
    接受任意数量的源对象,并按指定的顺序将属性复制到接收对象中。所以如果多个源对象局哟楼同名属性,则排位靠后的源对象会覆盖排位靠前的。
let receiver = {} ;
Object.assign(receiver,
    {
        type : 'js' ,
        name : 'file.js'
    },{
        type : 'css'
    }
);
console.log( receiver ); //{type: "css", name: "file.js"}
console.log( receiver.type ); //'css'
console.log( receiver.name ); //'file.js'

重复的对象字面量属性

在ES5严格模式下,对象字面量属性名重复时会抛出错误
而在ES6中,字面量属性名称如果重复的话,只会选取最后一个取值:

let person = {
    name : 'unKnown',
    name : '欧阳不乖'
}
console.log(person.name); // '欧阳不乖'

自由属性枚举顺序

在ES5中未定义对象属性的枚举顺序,由Javascript引擎厂商自行决定。
在ES6中严格规定了对象的自由属性被枚举时的返回顺序。
自有属性枚举顺序的基本规则是:

  1. 所有数字键按升序排序
  2. 所有字符串键按照它们被加入对象的顺序排序
  3. 所有symbol键按照它们被加入对象的顺序排序
let obj = {
    a:1,
    0:1,
    c:1,
    2:1,
    b:1,
    1:1
}
obj.d = 1;
console.log(Object.getOwnPropertyNames(obj).join('')); //012acbd

对于数值键,尽管在对象自绵中的顺序是随意的,但是在枚举时会被重新组合和排序
对于for-in、Object.keys和JSON.stringify()方法暂时仍按照各引擎厂商的自行实现顺序枚举

增强对象原型

  • 改变对象的原型
    正常情况下,对象原型是在对象被创建的时候指定的,对象原型在实例化之后保持不变。
    在ES6中添加了Object.setPrototypeOf()方法来改变对象原型,它接受两个参数:被改变原型的对象及替代第一个参数原型的对象:
let person = {
    getGreeting(){
          return 'Hello';
    }
};
let dog = {
    getGreeting(){
        return 'Woof';
    }
}
// 以person对象为原型
let friend = Object.create(person);
console.log(friend.getGreeting()); // 'Hello'
console.log(Object.getPrototypeOf(friend)===person); // true
// 将原型设置为dog
Object.setPrototypeOf(friend,dog);
console.log(friend.getGreeting()); // 'Woof'
console.log(Object.getPrototypeOf(friend)===dog); // true

对象原型的真实值被存储在内部专用属性[[Prototype]]中,调用Object.getPrototypeOf()方法返回存储在其中的值,调用Object.setPrototypeOf()方法改变其中的值

  • 简化原型访问的Super引用
    ES6中引入了Super引用的特性,使用它可以更便捷地访问原型对象。
let person = {
    getGreeting(){
          return 'Hello';
    }
};
let dog = {
    getGreeting(){
        return 'Woof';
    }
}
let friend = {
    getGreeting(){
          return super.getGreeting() + ',nice to meet you. '             
          // 等价于 Object.getPrototypeOf(this).getGreeting().call(this)
    }
}

简单来说,Super引用相当于指向对象原型的指针,实际上也就是Object.getPrototypeOf(this)的值。
Super引用不是动态变化的,它总是指向正确的对象。
Super方法必须在简写方法的对象中使用,其他地方引用会导致语法错误。

正式的方法定义

在上边我们用Super的时候指明要求只能在简写方法的对象中使用,下面我们来解释一下原因。
在ES6中正式将方法定义为一个函数,它会有一个内部的[[HomeObject]]属性来容纳这个而方法从属的对象:

let person = {
    // 是方法
    getGreeting(){
          return 'Hello';
    }
}
// 不是方法
function shareGreeting(){
    return 'Hi !'
}

这个示例中定义了person对象,它有一个getGreeting()方法,由于直接把函数赋值给了person对象,因而getGreeting()方法的[[HomeObject]]属性值为person。而创建shareGreeting()函数时,由于未将其赋值给一个对象,因为该方法没有明确定义[[HomeObject]]属性。在大多数情况下这点小差别无关紧要,但是当使用Super引用时就变得非常重要了。
Super的所有引用都通过[[HomeObject]]属性来确定后续的运行过程,第一步是在[[HomeObject]]属性上调用Object.getPrototypeOf()方法来检索原型的引用:然后搜寻原型找到同名函数;最后,设置this绑定并且调用相应的方法。
注意:这里定义的是方法,而非函数,二者都是函数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容