1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00
es6tutorial/docs/object.md
2014-05-04 00:20:46 +08:00

236 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 对象的扩展
## Object.is()
Object.is()用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0二是NaN等于自身。
```javascript
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
```
## __proto__属性
ES6正式将__proto__属性写入了标准用来指定对象的prototype对象。
```javascript
var obj = {
__proto__: someOtherObj,
method: function() { ... }
}
```
有了这个属性实际上已经不需要通过Object.create()来生成新对象了。
## 增强的对象写法
ES6允许直接写入变量和函数作为对象的属性和方法。这样的书写更加简洁。
```javascript
var Person = {
name: '张三',
//等同于birth: birth
birth,
// 等同于hello: function ()...
hello() { console.log('我的名字是', this.name); }
};
```
这种写法用于函数的返回值,将会非常方便。
```javascript
function getPoint() {
var x = 1;
var y = 10;
return {x, y};
}
getPoint()
// {x:1, y:10}
```
## 属性名表达式
ES6允许定义对象时用表达式作为对象的属性名。在写法上要把表达式放在方括号内。
```javascript
var lastWord = "last word";
var a = {
"first word": "hello",
[lastWord]: "world"
};
a["first word"] // "hello"
a[lastWord] // "world"
a["last word"] // "world"
```
上面代码中对象a的属性名lastWord是一个变量。
下面是一个将字符串的加法表达式作为属性名的例子。
```javascript
var suffix = " word";
var a = {
["first" + suffix]: "hello",
["last" + suffix]: "world"
};
a["first word"] // "hello"
a["last word"] // "world"
```
## symbols
ES6引入了一种新的原始数据类型symbol。它通过Symbol函数生成。
```javascript
var mySymbol = Symbol('Test');
mySymbol.name
// Test
typeof mySymbol
// "symbol"
```
上面代码表示Symbol函数接受一个字符串作为参数用来指定生成的symbol的名称可以通过name属性读取。typeof运算符的结果表明Symbol是一种单独的数据类型。
注意Symbol函数前不能使用new命令否则会报错。这是因为生成的symbol是一个原始类型的值不是对象。
symbol的最大特点就是每一个symbol都是不相等的保证产生一个独一无二的值。
```javascript
let red = Symbol();
let green = Symbol();
let blue = Symbol();
function handleColor(color) {
switch (color) {
case red:
...
case green:
...
case blue:
...
}
}
```
上面代码中red、green、blue三个变量都是Symbol类型它们的值是不相等的。
由于这种特点Symbol类型适合作为标识符用于对象的属性名保证了属性名之间不会发生冲突。如果一个对象由多个模块构成不会出现同名的属性。
```javascript
var a = {};
var mySymbol = Symbol();
a[mySymbol] = 'Hello!';
//另一种写法
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
```
上面代码通过点结构和Object.defineProperty两种方法为对象增加一个属性。
下面的写法为Map结构添加了一个成员但是该成员永远无法被引用。
```javascript
let a = Map();
a.set(Symbol(), 'Noise');
a.size // 1
```
如果要在对象内部使用symbol属性名必须采用属性名表达式。
```javascript
let specialMethod = Symbol();
let obj = {
[specialMethod]: function (arg) {
...
}
};
obj[specialMethod](123);
```
## Proxy
所谓Proxy可以理解成在目标对象之前架设一层“拦截”外界对该对象的访问都必须先通过这层拦截可以被过滤和改写。
ES6原生提供Proxy构造函数用来生成proxy实例对象。
```javascript
var proxy = new Proxy({}, {
get: function(target, property) {
return 35;
}
});
proxy.time // 35
proxy.name // 35
proxy.title // 35
```
上面代码就是Proxy构造函数使用实例它接受两个参数第一个所要代理的目标对象上例是一个空对象第二个是拦截函数它有一个get方法用来拦截对目标对象的访问请求。get方法的两个参数分别是目标对象和所要访问的属性。可以看到由于拦截函数总是返回35所以访问任何属性都得到35。
下面是另一个拦截函数的例子。
```javascript
var person = {
name: "张三"
};
var proxy = new Proxy(person, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
proxy.name // "张三"
proxy.age // 抛出一个错误
```
上面代码表示如果访问目标对象不存在的属性会抛出一个错误。如果没有这个拦截函数访问不存在的属性只会返回undefined。