Symbol.hasInstance
// Symbol.hasInstance
class MyClass {[Symbol.hasInstance] (foo) {return foo instanceof Array;}
}
[1, 2, 3] instanceof new MyClass() // true// symbol.hasInstance:會在[1, 2, 3] instanceof 時 自動調用 [Symbol.hasInstance] (foo) 方法...
// 等價于. ([1,2,3]) => { return [1,2,3] instanceof Array}
Symbol.isConcatSpreadable
class A1 extends Array {construcor(args) {super(args);this[Symbol.isConcatSpreadable] = true;}
}
class A2 extends Array {constructor(args) {super(args);this[Symbol.isConcatSpreadable] = false;}
}
let a1 = new A1();
a1[0] = 3;
a1[1] = 4;
let a2 = new A2();
a2[0] = 5;
a2[1] = 6;
[1, 2].concat(a1).concat(a2)
// [1, 2, 3, 4, [5, 6]]
// Symbol.isConcatSpreadable:表示對象使用Array.prototype.concat()時,是否可以展開
Symbol.species
// Symbol.species
// 使用格式
class MyArray extends Array {// 覆蓋父類 Array 的構造函數static get [Symbol.species] () { return 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);mapped instanceof MyArray // false
mapped instanceof Array // true// 注:在static get[Symbol.species] () 中 將構造函數改為了 返回Array類,, 故使用instance MyArray 返回 false.
Symbol.match
// Symbol.match
class MyMatcher {[Symbol.match] (string) {return 'hello world'.indexOf(string);}
}
'e'.match(new MyMatcher)) // 1
// 注:等同于 [Symbol.match] ('e') { return 'hello world'.indexOf('e')}
Symbol.replace
// Symbol.replace
const x= {};
x[Symbol.replace] = (...s) => console.log(s);
'Hello'.replace(x, 'World')
// 注:在執行'Hello'.replace操作時,實際上執行:(['Hello','World']) => console.log ('["Hello","World"]');
// Symbol.replace會在執行String.prototype.replace方法時調用函數.
Symbol.search
// Symbol.search
class MySearch {constructor (value) {this.value = value;}[Symbol.search] (string) {return string.indexOf(this.value);}
}
'foobar'.search(new MySearch('foo')) // 0
// 注: [Symbol.search] (string),在執行String.prototype.search方法時調用.
// 本例相當于執行: ('foobar') { return 'foobar'.indexOf('foo')}
}
Symbol.split
// Symbol.split
class MySplitter {constructor (value) {this.value = value;}[Symbol.split] (string) {var index = string.indexOf(this.value);if (index = -1){return string;}return [string.substr(0, index),string.substr(index + this.value.length)];}
}
'foobar'.split(new MySplitter('foo')) // ['', 'bar']
'foobar'.split(new MySplitter('bar')) // ['foo', '']
'foobar'.split(new MySplitter('baz')) // ['foobar']
// 注: [Symbol.split]](string) 在執行String.prototypr.string方法時觸發
// 本例改寫了split方法,將string分為2部分,一部分(未匹配的)不變,另一部分(匹配到的)置為空, 若string中無匹配值,則完整返回...
Symbol.iterator
// Symbol.iterator
class Collection {*[Symbol.iterator] () {let i = 0;while (this[i] !== undefined) {yield this[i];++i;}}
}
let myCollection = new Collection();
myCollection[0] = 1;
myCollection[1] = 2;
for (let value of myCollection) {console.log (value);
}
// 1
// 2
// 注:在執行for ... of 循環時 觸發Symbol.iterator方法
// yield 在for循環時會保存當前的元素...
Symbol.toPrimitive
// Symbol.toPrimitive
let obj = {[Symbol.toPrimitive] (hint) {swtich (hint) {case 'number':return 123;case 'string':return 'str';case 'default':return ‘default';default:throw new Error ();}}
}
2 * obj ; // 246
3 + obj ; // '3default'
obj == 'default' // true
String(obj) // 'str'
// 注:在對象被轉為原始類型的值時,會調用這個方法
Symbol.toStringTag
// Symbol.toStringTag
class Collection {get [Symbol.toStringTag] () {return 'xxx',}
}
var x = new Collection();
Object.prototype.toString.call(x); // "[object xxx]"
// 注:當執行Object.prototype.toString方法時,觸發Symbol.toStringTag
Symbol.unscopables
// Symbol.unscopables
// 無unscopables
class MyClass {foo() { return 1;}
}
var foo = function () { return 2;};
with (MyClass.prototype) {foo(); // 1
}
// 有unscopables
class MyClass {foo() { return 1; }get [Symbol.unscopables] () {return { foo: true};}
}
var foo = function () { return 2;};
with (MyClass.prototype) {foo(); // 2
}
// 注:unscopables屬性指定了使用with關鍵字時哪些屬性會被with環境排除.
// 在本例中指定了foo屬性被排除....
參考《ES6標準入門》 P194~P203