ES6 对象增强

Wesley13
• 阅读 502

  对象字面量语法扩展:

  1, 属性初始化语法简写给一个属性赋一个变量值,如果变量名和属性名相同,可以省略变量名和冒号,直接写属性名,js引擎在执行代码的时候,自动查找 和属性命名相同的变量并赋值。

ES6 对象增强

let x = 1, y = 2;
let object = {   x, // 属性名是x,变量名也是x, 两者一致,可以简写  y };
console.log(object.x); //output "1"

ES6 对象增强

  2, 更为简洁 的方法属性定义:ES5的时候,把一个函数赋值给属性的时候,函数必须是一个完整的函数定义

let object = {
    myFunction: function(){
        console.log("Hello World")  
    }  
}

  但是在ES6中,可以把:function 这一部分去掉了,写法如下

let object = {
    myFunction(){
        console.log("Hello World")  
    }  
}

  语法确实简洁多了,不过要注意一个特殊情况,只有给属性赋值的是匿名函数的时候,才可以使用简洁语法,如果赋值的是一个有名字的函数,那么就不能使用匿名函数了。如下情况就不能

let object = {
    myFunction: function hello(){
        console.log("Hello World")  
    }  
}

  函数hello 赋值给属性myFunction, 你可能会问,为什么要给函数取一个hello 名字,最常见的一种情况是递归,自己调用自己,如果没有名字,怎么调用?还有就是程序debugger 的时候,有函数名字可以直接定位, you don't know js 的作者就强烈建议书写有名字的函数。

  3, 计算属性名:ES5 的时候,对象字面量中的属性都是事先定义好的, 不能使用变量,从而在程序运行的时候动态生成属性,但在ES6中,这种情况改变了,对象字面量中可以存在动态生成的属性,不过语法就要稍微变一下了,需要把动态属性用[] 包括起来,这样在程序运行的时候可以对[] 中的内容进行计算

let object = {
  ["first" + "Name"]: "Eden",
};

//extract
console.log(object["first" + "Name"]); //Output "Eden"

  4, 对重复属性名的处理: 在ES5 的时候,如果给一个对象赋值为相同的属性,它就会报错。但在ES6 下,它不会报错了,它会取最后一个相同属性的值。

let obj = {
    name: 'Sam',
    name: 'Jason'
};
console.log(obj.name) // 'jason'

  **新的方法
**

1, Object.is() 方法:  判断两个数是否相等。你可能有点差异,不是有 == 和 === 来判断相等了吗,怎么还需要判断相等的方法? 不用担心,Object.is() 是用来处理极端情况的,比如NaN. NaN 和任何数都不相等,包含它本身,没有办法直接比较,现在就可以调用Object.is() 方法了,他就接受俩个要比较相等的参数。Object.is(NaN, NaN);  还有+0和-0, 对于js 引擎来说,他们两个是不相等的,但是 用== 和=== 做判断的时候,他们是相等的,为了解决这种问题,就可以使用Object.is(+0, -0) 

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

  对于Object.is () 来说,你可能发现,我们几乎用不到它, 它就是对=== 操作符在某些极端情况下的纠正,所以对于比较,我们还是用== 或===, 平常怎么用就怎么用,只有碰到极端情况再用Object.is() 方法。 

  2, Object.assign(): 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。Object.assign(target, ...sources),target 目标对象,sources: 源对象

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target); // Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget); // Object { a: 1, b: 4, c: 5 }

   3, Object.setPrototypeOf(), 设置一个对象的原型对象,它接受两个参数,一个是对象,一个是对象要链接到的原型对象 。Object.setPrototypeOf(obj, prototypeObj).

let person = {
    greeting() {
        return "hello";
    }
}

let dog = {
    greeting() {
        return "woof";
    }
}

let obj = {};

// obj 链接到person 
Object.setPrototypeOf(obj, person);
console.log(obj.greeting()); // "hello"
// obj 链接到dog
Object.setPrototypeOf(obj, dog);
console.log(obj.greeting()); // woof

  通过Object.setPrototypeOf() 方法可以动态地改变一个对象的原型对象。这里简单说一下对象的原型,在js中没有所谓的类式继承,因为js中没有java  中的类, 那Js中有什么呢? 它只有对象,当我们把一个对象链接到原型对象上的时候,它是对象和对象之间的关系,就像上面中的代码一样, obj 就一个对象,它的原型对象无论是person, 还是dog, 也是普通的对象, 对象和对象的链接关系,就像火车的车厢

