ES6学习——类语法:Symbol.species在实例创建中的应用
来源:互联网 发布:linux 启动tomcat 编辑:程序博客网 时间:2024/06/06 07:16
在Symbol的章节我们大概介绍了一下species,这篇文章详细看一下规范中是如何调用的,以及我们在自定义类的时候可以怎么使用这个symbol。
我们拿Array.prototype.map举例:
规范22.1.3.15 Array.prototype.map ( callbackfn [ , thisArg ] ):
1. Let O be ToObject(this value).
2. ReturnIfAbrupt(O).
7. Let A be ArraySpeciesCreate(O, len).
8. ReturnIfAbrupt(A).
规范9.4.2.3 ArraySpeciesCreate(originalArray, length):
3. Let C be undefined.
4. Let isArray be IsArray(originalArray).
5. ReturnIfAbrupt(isArray).
6. If isArray is true, then
a. Let C be Get(originalArray, "constructor").
b. ReturnIfAbrupt(C).
c. If IsConstructor(C) is true, then
......
d. If Type(C) is Object, then
i. Let C be Get(C, @@species).
ii. ReturnIfAbrupt(C).
iii. If C is null, let C be undefined.
7. If C is undefined, return ArrayCreate(length).
8. If IsConstructor(C) is false, throw a TypeError exception.
9. Return Construct(C, «length»).
我们应该注意ArraySpeciesCreate中的6.a,这里要取一次originalArray的constructor属性,并赋值给C,所以在重写这个Symbol.species的时候,应该复写成静态getter的形式,或者用Object.defineProperty。
下面我们详细看一下这两种形式:
class MyArray1 extends Array {static get [Symbol.species]() { // 静态getterreturn Array;}}var arr = new MyArray1(4),mapArr = arr.map(x=>x);trace(mapArr instanceof Array)//truetrace(mapArr instanceof MyArray1)//false
class MyArray1 extends Array {}Object.defineProperty(//Object.definePropertyMyArray1, Symbol.species, {value: Array});
上面两种形式的本质目的就是为了符合规范,其实就是让mapArr.constructor[Symbol.species]能取回一个Object。那么为什么不能直接在MyArray1上定义静态属性呢?如下:
MyArray1[Symbol.species] = Array
因为Array上已经有这个属性了,并且是只读的,只有一个getter,没有setter,不能进行赋值。在规范的22.1.2.5 get Array [ @@species ]:
Array[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:
1. Return the this value.
The value of the name property of this function is "get [Symbol.species]".
NOTE Array prototype methods normally use their this object’s constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.
如果Symbol.species返回null,规范ArraySpeciesCreate的7中就会自动使用默认的创建数组方法,即创建出来的是Array类型:
class MyArray3 extends Array { static get [Symbol.species]() { return null; }}let result3 = new MyArray3().map(x => x);trace(result3 instanceof Array); // true
下面我们看一个自定义的类中如何使用这个Symbol.species:
class Foo {static get [Symbol.species]() { return this; }spawn() {return new this.constructor[Symbol.species]();//不需要写死返回实例类型}}class Bar extends Foo {static get [Symbol.species]() { return Foo; }//自定义需要返回的实例类型}var a = new Foo();var b = a.spawn();b instanceof Foo; // truevar x = new Bar();var y = x.spawn();y instanceof Bar; // falsey instanceof Foo; // true
*以上全部代码在Kinoma Studio中通过测试。
- ES6学习——类语法:Symbol.species在实例创建中的应用
- ES6学习——新的语法:Symbols——Symbol.toPrimitive,Symbol.hasInstance,Symbol.toStringTag,Symbol.species
- ES6学习——新的语法:Symbol概述
- ES6学习——新的语法:Symbol API介绍
- ES6学习——类语法:继承中的实例构造过程
- ES6学习——新的语法:Symbol private类属性
- ES6学习——类语法:继承中的原型链
- ES6学习——类语法:继承中的原型链
- ES6学习——新的语法:Symbols——Symbol.iterator
- 8、Symbol数据类型—ES6学习笔记
- ES6 — Symbol
- ES6学习——类语法:其它
- ES6——Symbol数据类型
- es6 中的symbol
- ES6中的Symbol类型
- ES6 Symbol 学习
- ES6学习——类语法:基本概念介绍
- ES6学习——类语法:super和new.target
- 通过VGA启动参数来设置屏幕分辨率模式
- 腾讯云公网ip访问不通的问题解决
- BZOJ 4247: 挂饰|动态规划
- [leetcode] 117. Populating Next Right Pointers in Each Node II 解题报告
- 【经验之谈】C3P0或者dbcp连接池报错
- ES6学习——类语法:Symbol.species在实例创建中的应用
- Swift学习之转义字符
- 神经网络如何表达x1*x2?
- 深入理解Java:注解(Annotation)基本概念
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)--注解处理器
- 深入理解Java:内省(Introspector)
- Topcoder SRM 677 div2
- 无名网络流1