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

标签 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

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给的例子很好,大家一定不要错过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

(如您所知,instanceof is 只是 isPrototypeOf 的逆向糖)

所以这里发生的是 Array map methodMyArray 实例上调用,并且 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/

相关文章:

javascript - 客户端存储/缓存大型 HTML

javascript - 为什么ES6定义了map.length==0?

javascript - ES2015 类是 "not autobind"吗?

javascript - 使用 jQuery 创建 DIV 网格

javascript - 向匿名元素添加伪元素和光标样式以及事件监听器

javascript - 对象旋转中的对象 ThreeJS

javascript - 上传到存储服务器时文件格式发生变化

javascript - 如果 td 元素(.grid 单元格)具有某些文本(在 '...' 中),则在单击时更改其样式

javascript - 如何正确加载图片路径?

javascript - html 似乎无法读取脚本元素