1.属性的简洁表示法

ES6 允许直接写入变量和函数,作为对象的属性和方法。这样书写更加简洁。

  1. const foo = 'bar';
  2. const baz = {foo};
  3. baz //{foo: "bar"}
  4.  
  5. //等同于
  6. const baz = { foo: foo};
  7. baz //{foo: "bar"}

上面代码表明,ES6 允许在对象之中,直接写变量。这时,属性名为变量名,属性值为变量的值。下面是另一个例子。

  1. function f(x, y){
  2. return {x, y};
  3. }
  4.  
  5. //等同于
  6. function f(x, y){
  7. return {x:x, y:y};
  8. }
  9. f(1, 2); //{x: 1, y: 2}

除了属性简写,方法也可以简写。

  1. const o = {
  2. method (){
  3. return "hello!";
  4. }
  5. };
  6.  
  7. //等同于
  8. const o = {
  9. method : function() {
  10. return "hello!";
  11. }
  12. };

下面还有一个例子。

  1. let brith = '2000/01/01';
  2. const Person = {
  3. name = 'lisi',
  4. //等同于 birth: birth
  5. birth,
  6. hell() {
  7. //等同于 hello: function ()...
  8. console.log('My name is', this.name);
  9. }
  10. };

这种写法用于函数的返回值,将会非常方便。

  1. function getPoint() {
  2. const x = 1;
  3. const y = 2;
  4. return {x, y};
  5. }
  6. getPoint() //{x: 1, y: 2}

2.属性名表达式

Javascript 定义对象的属性,有两种方法。

  1. //方法一:直接用标识符作为属性名
  2. obj.name = 'lisi';
  3.  
  4. //方法二:用表达式作为属性名,将表达式放在方括号内
  5. obj['a' + 'bc'] = 123;

但是,如果使用字面量方式定义对象(使用大括号),在ES5 中只能使用方法一定义属性。ES6 允许字面量定义对象时,用方法二作为对象的属性名,即把表达式放在方括号内。

  1. let propKey = 'foo';
  2. let obj = {
  3. [propKey]:true,
  4. ['a' + 'bc']: 123
  5. };

表达式还可以用于定义方法名。注意,属性名表达式与简洁表示法不能同时使用,会报错。

  1. //报错
  2. const foo = 'bar';
  3. const bar = 'abc';
  4. const baz = {[foo]};
  5.  
  6. //正确
  7. const foo = 'bar';
  8. const baz = {[foo]: 'abc'}

注意,如果属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串 [object, object]。

  1. const keyA = {a: 1};
  2. const keyB = {b: 2};
  3.  
  4. const myObject = {
  5. [keyA]: 'valueA',
  6. [keyB]: 'valueB'
  7. };
  8. myObject //{[object Object]: "valueB"}

上面代码中,[keyA] 和 [keyB] 得到的都是 [object, object],所以 [keyB] 会把 [keyA] 覆盖掉,而 myObject 最后只有一个 [object, object] 属性。

3. 方法的 name 属性

函数的name属性,返回函数名。对象方法也是函数,因此也有 name 属性。

  1. const person = {
  2. sayName() {
  3. console.log('hello!');
  4. },
  5. };
  6. person.sayName.name //"sayName"

上面代码中,方法的 name 属性返回函数名 (即方法名)

如果对象的方法使用了取值函数 (getter)和存值函数 (setter),则 name 属性不是在该方法上面,而是该方法的属性的描述对象的 get 和 set 属性上面,返回值是方法名前加上get 和 set。

  1. const person = {
  2. sayName() {
  3. console.log('hello!');
  4. },
  5. };
  6. person.sayName.name //"sayName"
  7.  
  8. const obj = {
  9. get foo() {},
  10. set foo(x) {}
  11. };
  12.  
  13. //obj.foo.name TypeError: Cannot read property 'name' of undefined
  14.  
  15. const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
  16. descriptor.get.name //"get foo"
  17. descriptor.set.name //"set foo"

