4. 扩展对象的功能性
1. 对象类别
- 普通对象:具有JS对象所有的默认内部行为
- 特异对象:具有某些与默认行为不同的行为
- 标准对象:ES6中定义的对象,比如Array,Date等。标准对象可以为普通对象,也可以是特异对象
- 内建对象:脚本开始执行是,存在于JSS执行环境的对象。所有标准对象都是内建对象。
2. 对象字面量语法扩展
2.1.属性初始值的简写
- 属性初始值简写:
{属性名: 属性值名称} // 当属性名===属性值名称就可以写作 {属性名}
2.2.对象方法的简写语法
{
a: '我是a',
b () {
console.log('我是b方法');
}
}
与之前的区别就是这里可以使用super关键字。 之前的不能使用super
2.3.可计算属性名
读取属性的方法
var a = {
'this Male': true
} // {this Male: true, last Name: "Nick", first Name: "zak"}
var lastName = 'last Name';
a[lastName] = 'Nick'
a["first Name"] = 'zak'
var lastName = 'last Name';
var a = {
[lastName]: 'Nick', // 使用[]表示该属性名称是可计算的
"first Name": 'zak',
'this Male': true
}
3. 新增方法
ES6的设计目标是:不再创建新的全局函数,也不再object.prototype上创建新的方法。
3.1.Object.is()
我们一般比较两值相等的情况使用"==="或者"=="。其实是有特列的,+0 === -0 // true NaN ===NaN // false 判断是否NaN徐亚使用isNaN
弥补全等运算的不准确运算
console.log(+0 == -0) // true
console.log(+0 === -0) // true
Object.is(+0, -0) // false
console.log(NaN == NaN) // true
console.log(NaN === NaN) // true
Object.is(NaN, NaN) // false
其实大多数表现都是一致的和'==='只有在+0与-0和NaN与NaN之间做比较,才会有不同的行为。当我们有这些特殊情况时,我们使用这个方法比较妥当。
3.2.Object.assign()
mixin是在JS中组合对象时最流行的模式。在一次混入中,一个对象会从另一个对 象中接收属性与方法。
function mixin(receiver, supplier) {
Object.keys(supplier).forEach(function(key) {
receiver[key] = supplier[key];
});
return receiver;
}
这里就是对属性进行拷贝而已。这种方法可以不用原型继承就可以使用另一个对象的方法。
运用场景:
// 作用:使用另外一个对象上的方法
function EventTarget () { /*...*/ }
EventTarget.prototype = {
constructor: EventTarget,
emit: function() { /*...*/ },
on: function() { /*...*/ }
};
var myObject = {};
mixin(myObject, EventTarget.prototype);
myObject.emit("somethingChanged");
- 相同:Object.assign()也是相同的模式。传参方式和mixin相同。
- 区别:2.1 由于mixin()函数使用了赋值运算符(=),它就无法将访问器属性复制到接收者上,Object.assign()体现了这种区别。2.2 Object.assign()并未在接收者上创建访问器属性,即使供应者拥有访问器属性。由于Object.assign()使用赋值运算符,供应者的访问器属性就会转变成接收者的数据属性。
重要!当属性名称一样时,会进行覆盖
4. 重复的对象字面量属性
ES6严格模式下,可以允许一个对象有重复的属性名。只是会发生覆盖。
5. 自有属性枚举顺序
ES6 则严格定义了对象自有属性在被枚举时返回的顺序。这对Object.getOwnPropertyNames()与Reflect.ownKeys如何返回属性造成了影响,还同样影响了 Object.assign()处理属性的顺序。(覆盖原因嘛)。这意味着object.asign不是我们想象中的进行覆盖,所以需要注意。
- 所有的数字类型键,按升序排列。**
- 所有的字符串类型键,按被添加到对象的顺序排列。
- 所有的符号类型键,也按添加顺序排列。
- for-in 循环的枚举顺序仍未被明确规定(Object.keys()和Json.stringify()和for-in的顺序相同)
6. 增强对象原型
6.1.改变对象原型
原型是在对象被创建时指定的。对象原型在实例化之后保持不变。ES5中添加了object.getPrototypeOf()返回对象的原型。
居然还有这种创建对象的方法
let Person = {
say () {
return 'Hello'
}
}
let P1 = Object.create(Person);
Object.getPrototypeOf(P1) === Person // true
调用Object.getPrototypeOf()方法返回对象[[Prototype]]值。调用Object.setPrototype可以改变原型值。但是还有别的方法。
6.2.简化对象访问的Super()引用
Super为了更方便访问对象原型。super是指向当前对象的原型的一个指针
function Person () {
this.name = 'hahaha'
}
Person.prototype = {
say () {
return 'hihihiihi'
}
}
var s = new Person();
Object.setPrototypeOf(s, {age: '121212'}) // 这种方法难以继承
s.age //"121212"
s.say() // 报错
function Person () {
this.name = 'hahaha'
}
Person.prototype = {
say () {
return 'hihihiihi'
}
}
var friend = {
//gretet () {return Object.getPrototypeOf(friend).say.call(this)+'你好'}
//从原型中找到相应的方法,并且绑定自己
gretet () {return super.say()+'你好'}
//gretet: function() {} 错误的
}
var s = new Person();
Object.setPrototypeOf(friend, Person.prototype).gretet()
// friend对象要重写 但是可以使用部分后面Person.prototype中的方法 继承
当然这非常麻烦,所以引入了super
7. 正式的方法定义
方法是一个拥有[[HomeObject]]内部属性的函数,此内部属性指向该方法所属的对象
任何对super的引用都会使用[[HomeObject]]属性来判断要做什么。
这一点对于super非常重要。super第一步是在[[HomeObject]]上调用Object.getPrototypeOf()来获取对原型的引用;接下来,在该原型 上查找同名函数;最后,创建this绑定并调用该方法。