MDN给出了以下 Symbol.species
的工作示例:
class MyArray extends Array { // Overwrite species to the parent Array constructor 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
ECMAScript 2015 specifications说:
A function valued property that is the constructor function that is used to create derived objects.
据我了解,它主要用于以某种方式自定义对象的 Duck-Type,以欺骗 instanceof
运算符。
它看起来很有用,但我还没有设法在普通对象上使用它 (FF 44.0a2):
let obj = {
get [Symbol.species]() {
return Array
}
}
console.log(obj instanceof Array) //false =(
console.log(obj instanceof Object) //true
有没有办法在普通对象上使用 Symbol.species
来欺骗 instanceof
运算符?
最佳答案
The way I understand it it would be mainly used to Duck-Type in some way custom objects in order to trick the
instanceof
operator.
不,这就是 Symbol.hasInstance
的用处(尽管它会生成棘手的构造函数,例如 mixins,而不是棘手的实例)。
Symbol.species
的要点是让内置方法确定派生对象 的正确类型。每当函数应该返回同类的新实例时,它通常会实例化一个 new this.constructor
,它可能是定义该方法的类的子类。但是在子类化时您可能并不总是想要这个,这就是 Symbol.species
的用武之地。
MDN给的例子很好,大家一定不要错过a
和mapped
的区别:
var a = new MyArray(1,2,3);
var mapped = a.map(x => x * x);
Object.getPrototypeOf(a) == MyArray.prototype; // true
Object.getPrototypeOf(mapped) == Array.prototype; // true
(如您所知,instanceof
is 只是 isPrototypeOf
的逆向糖)
所以这里发生的是 Array map
method在 MyArray
实例上调用,并且 creates a derived object那现在是 Array
的一个实例 - 因为 a.constructor[Symbol.species]
是这么说的。没有它,map
会创建另一个 MyArray
。
这个技巧同样适用于普通对象:
var b = {
length: 0,
map: Array.prototype.map,
constructor: { // yes, usually a function
[Symbol.species]: MyArray
}
};
var mapped = b.map(x => x*x);
console.log(mapped instanceof MyArray); // true
虽然我不能说它在这个例子中是否有用:-)
关于javascript - 是否可以将 Symbol.species 用于普通对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33972314/