是否可以将Symbol.species用于普通对象?

Kyl*_*yll 5 javascript ecmascript-6

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
Run Code Online (Sandbox Code Playgroud)

ECMAScript的2015年规范说:

一个函数值属性,它是用于创建派生对象的构造函数.

我理解它的方式主要用于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
Run Code Online (Sandbox Code Playgroud)

有没有办法Symbol.species在普通物体上使用以欺骗instanceof操作员?

Ber*_*rgi 5

我理解它的方式主要用于Duck-Type以某种方式自定义对象以欺骗instanceof操作员.

不,这Symbol.hasInstance是有益的(虽然它使得棘手的构造函数,例如mixin,而不是棘手的实例).

关键Symbol.species是让内置方法确定派生对象的正确类型.每当一个函数应该返回一个同类的新实例时,它通常会实例化一个new this.constructor,它可能是定义该方法的类的子类.但是你可能不总是希望这个子类时,和这是哪里Symbol.species的用武之地.
通过MDN给出的例子是相当不错的,你就一定不能错过的区别amapped:

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
Run Code Online (Sandbox Code Playgroud)

(你知道,instanceof 就是是对的反向刚刚糖isPrototypeOf)

所以这里发生的是在一个实例上调用Array map方法MyArray,并创建一个派生对象,现在它是一个实例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
Run Code Online (Sandbox Code Playgroud)

我不能说这个例子中是否有用,但是:-)