ES6 学习笔记之四 对象的扩展
ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便。
一、属性的简洁表示法
当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名。
例1:
var x = , y = ,
o = {
x,
y
}
与例2:
var x = 2, y = 3,
o = {
x: x,
y: y
}
是相同的。
二、方法的简洁表示法
下面的例子是方法的简洁表示法(例3)
let o = {
m (x) {
console.log(x);
}
}
o.m("Hello!");
和下例是完全等同的(例4)
let o = {
m: function (x) {
console.log(x);
}
}
o.m("Hello!");
由于例3和例4完全相同,也就是说例3中的函数也是匿名函数,不能在函数内部使用函数名调用自身,因此下例(例5)这种使用命名函数定义方法,并作自我调用的情况,是不能使用方法的简洁表示法的:
let o = {
factorial: function factorial (x) {\
if (x > 1) {
return x * factorial(x - 1)
} else {
return 1;
}
}
}
console.log(o.factorial(5));
三、 属性名表达式
ES6 允许在字面量定义对象时,使用表达式做属性名和方法名,示例如下(例6):
let firstName = 'first';
let secondFrontName = 'se';
let secondBehandName = 'cond';
let funcName = function () {
return 'func';
}
let methodName1 = 'sayHello';
let methodName2 = 'sayBye';
let obj = {
[firstName]: 'hello',
[secondFrontName + secondBehandName]: 'world',
[funcName()]: 'bye',
[methodName1]() {
console.log('Hello, world!');
},
[methodName2]: function () {
console.log('Goodbye!');
}
}
console.log(obj[firstName]);
console.log(obj[secondFrontName + secondBehandName]);
console.log(obj[funcName()]);
obj.sayHello();
obj.sayBye();
注意,在第13行时,同时使用了属性名表达式和方法的简洁表示法,这是没问题的。
但是不能同时使用属性名表达式和属性的简洁表示法,会报错(例7):
let foo = 'bar';
let bar = 'abc';
let baz = { [foo] };
四、操作[Prototype]
作为原型继承语言,在JavaScript中,prototype属性是非常重要的。在前ES6中,浏览器提供了扩展的属性__proto__,来获取和设置它。
ES6 将这个属性放在了标准的附录部分,并且说明仅要求浏览器实现这个属性,也就是说只有在浏览器中的脚本使用这个属性才是安全可信赖的。
为保持对特定环境的非依赖,不应该在代码中使用这个属性。而应该使用 Object.setPrototypeOf(...) 和 Object.getPrototypeOf(...) 方法设置和获取,这两个方法是全环境安全的。
例8:
let proto = {};
proto.y = 20;
let obj = {x : 10};
console.log(Object.getPrototypeOf(obj));
console.log(obj.y);
Object.setPrototypeOf(obj, proto);
console.log(Object.getPrototypeOf(obj));
console.log(obj.y);
第四行的结果显示,obj 的 [prototype] 是 Object,并且第五行获得的 y 属性为 undefined。
经过第6行的设置,obj 的 [prototype] 就是proto对象了,并且第8行 obj 的 y 属性是循着原型链获取到的 proto 对象的 y 属性的值。
五、super
super 可以用来调用原型链上的方法,如下例(例9):
let proto = {
foo () {
console.log("I'm proto foo.");
}
}
let parent = {
}
let obj = {
foo () {
super.foo();
console.log("I'm obj foo.");
}
}
Object.setPrototypeOf(parent, proto)
Object.setPrototypeOf(obj, parent);
obj.foo(); // I'm proto foo.
// I'm obj foo.
super 只能出现在方法的简洁表示法定义中,如下例(例10)这样是会报错的:
let proto = {
foo () {
console.log("I'm proto foo.");
}
}
let parent = {
}
let obj = {
foo: function () {
super.foo();
console.log("I'm obj foo.");
}
}
Object.setPrototypeOf(parent, proto)
Object.setPrototypeOf(obj, parent);
obj.foo();
对于要调用的方法是不是用简洁表示法定义的,则没有限制,如下例(例11):
let proto = {
foo: function () {
console.log("I'm proto foo.");
}
}
let parent = {
}
let obj = {
foo () {
super.foo();
console.log("I'm obj foo.");
}
}
Object.setPrototypeOf(parent, proto)
Object.setPrototypeOf(obj, parent);
obj.foo();
六、 Object.is()方法和Object.assign()方法
Object.is() 方法用来比较两个对象是否严格相等,它的行为与 === 极为相似,不同点有二:
1. +0 和 -0
对于 === 运算符,+0 和 -0 是相等的,而 Object.is()则认为这两个值不同。
+0 === -0; // true
Object.is(+0, -0); // false
2. NaN 和 NaN
对于 === 运算符,NaN 和 NaN 是不等的,Object.is() 则认为这是相同的。
NaN == NaN; // false
Object.is(NaN, NaN); // true
Object.assign() 方法用来将一个至多个对象的可枚举属性拷贝到目标对象中。
Object.assign()方法的第一个参数是目标对象,后续的参数为源对象(参数必须是对象)。如果对象中有相同名称的属性,则排列在后的对象的属性会覆盖排在前面的对象的同名属性。(这个方法,有点像 JQuery 中的 extend 方法)
例12:
let obj1 = {};
let obj2 = {
prop: "I'm property",
func () {
return "I'm function.";
}
}
Object.assign(obj1, obj2);
console.log(obj1);
console.log(obj1.func());
这一方法的限制是:它只复制自身的可枚举属性,继承来的属性不复制,不可枚举属性也不复制;另外它的复制是浅拷贝,即只处理一级属性的添加和替换,嵌套属性不处理。
如下例(例13)
let target = { a: { b: 'c', d: 'e' } };
let source = { a: { b: 'hello' } };
Object.assign(target, source); // { a: { b: 'hello' } }
注意此例的结果,target 的 a 属性被 source 的 a 属性完全替换,而不是 source 中 a 属性的 b 嵌套属性替换了 target 中 a 属性的 b 嵌套属性。如果你期望的结果是 { a: { b: 'hello', d: 'e' } } ,你可要失望了。
ES6 学习笔记之四 对象的扩展的更多相关文章
- ES6学习笔记(8)----对象的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 对象的扩展 1.属性名的简洁表示法 : ES6允许在代码中直接写变量,变量名是属性名,变量值是属 ...
- ES6学习笔记(三)——数值的扩展
看到这条条目录有没有感觉很枯燥,觉得自己的工作中还用不到它所以实在没有耐心看下去,我也是最近得闲,逼自己静下心来去学习去总结,只有在别人浮躁的时候你能静下心来去学去看去总结,你才能进步.毕竟作为前端不 ...
- es6学习笔记9--函数的扩展
函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,为了避免这个问题,通常需要先判断一下参数y是否被赋值,如果没有,再等于默认值. ES6允许为函数的参数设置默认值,即直接写在参 ...
- ES6学习笔记二:各种扩展
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7242967.html 一:字符串扩展 1:字符串遍历器 for (let char of str) { // ...
- ES6学习笔记(对象)
1.属性的简洁表示法 const foo = 'bar'; const baz = {foo}; baz // {foo: "bar"} // 等同于 const baz = {f ...
- ES6学习笔记(5)----数值的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 数值的扩展 1.Number对象的扩展(1)javascript的全局函数isNaN,isFin ...
- es6学习笔记-proxy对象
前提摘要 尤大大的vue3.0即将到来,虽然学不动了,但是还要学的啊,据说vue3.0是基于proxy来进行对值进行拦截并操作,所以es6的proxy也是要学习一下的. 一 什么是proxy Prox ...
- ES6学习笔记(一)——扩展运算符和解构赋值
前言 随着前端工程化的快速推进,在项目中使用ES6甚至更高的ES7等最近特性早已不是什么新鲜事.之前还觉得既然浏览器支持有限,那了解一下能看懂就好,然而仅仅了解还是不够的,现在放眼望去,那些成熟框架的 ...
- es6学习笔记--promise对象
Promise对象是为了简化异步编程.解决回调地狱情况 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可 ...
随机推荐
- nyoj86-找球号(一) 【set 二分查找 hash】
http://acm.nyist.net/JudgeOnline/problem.php?pid=86 找球号(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 ...
- iOS9 UIWindow rootViewController
在iOS9中App被其他应用唤起的时候Crash,正常启动或者调试模式都不会Crash. 通过XCode - Window -Device,查看设备的log,如下 Assertion failure ...
- sql不带锁查询
原文 sql server在执行查询语句时会锁表.在锁表期间禁止增删改操作. 如果不想锁表,那就再表名或别名后面加上WITH(NOLOCK) 如下所示: SELECT Id FROM dbo.T_Ta ...
- runloop - 面试题
2.
- Java 架构师
“学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 1.能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超 ...
- 什么是springMvc的参数绑定?
参数绑定通俗来讲就是从页面传过来的数据通过SpringMvc进行接收.接收的数据类型可以有: (1)SpringMvc默认支持的类型:request.session.application等. (2) ...
- js深拷贝、浅拷贝
浅拷贝: 只针对当前对象的属性进行拷贝,若当前对象的属性是引用类型时,这个不考虑,不进行拷贝.若属性是引用类型,拷贝后引用的是地址,如果进行更改,会影响拷贝的原对象属性. 深拷贝:针对当前对象的数据的 ...
- loadrunner12.5-vugen回放脚本提示:URL=“http://www.testclass.net/js/scripts.js”的常规连接当前无套接字 (16 不足) 可用,是什么意思呢?怎么理解呢?
会发生这个报错,是因为每个浏览器都有一个限制,检查哪个浏览器客户正在模拟, 通常只允许16个并发连接. 如果超过此超过接数,将显示该消息,通知您没有可用的连接. 而max connection的默认值 ...
- Mockplus是如何节省你的原型时间的?
还在用老牌原型工具一点点绘制产品原型吗?还在为实现一个满意的交互而绞尽脑汁吗?还在为无法和用户高效沟通而发愁吗?朋友,现在是快速原型的时代了.时间不等人,当你精雕细琢完成产品启动页的时候,别人的原型已 ...
- oracle常用函数速记
1.截断中文字符串 CREATE OR REPLACE function cn_cutstr(v_str varchar2,v_len number) return varchar2 IS v_i n ...