Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

对象的扩展(es6) #12

Open
YoursJoker opened this issue Aug 8, 2020 · 0 comments
Open

对象的扩展(es6) #12

YoursJoker opened this issue Aug 8, 2020 · 0 comments

Comments

@YoursJoker
Copy link
Owner

ES6总结系列之 对象的扩展 篇


1. 属性、方法简洁表示法

属性简写

const foo = 'bar';

const baz = {foo}; //属性名就是变量名, 属性值就是变量值
baz // {foo: "bar"}

// 等同于
const baz = {foo: foo};

方法简写

const obj = {
  method () {
    return 'Hello!'
  }
}

//等同于
const obj = {
  method: function () {
    return 'Hello!'
  }
}

简写的对象方法不能用作构造函数,会报错。

const obj = {
  f() {
    this.foo = 'bar';
  }
};

new obj.f() // 报错

2. 属性名表达式

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

// 方法一
obj.foo = true;
//直接用标识符作为属性名

// 方法二
obj['a' + 'bc'] = 123;
//用表达式作为属性名,须将表达式放在方括号之内

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

let lastWord = 'last word';

const a = {
  'first word': 'hello',
  [lastWord]: 'world'
};

a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"

②表达式还可以用于定义方法名

let obj = {
  ['h' + 'ello']() {
    return 'hi';
  }
};

obj.hello() // hi

③属性名表达式与简洁表示法,不能同时使用

// 报错
const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };

// 正确
const foo = 'bar';
const baz = { [foo]: 'abc'};

④属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object],这一点要特别小心。

const keyA = {a: 1};
const keyB = {b: 2};

const myObject = {
  [keyA]: 'valueA',
  [keyB]: 'valueB'
};

myObject // Object {[object Object]: "valueB"}

3.属性的可枚举和遍历

可枚举性

①每个对象都有一个描述对象(Descriptor),来控制属性的行为
②用Object.getOwnPropertyDescriptor ()来获取

let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
	//    value: 123,
	//    writable: true,
	//    enumerable: true,
	//    configurable: true
//  }

③enumerable为false时,为不可枚举,四种操作会忽略enumerable为false的属性
1)for...in 循环 返回自身和继承的可枚举属性
2)Object.keys(obj) 返回可枚举的key数组
3)JSON.stringify() 串化可枚举的属性
4)Object.assign() 拷贝自身可枚举的属性
5)其中只有 for...in 会遍历继承的属性,其他只遍历自身属性

属性的遍历

④五种属性的遍历
1)for...in
2)Object.keys(obj) 返回数组
3)Object.getOwnPropertyNames(obj) 返回数组
4)Object.getOwnPropertySymbols(obj) 返回数组
5)Reflect.ownKeys(obj) 返回数组
6)(1)(2)(3)不含Symbol属性,(4)(5)含Symbol属性,(3)(5)包含不可枚举属性
⑤遍历顺序
数值键 --> 字符串键 --> Symbol键
(数值升序) - (时间升序) - (时间升序)

4.super关键字

1)指向对象原型
2)只能用在对象的方法中
3)只能用在对象简写法可以让JavaScript引擎确认,定义的是对象的方法

const proto = {
  foo: 'hello'
};

const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};

Object.setPrototypeOf(obj, proto);
obj.find() // "hello"

5.对象的扩展运算符

1)解构赋值要求求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象
2)扩展运算符的解构赋值不能复制继承制原型对象上的属性
3)let { x, ...{ y, z } } = o; 错误
4)解构赋值的拷贝是浅拷贝
5)如果有取值函数get,这个函数是会执行的

6.链判断运算符 ES2020引入?.

1)const firstName = message?.body?.user?.firstName || 'default';
2)等号右边的对象如果是null或undefined,就返回undefined,不在往下计算
3)三种用法:
a.obj?.prop //对象属性
b.obj?.[prop] //对象属性
c.func?.(...args)//函数或对象方法的调用
4)右侧不能是十进制数,不然?.不在被看成一个完整的运算符,小数点.会和后面的数字结合成小数,将变成一个三目运算符

7.Null判断运算符(??)

1)ES2020 引入了一个新的 Null 判断运算符??。它的行为类似||,但是只有运算符左侧的值为null或undefined时,才会返回右侧的值。 (0和false不生效)

const headerText = response.settings.headerText ?? 'Hello, world!';

  • 个人Github,欢迎star^_^
  • ES6总结系列参考自阮一峰《ECMAScript6入门》
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant