美文网首页JavaScript
[ECMAScript] 当Public Class Field

[ECMAScript] 当Public Class Field

作者: 何幻 | 来源:发表于2017-03-17 18:05 被阅读83次

    1. Babel

    Public Class Fields目前是TC39 Stage 2的特性。

    在实际项目中,我们使用了Babel进行转译。
    Public Class Fields如果是一个箭头函数,那么这个函数中this的指向,如下所示。
    (可在Babel REPL中试验

    class A {
        v = this;  // instance
    
        static f = () => {
            return this;  // undefined
        }
    
        g = () => {
            return this;  // instance
        }
    }
    
    alert(A.f() === undefined);  // true
    
    const a = new A;
    alert(a.g() === a);  // true
    alert(a.v === a);  // true
    

    对于static字段,thisundefined
    对于实例字段,this指向类的实例。


    2. Public Class Fields

    (1)ClassDefinitionEvaluation

    我们看Public Class Fields规范,
    执行过程是从ClassDefinitionEvaluation开始的,
    这个函数比较长,我们只截取与public class fields有关的部分,如下,

    因此在class声明的时候,对于那些public class fields进行了求值。
    实际调用的是ClassPublicFieldDefinitionEvaluation函数,
    该函数最后返回了一个Record


    (2)ClassPublicFieldDefinitionEvaluation

    其中[[initializer]]字段是一个函数,由FunctionCreate创建。
    FunctionCreateECMAScript规范中定义的函数。

    因此,每一个public class fields对应一个Record
    这个Record中有一个[[initializer]]函数字段,
    函数体是产生式PublicFieldDefinition: PropertyName Initializer中的Initializer
    函数的求值结果是public class fields的值。

    为什么不直接使用产生式中Initializer对应的值呢,
    而是要先把它包裹成一个函数。
    这是为了改变public class fields等式右边this指向。

    class A {
        v = this;  // instance
    }
    

    到此为止,class声明时要做的事情就完成了,
    然后我们要看实例化时发生的事情。


    (3)[[Construct]]

    这个函数描述了进行new操作时发生的事情,
    其中,InitializePublicInstanceFields表示了对public class fields初始化,
    OrdinaryCallEvaluateBody表示了求值classconstructor函数。

    下面我们看InitializePublicInstanceFields函数。


    (4)InitializePublicInstanceFields

    这时拿到ClassPublicFieldDefinitionEvaluation返回的Record
    获取它的[[initializer]]函数字段,然后用当前类的实例,调用它,
    因此,this就指向当前类型的实例了。

    class A {
        v = this;
    
        g = () => {
            return this;
        }
    }
    
    // 声明时,变成了
    class A {
        v = new Record({
            [[initializer]]:function(){
                return this;
            }
        });
    
        g = new Record({
            [[initializer]]:function(){
                return ()=>{
                    return this;
                }
            }
        });
    }
    
    // new的时候变成了
    class A {
        v = record.[[initializer]].call(instance);
    
        g = record.[[initializer]].call(instance);
    }
    

    因此,public class fields字段中的this指向类的实例。


    参考

    Babel REPL - Stage 2
    Public Class Fields
    ECMAScript® 2017 Language Specification

    material-ui中的例子
    React官方文档中的例子 - handleClick

    相关文章

      网友评论

        本文标题:[ECMAScript] 当Public Class Field

        本文链接:https://www.haomeiwen.com/subject/mjoenttx.html