有两种特殊情况:bind 方法创造的函数, name 属性返回 bound 加上原函数的名字;Function 构造函数创造的函数,name 属性返回 anonymous。

  1. (new Function ()).name //"anonymous"
  2.  
  3. var doSomething = function (){};
  4. doSomething.bind().name //"bound doSomething"

如果对象的方法是一个 Symbol 值, 那么 name属性返回的是这个 Symbol 值的描述。

  1. const key1 = Symbol('description');
  2. const key2 = Symbol();
  3. let obj = {
  4. [key1]() {},
  5. [key2]() {},
  6. };
  7. obj[key1].name //"[description]"
  8. obj[key2].name //""

上面代码中,key1 对应的Symbol 值有描述,key2 没有。

4.属性的可枚举和遍历

可枚举性

对象的每个属性都有一个描述对象(Descriptior),用来控制该属性的行为。Object.getOwnPropertyDescriptor 方法可以获取该属性的对象。

  1. let obj = { foo:123 };
  2. Object.getOwnPropertyDescriptor(obj, 'foo')
  3. /* {
  4. value: 123,
  5. writable: true,
  6. enumerable: true,
  7. configurable: true
  8. } */

描述对象的 enumerable 属性,称为“可枚举性”,如果该属性为 false,表示某些操作会忽略当前属性。

目前,有四个操作会忽略 enumerable 为 false 的属性。

  • for ... in循环:只遍历对象自身的和继承的可枚举的属性
  • Object.keys():返回对象自身的所有可枚举的属性的键名
  • Json.stringify():只串行化对象自身的可枚举的属性
  • Object.assign():忽略 enumerable 为 false 的属性,只拷贝对象自身的可枚举的属性

另外,ES6 规定,所有 Class 的原型的方法都是不可枚举的。

总的来说,操作中引入继承的属性会让问题复杂化,大多时候。我们只关心对象自身的属性。所以尽量不要用 for...in 循环,而用Object.keys() 代替。

属性的遍历

ES6 中一共有 5 种方法可以遍历对象的属性。

  1. for in:循环遍历对象自身的和可继承的可枚举属性(不包括 Symbol 属性)
  2. Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不包括 Symbol 属性)的键名
  3. Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不包括 Symbol 属性,但是包括不可枚举属性)的键名
  4. Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有 Symbol 属性的键名
  5. Reflect.ownKeys(obj):返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举

以上的5种方法遍历对象的键名,都同样遵循属性遍历的次序规则。

  1. 首先遍历所有数值键,按照数值升序排列。
  2. 其次遍历所有字符串键,按照加入时间升序排列
  3. 最后遍历所有的 Symbol 键,按照加入时间升序排列
  1. Reflect.ownKeys({ [Symbol()]:0, b:0,10:0, 2:0,a:0})
  2. // ["2", "10", "b", "a", Symbol()]

上面代码中,Reflect.ownKeys 方法返回一个数组,包含了参数对象的所有属性。

5. super 关键字

我们知道,this 关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字 super,指向当前对象的原型对象。

  1. const proto = {
  2. foo: 'hello'
  3. };
  4. const obj = {
  5. foo: 'world',
  6. find() {
  7. return super.foo;
  8. }
  9. };
  10. Object.setPrototypeOf(obj, proto);
  11. obj.find(); //"hello"

上面代码中,对象 obj.find() 方法中,通过 super.foo 引用了原型对象 proto 的 foo 属性。

注意,super 关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错

  1. //报错
  2. const obj = {
  3. foo: super.foo
  4. }
  5.  
  6. const obj = {
  7. foo: () => super.foo
  8. }
  9.  
  10. const obi = {
  11. foo: function (){
  12. return super.foo
  13. }
  14. }

上面三种 super 的用法都会报错,因为对于 Javascript 引擎来说,这里的 super 都没有用在对象的方法之中。第一种写法是 super 用在属性里面,第二种和第三种写法是 super 用在一个函数里面,然后赋值给 foo 属性。目前,只有对象方法的简写法可以让javascript引擎确认,定义的是对象的方法。

6. 对象的拓展运算符

解构赋值

拓展运算符

ES6 学习笔记之对象的拓展的更多相关文章

  1. es6学习笔记-proxy对象

    前提摘要 尤大大的vue3.0即将到来,虽然学不动了,但是还要学的啊,据说vue3.0是基于proxy来进行对值进行拦截并操作,所以es6的proxy也是要学习一下的. 一 什么是proxy Prox ...

  2. es6学习笔记--promise对象

    Promise对象是为了简化异步编程.解决回调地狱情况 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可 ...

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

    ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便. 一.属性的简洁表示法 当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名. 例1: , ...

  4. ES6学习笔记(对象)

    1.属性的简洁表示法 const foo = 'bar'; const baz = {foo}; baz // {foo: "bar"} // 等同于 const baz = {f ...

  5. ES6学习笔记(8)----对象的扩展

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 对象的扩展 1.属性名的简洁表示法 : ES6允许在代码中直接写变量,变量名是属性名,变量值是属 ...

  6. ES6学习笔记(对象新增方法)

    1.Object.is() ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===).它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0. ...

  7. ES6 学习笔记之对象的新增方法

    1. Object.is() ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===).它们都有缺点,前者会自动转换数据类型,后者的 NaN 不等于自身,以及 +0 等 ...

  8. es6学习笔记-class之一概念

    前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...

  9. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

随机推荐

  1. window 共享打印机

    https://www.zhihu.com/question/20653708 https://h30471.www3.hp.com/t5/da-yin-ji-yu-sao-miao-yi-de-an ...

  2. LVM 相关知识

    LVM 相关知识 一.示例图 二.概念 名词 全称 释义 PV Physical Volume 物理硬盘.硬盘分区或者RAID磁盘阵列,先要创建pv VG Volume Group 卷组建立在物理卷之 ...

  3. 005.Python条件if语句

    一  流程控制 流程控制的定义 流程:代码执行的过程 流程控制:对代码执行过程的管控 流程控制三大结构: 顺序结构:从上到下,代码依次执行 分支结构: 一共4个 循环结构:while for 分支结构 ...

  4. linux初级之总结复习

    一.linux命令复习 1.ls:列出当前目录下的文件 -h: -l: -d: -a: 2. man: 命令帮助手册 3. cd: 切换目录 -:  ~: ..: cd: 4. pwd: 显示当前工作 ...

  5. JQuery.Gantt开发指南(转)

    说明 日前需要用到甘特图,以下转载内容源自网络. • 概述 1.JQuery.Gantt是一个开源的基于JQuery库的用于实现甘特图效果的可扩展功能的JS组件库. •前端页面 o 资源引用 首先我们 ...

  6. Redis SWAPDB 命令背后做了什么

    Redis SWAPDB 命令背后做了什么 目录 Redis SWAPDB 命令背后做了什么 0x00 摘要 0x01 SWAPDB 基础 1.1 命令说明 1.2 演示 0x02 预先校验 0x03 ...

  7. Linux下RAID磁盘阵列的原理与搭建

    RAID概念 磁盘阵列(Redundant Arrays of Independent Disks,RAID),有"独立磁盘构成的具有冗余能力的阵列"之意. 磁盘阵列是由很多价格较 ...

  8. Pandas之:Pandas高级教程以铁达尼号真实数据为例

    Pandas之:Pandas高级教程以铁达尼号真实数据为例 目录 简介 读写文件 DF的选择 选择列数据 选择行数据 同时选择行和列 使用plots作图 使用现有的列创建新的列 进行统计 DF重组 简 ...

  9. MMF的初步介绍:一个规范化的视觉-语言多模态任务框架

    在VQA, Image Caption等任务中,构建模型是一件工作量较大的工作.有没有什么能减少这些重复的工作量呢?与此同时,Pytorch,tensorflow等开源的深度学习工具包发布,大大减少了 ...

  10. uwsgi启动Django应用

    uwsgi启动Django应用   uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议. WSGI / uwsgi / uWSGI 三者区别: WSGI是一种通信协议,Fl ...