es6学习之对象的扩展

一.对象属性和方法的简洁表示法

对象属性

const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}

对象方法

const o = {
  method() {
    return "Hello!";
  }
};

二.对象属性名和方法表达式

属性名和方法名表达式不能和简洁表示法同时使用,否则报错
属性名表达式

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

三.属性的可枚举性和遍历

Object.getOwnPropertyDescriptor(obj, ‘foo’);能获取对象的属性的描述,enumerable代表是否可被枚举

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

目前es6的5中对象的属性遍历方法

(1)for ... in
遍历自身属性和继承的可枚举属性,但是不包括Symbol属性
(2)Object.keys(obj)
遍历自身的属性,但是不包含不可枚举的和Symbol属性
(3)Object.getOwnPropertyNames(obj);
遍历自身的属性,包含不可枚举属性,但是不包含Symbol属性
(4)Object.getOwnPropertySymbols()
遍历自身的所有Symbol属性
(5)Reflect.ownKeys(obj)
遍历自身的所有属性,包含不可枚举的,包含Symbol属性

四.对象中方法的name属性

类似于函数的name属性

const person = {
  sayName() {
    console.log('hello!');
  },
};
person.sayName.name   // "sayName"

对象的方法上使用getter或者setter,则name属性不在这个方法上,而是在该方法的描述对象上

const obj = {
  get foo() {},
  set foo(x) {}
};
obj.foo.name
// TypeError: Cannot read property 'name' of undefined
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
descriptor.get.name // "get foo"
descriptor.set.name // "set foo"

对象方法是Symbol值,则方法的name返回Symbol的描述

const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
  [key1]() {},
  [key2]() {},
};
obj[key1].name // "[description]"
obj[key2].name // ""

五.对象的super关键字

指向当前对象的原型对象,只能用在对象的方法中

const proto = {
  foo: 'hello'
};

const obj = {
  foo: 'world',
  find() {
    console.log(this.foo);
    return super.foo;
  }
};
// es6提供的用于设置对象的原型的方法,下面的是将obj的原型对象设置为proto
Object.setPrototypeOf(obj, proto);
obj.find() 
// world
// "hello"

下面的是反例

// 报错,没在对象方法中使用
const obj = {
  foo: super.foo
}

// 报错,没在对象方法中使用
const obj = {
  foo: () => super.foo
}

// 报错,没在对象方法中使用
const obj = {
  foo: function () {
    return super.foo
  }
}

六.对象的扩展运算符

1.解构赋值

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
  • 等号右边不能是undefined和null,否则报错
  • 解构赋值必须是最后一个,否则报错
  • 解构赋值是浅拷贝
  • 解构赋值不能拷贝对象的原型属性
// 浅拷贝
let obj = { a: { b: 1 } };
let { ...x } = obj;
obj.a.b = 2;
x.a.b // 2

// 不拷贝原型对象属性
let o1 = { a: 1 };
let o2 = { b: 2 };
o2.__proto__ = o1;
let { ...o3 } = o2;
o3 // { b: 2 }
o3.a // undefined
// 另一个不拷贝原型对象属性的例子,变量x是单纯的解构赋值,所以可以读取对象o继承的
属性;变量y和z是扩展运算符的解构赋值,只能读取对象o自身的属性,所以变量z可以赋值
成功,变量y取不到值。
const o = Object.create({ x: 1, y: 2 });
o.z = 3;
let { x, ...{ y, z } } = o;
x // 1
y // undefined
z // 3

2.扩展运算符

let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }

完整的克隆一个对象,包含原型对象,可以使用如下方法,推荐第二种和第三种

// 写法一
const clone1 = {
  __proto__: Object.getPrototypeOf(obj),
  ...obj
};

// 写法二
const clone2 = Object.assign(
  Object.create(Object.getPrototypeOf(obj)),
  obj
);

// 写法三
const clone3 = Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
)

七.对象的方法

(1)Object.is(p1,p2);

行为类似 === 号
不同如下:

+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

(2)Object.assign(target,p1,p2),

将p1和p2等对象合并到target对象中,但是使用微信公众号项目注意,这里会不支持,被坑过
具体用法和用处请看文档: http://es6.ruanyifeng.com/#docs/object#Object-assign

(3)Object.getOwnPropertyDescriptors() ,

返回指定对象的所有自身属性的描述对象,不包括继承属性,

const obj = {
  foo: 123,
  get bar() { return 'abc' }
};

Object.getOwnPropertyDescriptors(obj)
// { foo:
//    { value: 123,
//      writable: true,
//      enumerable: true,
//      configurable: true },
//   bar:
//    { get: [Function: get bar],
//      set: undefined,
//      enumerable: true,
//      configurable: true } }

(4)Object.setPrototypeOf(),Object.getPrototypeOf()

Object.setPrototypeOf方法的作用与proto相同,用来设置一个对象的prototype对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
“__proto__”标准上只有浏览器才会部署,因此要采用上述2中方法设置原型对象

function Rectangle() {
  // ...
}

const rec = new Rectangle();

Object.getPrototypeOf(rec) === Rectangle.prototype
// true

Object.setPrototypeOf(rec, Object.prototype);
Object.getPrototypeOf(rec) === Rectangle.prototype
// false

(5)Object.keys(),Object.values(),Object.entries()

Object.keys() , 返回对象自身的可遍历属性的键数组,不包含继承属性,供for … of使用
Object.values() , 返回对象自身的可遍历属性的键数组,不包含继承属性,供for … of使用
Object.entries() , 返回对象自身的可遍历属性的键数组,不包含继承属性,供for … of使用

const obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值