文档章节

ES6 学习笔记之四 对象的扩展

o
 osc_pn11u1x9
发布于 2018/08/08 16:10
字数 1277
阅读 7
收藏 0

精选30+云产品,助力企业轻松上云!>>>

ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便。

一、属性的简洁表示法

当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名。

例1:

var x = 2, y = 3,
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):

 1 let firstName = 'first';
 2 let secondFrontName = 'se';
 3 let secondBehandName = 'cond';
 4 let funcName = function () {
 5     return 'func';
 6 }
 7 let methodName1 = 'sayHello';
 8 let methodName2 = 'sayBye';
 9 let obj = {
10     [firstName]: 'hello',
11     [secondFrontName + secondBehandName]: 'world',
12     [funcName()]: 'bye',
13     [methodName1]() {
14     console.log('Hello, world!');
15     },
16     [methodName2]: function () {
17     console.log('Goodbye!');
18   }
19 }
20 console.log(obj[firstName]);
21 console.log(obj[secondFrontName + secondBehandName]);
22 console.log(obj[funcName()]);
23 obj.sayHello();
24 obj.sayBye();

注意,在第13行时,同时使用了属性名表达式和方法的简洁表示法,这是没问题的。

但是不能同时使用属性名表达式和属性的简洁表示法,会报错(例7):

let foo = 'bar';
let bar = 'abc';
let baz = { [foo] };

四、操作[Prototype]

作为原型继承语言,在JavaScript中,prototype属性是非常重要的。在前ES6中,浏览器提供了扩展的属性__proto__,来获取和设置它。

ES6 将这个属性放在了标准的附录部分,并且说明仅要求浏览器实现这个属性,也就是说只有在浏览器中的脚本使用这个属性才是安全可信赖的。

为保持对特定环境的非依赖,不应该在代码中使用这个属性。而应该使用 Object.setPrototypeOf(...) 和 Object.getPrototypeOf(...) 方法设置和获取,这两个方法是全环境安全的。

例8:

1 let proto = {};
2 proto.y = 20;
3 let obj = {x : 10};
4 console.log(Object.getPrototypeOf(obj));
5 console.log(obj.y);
6 Object.setPrototypeOf(obj, proto);
7 console.log(Object.getPrototypeOf(obj));
8 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' } } ,你可要失望了。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
ES学习充电笔记

整理一下最近前端的充电笔记,惭愧以前一直没有去很好的理解原型和闭包 JS高级基础 函数的理解和使用 函数也是对象 instanceof Object===true 函数有属性: prototype 函数有方法: call()/appl...

lemonLove
2019/01/10
36
0
ES6学习笔记(二)

本篇内容: 1.函数的扩展; 2.数组的扩展; 1.函数的扩展 (1)函数参数的默认值 ES6之前的版本无法为函数的参数指定默认值 ES6之后可以给函数参数指定默认值,用法如下: function log(x, ...

osc_tugm8wcv
2019/05/28
1
0
ES6中的元编程-Proxy & Reflect

##前言 ES6已经出来好久了,但是工作中比较常用的只有let const声明,通过箭头函数改this指向,使用promise + async 解决异步编程,还有些数据类型方法...所以单独写一篇文章学习ES6中的pro...

osc_dos38x1o
2018/09/21
2
0
React学习笔记之react基础篇(1)

一.React特点归纳   1.声明式的视图层:React 模板写在 JS 文件中,而不是 html 的 标签中。能使用所有 JS 语法,而不只有模板语法,所以更加灵活。   2.简单的更新流程:当状态数据发生...

前端老手
2019/10/12
25
0
es6学习笔记初步总结

es6学习笔记初步总结 1. let、const 和 block 作用域 在ES6以前,var关键字声明变量。无论声明在何处,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部)。这就是函数变量提升...

osc_r3t4hb0k
2018/05/16
2
0

没有更多内容

加载失败,请刷新页面

加载更多

聚焦餐饮行业,研究院昨发布数据显示

谈话,聚焦餐饮行业,研究院昨发布数据显示,今年上半年,全国餐饮行业招聘需求增长46.18%,平均月薪6387元.随着餐饮行业的快速发展,"如何留人"也成为餐饮企业的思考题. 记者了解到,中国饭店协会...

点击fojewio
58分钟前
20
0
3·15晚会曝光上海氪信、招财旺旺SDK包泄露隐私 后台上传交易验证码敏感信息

来源 | 央视 7月16日,央视3·15晚会曝光国美易卡、美的空调遥控器、姨妈日历、银码头等50多款软件中内嵌的SDK包读取、上传用户隐私问题。上海氪信信息技术有限公司、北京招财旺旺信息技术有...

镭射财经
今天
14
0
名称=''的无效表单控件不可聚焦 - An invalid form control with name='' is not focusable

问题: I have an acute problem on my website. 我的网站上有一个严重的问题。 In Google Chrome some customers are not able to proceed to my payment page. 在Google Chrome浏览器中,某......

技术盛宴
今天
14
0
Hacker News 简讯 2020-07-17

更新时间: 2020-07-17 01:01 Let’s avoid talk of ‘chemical imbalance’: it’s people in distress - (psyche.co) 让我们避免谈论“化学失衡”:这是处于困境中的人们 得分:260 | 评论:...

FalconChen
今天
92
0
【LeetCode】 59 在排序数组中查找元素的第一个和最后一个位置

题目: 解题思路: 二分法 https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/zai-pai-xu-shu-zu-zhong-cha-zhao-yuan-su-de-di-yi-/ 代......

JaneRoad
昨天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部