ES6语法(三) 对象

首先,在JavaScript中对象是个很重要的概念,因为在JavaScript中一切都是对象,无论是函数,还是数组。同样,ES6这次也带来了一些新特性。能够帮助我们更加轻松与准确的完成想要完成的目标。

对象字面量语法拓展

对象字面量属性简写

在ES6之前。我们使用字面量创建属性,会写一个属性名,后面跟一个":",最后跟着属性值。看起来一切都是很简洁的,但是在属性值与属性名同名时,这就很痛苦了,每次都要写两个同样的文字。我们看个例子:

    let Person = function(name,age){
        return {
            name : name,
            age : age,
        }
    }
复制代码

一个两个这种代码没问题,但是当类似的代码量一旦多起来,那便是很痛苦的一件事了。但是,在ES5中,这个问题将得到解决。它为我们提供了简写方式。

    let Person = function(name,age){
        return {
            name,
            age,
        }
    }
复制代码

在使用字面量的时候,我们只需写一个变量名就好,剩下的工作由JavaScript引擎帮我们去做。JavaScript引擎回去可访问作用域查找同名属性,找到便会将该变量的值赋值给字面量对象的同名属性。如果没找到,这个属性的值为undefined。

对象字面量的可计算属性名

在ES6之前,我们可以在对象创建之后,使用可计算属性名,但是无法在对象字面量中使用可计算属性名。现在ES6将可计算属性名带到了对象字面量中。

    // ES6之前
    
    let param1 = 'name';
    let person = {};
    person[param1] = 'kidd';
    console.log(person[name]);       // kidd
    
    //不允许
    let dog = {
        [param]:'Snoopy',
    }
    
    // ES6
    
    let firstName = 'first Name';
    
    let cat = {
        [firsName]:'tom'
    }
    console.log(cat[firstName]);        // tom
    
复制代码
对象方法的简写

这不是一个重大的改进。但是能帮助我们书写起来更容易。

    // ES6之前按
    let person= {
        getName:function(){
            return : this.name
        }
    }
    
    // ES6
    let person = {
        getName(){
            return this.name;
        }
    }
    
复制代码
重复的对象字面量属性

在ES5及之前,我们如果在对象字面量中声明了两个同名属性,严格模式下便会报错。而ES6中将这个特性改变了,无论是否在严格模式下,对象字面量中声明了两个同名属性,之后后面的属性会生效。

    let person = {
        getName(){
            return 'tom';
        },
        
        getName(){
            return 'jure';
        }
    }
    
    person.getName();       // jure
复制代码
对象自有属性的枚举顺序

在ES6之前自由属性的枚举顺序基本都是百家争鸣,不同的JavaScript引擎,都会有不同的枚举顺序,这次ES6算是将自由属性的枚举顺序给出了官方说法

  • 所有数字键按照升序排列
  • 所有字符串键按照它们被加入对象的顺序排列
  • 所有symbol键按照它们被加入对象的顺序排列

对象新增方法

在ES6也给对象新增了一些方法,下面让我们来看看

Object.is()

Object.is()很想一个完整版的 “===”,因为它大部分情况下与 “===” 相同,只有两种情况与 “===” 有一些差别。就是下面两种情况

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

复制代码

除了上面两种情况,与 “===”是一样的。

Object.assign()

因为很多JavaScript第三方库有混合模式,这次ES6便将它们直接引入进来。assign方法的主要作用是将一个对象的方法、属性复制给另一个对象。注意,这里的复制其实是浅复制,如果被复制对象的属性值是一个对象的话,那么便只是将这个对象的引用复制给被复制对象。

    function EventTarget(){ doSomething };
    
    EventTarget.prototype = {
        constructor : EventTarget,
        emit : function(){ doSomething },
        on : function(){ doSomething }
    }
    
    var obj = {},
    Object.assign(obj,EventTarget.prototype);
    
    obj.on();

复制代码

这样的话,新创建的对象就会拥有之前对象的属性。而且assign是可以接受任意数量的源对象的。如果不同的源对象中有同名属性,最后被复制对象中会采用最有一个拥有此属性的对象的属性值。 还有一个很重要的点。assign是不能复制访问器属性的。如果源对象中有访问器属性,会在新的对象中变为数值属性。

增强对象原型

我们都知道,JavaScript最特别的地方就是使用了原型继承的方式。而现在,ES6对对象原型又进行了增强。

Super引用

super引用其实就是保存了当前对象的原型对象的引用,在ES6之前,我们要获得对象的原型只有通过Object.getPrototypeOf(this)的方法去返回原型对象。但是这个方法在某些情况的时候会发生某些错误,比如


    let person = {
        getGreeting(){
            return 'Hello';
        }
    };
    
    let friend = {
        getGreeting(){
            return Object.getPrototypeOf(this).getGreeting.call(this) + ", Hi!";
        }
    }
    
    Object.setPrototypeOf(friend,person);
    
    let relative = Object.create(friend);
    
    console.log(person.getGreeting());          // Hello
    console.log(friend.getGreeting());          // Hello, Hi!
    console.log(relative.getGreeting());        // error

复制代码

这里的问题是陷入了一个调用死循环,this是relative时Object.getPrototypeOf(this)返回的对象是friend。而Object.getPrototypeOf(this).getGreeting会调用friend的getGreeting()方法。后面的call(this)又会去改变当前的函数作用域,因此,陷入了一个递归调用的死循环,最后栈溢出报错,但是在ES6中使用super就会解决这个问题

    let person = {
        getGreeting(){
            return 'Hello';
        }
    };
    
    let friend = {
        getGreeting(){
            return super.getGreeting() + ", Hi!";
        }
    }
    
    Object.setPrototypeOf(friend,person);
    
    let relative = Object.create(friend);
    
    console.log(person.getGreeting());          // Hello
    console.log(friend.getGreeting());          // Hello, Hi!
    console.log(relative.getGreeting());        // Hello, Hi!
    
复制代码

这是因为super引用不是动态变化的,它总是指向正确的对象。

改变对象原型的方法

在ES6之前我们要改变对象的原型很麻烦,现在ES6有了setPrototypeOf(),可以轻而易举的改变对象的原型。

   
   let person = {
        getGreeting(){
            return 'Hello';
        }
    };
    
    let dog = {
        getGreeting(){
            return 'Woof';
        }
    };
    
    let friend = Object.create(person);
    console.log(friend.getGreeting());      // Hello
    console.log(Object,getPrototypeOf(friend) === person);  //true
    
    Object.setPrototype(friend,dog);
    console.log(friend.getGreeting());      // Woof
    console.log(Object,getPrototypeOf(friend) === dog);  //true
    
复制代码

以上便是ES6有关对象的内容,如果您有不同的见解或者是本文哪里有错误,你都可以在下面留言给我!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值