对象的分类
- 普通对象(Ordinary Object):具备Javascript 对象所有的默认内部行为。
- 特异对象(Exotic Object): 具备某些与默认行为不符的内部行为。
- 标准对象(Standard Object):ES6中定义的对象,例如 Array、Date 等。既可以是普通对象,又可以是特异对象
- 内置对象(Build-in Object):JS脚本中的环境对象(window、document等)
对象字面量的扩充
属性初始值简写
// ES5
function createPerson(name, age) {
return {
name: name,
age: age,
sayName: function () {
console.log(this.name)
}
}
}
// ES6
function createPerson(name, age) {
return {
name,
age,
sayName() {
console.log(this.name)
}
}
}
可计算属性名
通过中括号 [ ] 标识属性的可计算性
let lastName = "last name"
let person_3 = {
"first name": 'Bicholas',
[lastName]: 'Mick'
}
var suffix = "name"
var person = {
["first " + suffix]: 'Test',
["last " + suffix]: 'Zakas'
}
新增方法
Object.is()
判断对象之间的全等性,解决 ES5 全等符号(===)出现的以下问题
- +0 === -0 【true】
- NaN === NaN 【false】
console.log("+0 === -0:", +0 === -0)
console.log("NaN === NaN:", NaN === NaN)
console.log("Object.is(+0, -0):", Object.is(+0, -0))
console.log("Object.is(NaN, NaN):", Object.is(NaN, NaN))
Object.assign
用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
function mixin(receiver, supplier) {
Object.keys(supplier).forEach(function (key) {
receiver[key] = supplier[key]
})
return receiver;
}
function EventTarget() { /* ... */ }
EventTarget.prototype = {
constructor: EventTarget,
emit: function () { /* ... */ },
on: function () { /* ... */ }
}
var myObject = {}
mixin(myObject, EventTarget.prototype)
// Object.assign(myObject, EventTarget.prototype)// ES6
myObject.emit('something')
注意: Object.assign 无法复制 访问器属性
let num = 0,
asad = 0
var testObj = {
get testName() {
return 'first123asdasd'
},
get name() {
return num++;
},
set testName(name) {
console.log(123, asad++)
if (asad < 5) {
this.testName = name
}
this.testName.split(name)
}
}
相关补充
1. 访问器引发的死循环
-
setter 中用 self.value = value
-
getter 中用 self.value
2. 在对象字面量中,不能为一个已有真实值的变量使用 set ,也不能为一个属性设置多个 set。
( { set x(v) { }, set x(v) { } } 和 { x: ..., set x(v) { } } 是不允许的 )
重复字面量属性
- ES5 及以下版本会报语法错误
- ES6 取同名属性的最后一个值
// ES5
let test = {
name: 'abc',
name: 'qwe' // 报错
}
// ES6
let test2 = {
name: 'abc',
name: 'woo'
}
console.log(test2.name) // woo
属性枚举顺序
-
所有数字键安装升序
-
所有字符串键按照他们加入对象顺序
-
Symbol 键按照他们加入对象的顺序
-
数字 > 字符串 > Symbol
var obj = {
a: 1,
0: 1,
[Symbol('test_3')]: 1,
c: 1,
2: 1,
[Symbol('test_2')]: 1,
b: 1,
1: 1,
[Symbol('test_1')]: 1,
}
console.log(Object.getOwnPropertyNames(obj))
console.log(Reflect.ownKeys(obj))
增强对象的原型
改变对象原型
新增 Object.setPrototypeOf 可以改变对象的原型(即[[Prototype]])
let person = {
getGreeting() {
return "Hello";
}
}
let dog = {
getGreeting() {
return "Woof"
}
}
let firend = Object.create(person)
console.log(firend.getGreeting())
console.log(Object.getPrototypeOf(firend) === person)
Object.setPrototypeOf(firend, dog)
console.log(firend.getGreeting())
console.log(Object.getPrototypeOf(firend) === dog)
简化对象原型的访问——Super 引用
let person = {
getGreeting() {
return "Hello";
}
}
let dog = {
getGreeting() {
return "Woof"
}
}
let firend = {
getGreeting() {
// 等价于 return Object.getPrototypeOf(this).getGreeting.call(this) + ",Hi"
return super.getGreeting() + ",Hi"
}
}
Object.setPrototypeOf(firend, person)
console.log(firend.getGreeting())
console.log(Object.getPrototypeOf(firend) === person)
// 对于 relative 会陷入死循环
let person = {
getGreetion() {
return "Hello"
}
}
// 以person 对象为原型
let firend = {
getGreetion() {
return Object.getPrototypeOf(this).getGreetion.call(this) + ", Hi"
}
}
Object.setPrototypeOf(firend, person)
let relative = Object.create(firend)
console.log(person.getGreetion())
console.log(firend.getGreetion())
console.log(relative.getGreetion())
方法的正式定义
ES6之前并未正式定义【方法】概念
let friend = {
// 方法
getGreeting() {
return super.getGreeting() + ", Hi"
}
}
// 函数
function add(a, b) {
return a + b
}