ECMAScript 6 符号对象(Symbol)-Symbol对象属性

 2015年11月10日    1836     声明


符号对象(Symbol)是ECMAScript 6 中新增的数据类型,通过Symbol可以创建一个唯一的值,由于这种特性使Symbol很适合做为标识符。本文将介绍Symbol中的属性,这些属性展示了除做为符号外,JavaScript还内建的一些在 ECMAScript 5 之前没有暴露给开发者的符号,它们代表语言的内部行为。

  1. Symbol.iterator属性
  2. Symbol.match属性
  3. Symbol.search属性
  4. Symbol.replace属性
  5. Symbol.split属性
  6. Symbol.hasInstance属性
  7. Symbol.isConcatSpreadable属性
  8. Symbol.unscopables属性
  9. Symbol.species属性
  10. Symbol.toPrimitive属性
  11. Symbol.toStringTag属性


1. Symbol.iterator属性

Symbol.iterator属性指向默认的默认使用的迭代器。即:对象for...of循环使用的迭代器。

var myIterable = {}
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};

for(let value of myIterable) {
    console.log(value);
}
// 1
// 2
// 3


2. Symbol.match属性

Symbol.match属性指向返回匹配字符串的方法。String.prototype.match()就是调用此方法。

regexp[Symbol.match](this)
// 等价于
String.prototype.match(regexp)


Symbol.search属性指向查找子字符串在字符串中位置的方法。String.prototype.search()就是调用此方法。

String.prototype.search(regexp)
// 等价于
regexp[Symbol.search](this)


4. Symbol.replace属性

Symbol.replace属性指向替换字符串中子字符串的方法。String.prototype.replace()就是调用此方法。

String.prototype.replace(searchValue, replaceValue)
// 等价于
searchValue[Symbol.replace](this, replaceValue)


5. Symbol.split属性

Symbol.split属性指向字符串分隔的方法。String.prototype.split()就是调用此方法。

String.prototype.split(separator, limit)
// 等价于
separator[Symbol.split](this, limit)


6. Symbol.hasInstance属性

Symbol.hasInstance属性判断该对象是否为某个构造函数的实例,instanceof就是调用此方法。

class MyClass {
  [Symbol.hasInstance](foo) {
    return foo instanceof Array;
  }
}
var o = new MyClass();
o instanceof Array // false


7. Symbol.isConcatSpreadable属性

Symbol.isConcatSpreadable属返回一个布尔值,该值表示对象调用String.prototype.split()方法进是否是可展开。

let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']

let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']


8. Symbol.unscopables属性

Symbol.unscopables属返回一个对象,该对象表示是否会被with环境排除的属性。

Array.prototype[Symbol.unscopables];

输出如下:

{ copyWithin: true,
  entries: true,
  fill: true,
  find: true,
  findIndex: true,
  keys: true }


9. Symbol.species属性

Symbol.species属性指向用来创建派生类对象的构造函数,即:this.constructor[Symbol.species]属性存在就会使用这个属性创建对象实例。

// 扩展 Array 的构造函数
class MyArray extends Array {
  static get [Symbol.species]() { return Array; }
}
var a = new MyArray(1,2,3);
var mapped = a.map(x => x * x);

console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array);   // true


10. Symbol.toPrimitive属性

Symbol.species属性指向将对象转换为原始值时所使用的方法。

// 对象不使用 Symbol.toPrimitive 属性
var obj1 = {};
console.log(+obj1);     // NaN
console.log(`${obj1}`); // "[object Object]"
console.log(obj1 + ""); // "[object Object]"

// 对象使用 Symbol.toPrimitive 属性
var obj2 = {
  [Symbol.toPrimitive](hint) {
    if (hint == "number") {
      return 10;
    }
    if (hint == "string") {
      return "hello";
    }
    return true;
  }
};
console.log(+obj2);     // 10      -- hint is "number"
console.log(`${obj2}`); // "hello" -- hint is "string"
console.log(obj2 + ""); // "true"  -- hint is "default"


11. Symbol.toStringTag属性

Symbol.toStringTag属性指向返回对象的描述的字符串值时所使用的方法,即:Object.prototype.toString()所使用的方法。
({[Symbol.toStringTag]: 'Foo'}.toString())
// "[object Foo]"

class Collection {
  get [Symbol.toStringTag]() {
    return 'xxx';
  }
}
var x = new Collection();
Object.prototype.toString.call(x) // "[object xxx]"