ES6躬行记(11)——对象
在第5篇中,讲解了多个对象字面量的改进,本节将重点介绍两个新增的静态方法,以及对象属性的重复处理和枚举顺序。
一、Object.is()
此方法用于判断两个值是否相同,内部实现了SameValue算法,其行为类似于全等(===)比较,但它认为两个NaN是相等的,而+0和-0却是不等的。Object.is()和全等的区别如下所示。
NaN === NaN; //false
Object.is(NaN, NaN); //true
+0 === -0; //true
Object.is(+0, -0); //false
二、Object.assign()
此方法可将多个对象合并成一个,它的第一个参数是目标对象,剩余的参数都是源对象,返回值是最终的目标对象,接下来会列举出此方法的6个特点。
(1)只能拷贝可枚举的自有属性(定义在对象中),无法拷贝继承属性(定义在对象原型中)和不可枚举的属性。以下面的代码为例,obj2对象中的name是继承属性,age是不可枚举的属性,只有school是可枚举的自有属性,因此只有school属性拷贝到了空对象中。
var obj1 = { name: "strick" },
obj2 = Object.create(obj1); //name是继承属性
obj2.age = 28; //age是不可枚举的属性
Object.defineProperty(obj2, "age", {
enumerable: false
});
obj2.school = "university"; //school是可枚举的自有属性
Object.assign({}, obj2); //{school: "university"}
(2)遇到同名的属性,后面的会覆盖之前的。例如下面的两个对象obj1和obj2都包含name属性,obj1在obj2之前传到方法中,最终obj1对象的name属性将被覆盖掉。
var obj1 = { name: "strick" },
obj2 = { name: "freedom" };
Object.assign({}, obj1, obj2); //{name: "freedom"}
(3)Object.assign()执行的是浅拷贝,如果属性的值是对象,那么只会拷贝引用该对象的指针。在下面的代码中,obj1对象的man属性是一个对象,将其与空对象合并,然后把返回值赋给obj2变量,再修改obj1中的name属性,由于是浅拷贝,因此obj2中的name属性也会受影响。
var obj1 = { man: { name: "strick" } },
obj2 = Object.assign({}, obj1);
obj1.man.name = "freedom";
console.log(obj2); //{man: {name: "freedom"}}
(4)Symbol类型的属性也能被拷贝。Symbol是ES6引入的第6种基本类型,可以像字符串那样作为对象的属性名,具体如下所示。
var obj1 = { [Symbol("name")]: "strick" },
obj2 = Object.assign({}, obj1);
console.log(obj2); //{Symbol(name): "strick"}
(5)当源对象的位置是基本类型的值时,它们会被包装成对象,再进行合并。但由于undefined和null没有包装对象,并且数字和布尔值的包装对象又没有可枚举的属性,因此只有字符串的包装对象才能不被忽略,最终以数组的形式拷贝到目标对象中,如下所示。
var obj = Object.assign({}, 1, "a", true, undefined, null);
console.log(obj); //{0: "a"}
(6)源对象的访问器属性会变成目标对象的数据属性。如下代码所示,obj对象包含一个名为name的访问器属性,在把它与空对象合并后,目标对象会有一个名为name的数据属性,其值就是访问器属性中get()方法的返回值。
var obj = {
get name() {
return "strick";
}
};
Object.assign({}, obj); //{name: "strick"}
三、重复属性
在ES5的严格模式中,重复的属性名会引起语法错误。但ES6不会再做这个检查,当出现重复属性时,排在后面的同名属性将覆盖前面的,即属性值以后面的为准,执行过程如下所示。
var obj = {
name: "strick",
name: "freedom"
};
console.log(obj.name); //"freedom"
四、枚举顺序
ES6规定了自有属性的枚举顺序,并且会将同一类别的属性整合到一块,具体的排列规则如下所列:
(1)首先遍历数字类型或数字字符串的属性,按大小升序排列。
(2)接着遍历字符串类型的属性,按添加时间的先后顺序排列。
(3)最后遍历符号类型的属性,也按添加顺序排列。
for-in循环、JSON对象的序列化方法stringify()、Object对象的getOwnPropertyNames()、keys()、getOwnPropertySymbols()以及新引入的assign()方法在执行过程中都会遵循这套新的排列规则,具体如下所示。
var obj = {
c: 1,
1: 2,
a: 3,
"0": 4,
[Symbol("x")]: 5,
[Symbol("y")]: 6
};
var properties = [];
for(var key in obj) {
if(obj.hasOwnProperty(key)) { //过滤掉继承属性
properties.push(key);
}
}
console.log(properties); //["0", "1", "c", "a"]
JSON.stringify(obj); //{"0":4,"1":2,"c":1,"a":3}
Object.getOwnPropertyNames(obj); //["0", "1", "c", "a"]
Object.keys(obj); //["0", "1", "c", "a"]
Object.getOwnPropertySymbols(obj); //[Symbol(x), Symbol(y)]
Object.assign({}, obj); //{0: 4, 1: 2, c: 1, a: 3, Symbol(x): 5, Symbol(y): 6}
ES6躬行记(11)——对象的更多相关文章
- ES6躬行记(1)——let和const
古语云:“纸上得来终觉浅,绝知此事要躬行”.的确,不管看了多少本书,如果自己不实践,那么就很难领会其中的精髓.自己研读过许多ES6相关的书籍和资料,平时工作中也会用到,但在用到时经常需要上搜索引擎中查 ...
- ES6躬行记 笔记
ES6躬行记(18)--迭代器 要实现以下接口## next() ,return,throw 可以用for-of保证迭代对象的正确性 例如 var str = "向
- ES6躬行记(8)——数字
一.进制 ES6不仅完善了数字的八进制形式,还补充了一种十六进制形式,并且添加了全新的二进制形式.下面的三个变量分别表示八进制.十六进制和二进制的10,注释中给出了该进制的另一种写法. var oct ...
- ES6躬行记(5)——对象字面量的扩展
一.简洁属性和方法 当创建对象字面量时,如果属性值是与属性同名的已定义的标识符(例如变量.常量等),那么ES6允许省略冒号和属性值,这样就能避免冗余的初始化.下面分别用传统的键值对和最新的简写方式创建 ...
- ES6躬行记(21)——类的继承
ES6的继承依然是基于原型的继承,但语法更为简洁清晰.通过一个extends关键字,就能描述两个类之间的继承关系(如下代码所示),在此关键字之前的Man是子类(即派生类),而在其之后的People是父 ...
- ES6躬行记(18)——迭代器
ES6将迭代器和生成器内置到语言中,不仅简化了数据处理和集合操作,还弥补了for.while等普通循环的不足,例如难以遍历无穷集合或自定义的树结构等. 迭代器(Iterator)是一种用于迭代的对象, ...
- ES6躬行记(16)——Set
ES6引入了两种新的数据结构:Set和Map.Set是一组值的集合,其中值不能重复:Map(也叫字典)是一组键值对的集合,其中键不能重复.Set和Map都由哈希表(Hash Table)实现,并可按添 ...
- ES6躬行记(13)——类型化数组
类型化数组(Typed Array)是一种处理二进制数据的特殊数组,它可像C语言那样直接操纵字节,不过得先用ArrayBuffer对象创建数组缓冲区(Array Buffer),再映射到指定格式的视图 ...
- ES6躬行记(3)——解构
解构(destructuring)是一种赋值语法,可从数组中提取元素或从对象中提取属性,将其值赋给对应的变量或另一个对象的属性.解构地目的是简化提取数据的过程,增强代码的可读性.有两种解构语法,分别是 ...
随机推荐
- BP神经网络算法推导及代码实现笔记zz
一. 前言: 作为AI入门小白,参考了一些文章,想记点笔记加深印象,发出来是给有需求的童鞋学习共勉,大神轻拍! [毒鸡汤]:算法这东西,读完之后的状态多半是 --> “我是谁,我在哪?” 没事的 ...
- 压力测试工具 Apache_jmeter软件配置+TCP示例说明
该软件jmeter是Apache官方开源压力测试软件. jmeter官网:http://jmeter.apache.org/ . 本文使用的版本是 3.0版本, 它需要jdk7及以上版本支持. 网 ...
- 通过shell脚本进行数据库操作
#!/bin/bash HOSTNAME="192.168.111.84" #数据库信息 PORT=" USERNAME="root" PASSWOR ...
- div界面元素生成图片
首先明确一下需求,界面上截取部分元素,生成图片,用户可以长按保存.主要是在微信里,所以设计到生成二维码的问题. 1.链接生成二维码,这里用qrcode生成,搜索可以搜到相关的js文件 var myUr ...
- intent和手势探测
一.三种启动方法 setComponent ComponentName comp = new ComponentName( this, SecondActivity.class); Intent in ...
- php面试题--并列排名问题
给定一个二维数组: <?php $data = [ ['name' =>'j1', 'score' => '80'], ['name' =>'j2', 'score' => ...
- Python核心团队计划2020年停止支持Python2,NumPy宣布停止支持计划表
Python核心团队计划在2020年停止支持Python 2.NumPy项目自2010年以来一直支持Python 2和Python 3,并且发现支持Python 2对我们有限的资源增加了负担:因此,我 ...
- Product and Sum in Category Theory
Even if you are not a functional programmer, the notion of product type should be familiar to you, e ...
- jenkins在windows服务器上执行含git push命令的脚本权限不足的解决方法
错误摘要 默认情况下执行脚本是没问题的,但是脚本中含有git push命令就无法执行了 用jenkins部署hexo博客时候遇到的,执行hexo d -g一直阻塞至Build was aborted, ...
- 吴恩达机器学习笔记15-假设陈述(Hypothesis Representation)
在分类问题中,要用什么样的函数来表示我们的假设呢?此前说过,希望我们的分类器的输出值在0 和1 之间,因 此,我们希望想出一个满足某个性质的假设函数,这个性质是它的预测值要在0 和1 之间.回顾在一开 ...