es6:对象的扩展

149 阅读3分钟

“这是我参与更文挑战的第8天,活动详情查看: 更文挑战

新的对象字面量特性

1.方法的简写
2.属性的简写
3.属性名表达式

// 方法的简写
let obj = {
    init : function(){
        console.log('123')
    }
}
obj.init();

// 可简写为
let obj = {
    init(){
        console.log('123')
    }
}
obj.init();
// 属性的简写
let name = 'ccy';
let obj = {
    name:name
}
console.log(name);

// 可简写为:
let obj = {name};
console.log(obj.name);
// 属性名表达式
let obj = {
    ['hel'+'lo']:'world',
    ['es'+6](){
        return 'good';
    }
}
console.log(obj['hello']);
console.log(obj['es6']());

属性简写和属性名表达式不能一起用

// 属性简写和属性名表达式不能一起用
let hello = "hello";
let obj = {
    [hello]
} // 报错:Uncaught SyntaxError: Unexpected token '}'

新的对象方法

1.Object.is(a, b)

与===类似,可以比较两者是否严格一致,但在NaN和±0上有差别

//Object.is 与 ===
// NaN
console.log(NaN === NaN); // fasle
console.log(Object.is(NaN, NaN)); // true

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

模仿Object.is写一个es5的工具方法
借助以下3个特点来判断NaN和±0:

NaN !== NaN 
1 / +0 = Infinity
1 / -0 = -Infinity
// 不用bable的匹配es5的工具方法
function isEq(a,b) {
    if (a !== a){
        return b !== b; // 如果b也是NaN,则返回true
    }
    if (a === 0 && b ===0 && (1/a === -Infinity || 1/a === Infinity)){
        return false;
    }
    return a === b;

}

console.log( isEq(NaN,NaN) ); // true
console.log(isEq(+0,-0)); // false

2.Object.setPrototypeOf(obj, prototype)

功能:给obj设置原型prototype,es5里就有的

let obj = {
    a:1,
    b:2
}
let obj1 = {
    c:3
}
Object.setPrototypeOf(obj1,obj);
console.log(obj1.c); // 输出3
// 之前设置原型的方法
// 方法一:__proto__,私有属性,没有写在es标准里,js不对外开放使用权,由浏览器开放
obj1.__proto__ = obj;
console.log(obj1.c); // 输出3  
// 方法二:Object.create,生成一个有指定原型对象和属性的新对象,仅能设置一次原型
let obj2 = Object.create(obj1); // 以obj1为原型,创建新对象obj2
console.log(obj2.c);

相应的,__proto__getPrototypeOf可以获取对象的原型

3.Object.assign(target, source_1, …)

功能:合并对象

let obj = {
    a:1
}
let obj1 = {
    b:2
}
let obj2 = {
    c:3
}
Object.assign(obj, obj1, obj2);
console.log(obj); // {a:1, b:2, c:3}

注意:

1.只能合并对象的属性,对象原型上的属性不会被合并

// 1.只能合并对象的属性,对象原型上的属性不会被合并
let obj4 = {
    d:4
}
Object.setPrototypeOf(obj2, obj4); // 设置obj2的原型为obj4
console.log(obj2.d); // 4
Object.assign(obj, obj1, obj2);
console.log(obj); // {a:1, b:2, c:3} 没有出现obj2的属性d

2.只能合并自身可遍历的属性

// 只能合并自身可遍历的属性
Object.defineProperty(obj2, "e", {
    value: 5,
    enumable: false
}); // 设置obj2的不可遍历属性e
console.log(obj2.e); // 5
Object.assign(obj, obj1, obj2);
console.log(obj); // {a:1, b:2, c:3} 没有出现obj2的属性e

3.按形参顺序合并,如果源对象之间或源对象和目标对象出现同名的属性,后面的会覆盖前面的属性

4.复制合并为浅拷贝

使用场景:

1.对象的复制

// 使用场景一:对象的复制,注意是浅拷贝
let obj = {
    a:1,
    b:2
}
let obj2 = Object.assign({}, obj);
console.log(obj2);

2.原型方法的添加

// 使用场景二:原型方法的添加
function Person(){
    this.name = 'ccy'
}
// 之前的方法
// Person.prototype.eat = function(){
//     console.log('cf')
// }

// 用Object.assign
Object.assign(Person.prototype, {
    eat: function(){
        console.log('eat');
    }
})

person = new Person();

在这里插入图片描述
3.函数默认参数

// 使用场景三:函数默认参数
const DEFAULT = {
    a:1,
    b:2
}
function fn(options){
    let realOption = Object.assign({}, DEFAULT, options);
    return realOption;
}
console.log( fn() );
let obj = {
    realObject: function(options){
        return Object.assign(DEFAULT, options)
    }
}

console.log(obj.realObject())

对象的遍历

1.Object.keys:遍历出属性名,返回数组
2.Object.values(es2017):遍历出属性值,返回数组
3.Object.entries(es2017):遍历属性键值对,返回数组,每个键值对也用数组包裹

let obj = {
    a:1,
    b:2,
    c:3
}
console.log( Object.keys(obj) ); // ["a", "b", "c"]
console.log( Object.values(obj) ); // [1, 2, 3]
console.log( Object.entries(obj) ); // [["a":1],["b":2],["c":3]]

整理:
在这里插入图片描述