通过链条链接起来一样, 把每一个车厢想象成每一个对象。为什么把对象链接起来呢? 因为另外一个对象有我们想要的方法,比如上面的greeting 方法。我们刚刚声明了一个对象obj,  空对象,什么都没有,刚要给他声明一个greeting 方法,突然发现person  对象有这个方法,那就不要声明了,拿过来用就可以了,这不,这两个对象就有必要链接到一起了。但执行obj.greeting()的时候,发现obj对象上并没有这个方法,但是发现它链接到一个对象person, 那就顺着链条继续找吧,正好,person 对象上有这个方法,就调用了person 对象上的方法。就像火车上找人一样,你先从第一车厢开始,没有,因为第一车厢和第二车厢链接起来了,你就到第二车厢去找,还是没有,第二车厢又和第三车厢链接到一起,你就去第三车厢去找,找到了,如果没有找到,继续第四车厢,因为每一个车厢都是链接起来的。如果所有的车厢都找完了,还是没有,那就真没有了。

  那我们还能不能在obj上面定义一个greeting 方法,因为有时候原型对象上的方法不能完全满足要求?可以,当我们在一个对象上定义一个方法的时候,它就不会就找原型链了,直接调用对象上面的方法。

let obj = {
    greeting() {
        return 'obj';
    }
};

  但有时候, 你发现,在obj 对象中定义的方法,可能使用到原型对象上的同名方法, 只要调用原型对象上面的方法再进行一下组装就可以达到要求了。ES6 提供了super 关键词,它就指向原型对象

let obj = {
    greeting() {
        return super.greeting()  + 'obj';
    }
};

  这里要注意的是,对象方法的定义只能使用简洁的语法形式,否则报错。

  super 是怎么实现的呢?在ES6 中,如果一个对象中定义了方法,这个方法自动获取到一个内置的属性[[HomeObject]], 来指向这个对象。super 呢,就是通过Object.getPrototypeOf([[HomeObject]]) 来获取到原型对象。obj.greeting() greeting() 方法中的[[HomeObject]] 就指向了obj.  那里面的super 就是Object.getPrototypeOf(obj), 那就是person 或dog 了,super.greeting() 就相当于person.greeting()了, 更为准确的说是 person.greeting.call(this).  因为如果person中的greenting有this, 我们还要给它指定this 指向, 不能让里面的this 指向别的对象, 只能让this 指向 obj 了。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Irene181 Irene181
2年前
一篇文章带教会你Python访问限制那些事儿
一、前言在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。二、案例分析以Teacher类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性。classTeacher(object):definit(self,name,score):s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
java8新特性
Stream将List转换为Map,使用Collectors.toMap方法进行转换背景:User类,类中分别有id,name,age三个属性。List集合,userList,存储User对象1、指定keyvalue,value是对象中的某个属性值。 Map<Integer,StringuserMap1userList.str
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
Java基础之类
一、类的一般形式1、类的概述类就是事物的集合和抽象。它所代表的是这类事物所共有的一些行为和属性。2、类的一般形式中国有13亿人,就有13亿个对象人类只有一个class类名{类型变量名;类型变量名;...类型方法名
Wesley13 Wesley13
2年前
ES6
JavaScript定义对象的属性,有两种方法。varobj{foo:true,abc:123};上面代码的方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时要将表达式放在方括号之内。但是,如果使用字面量方式定义对象(使用大括号),在ES5中只能使用方法
Stella981 Stella981
2年前
ES6入门六:class的基本语法、继承、私有与静态属性、修饰器
基本语法继承私有属性与方法、静态属性与方法修饰器(Decorator) 一、基本语法1classGrammar{2constructor(name,age){//定义对象自身的方法和属性3this.namename,
Easter79 Easter79
2年前
Spring两种依赖注入方式的比较
我们知道,Spring对象属性的注入方式有两种:设值注入和构造注入。先看代码:  假设有个类为People,该对象包含三个属性,name和school还有age,这些属性都有各自的setter和getter方法,还有一个包含这三个属性的构造方法。如果用spring来管理这个对象,那么有以下两种方式为People设置属性:  1.设值注入: