Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重学js —— 左侧表达式(new/super/import()/可选链等) #70

Open
lizhongzhen11 opened this issue Jan 27, 2020 · 0 comments
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN

Comments

@lizhongzhen11
Copy link
Owner

lizhongzhen11 commented Jan 27, 2020

左侧表达式

只选取了部分进行翻译

new 操作符

  • MDN-new
  • MDN-new.target
  • 冴羽——JavaScript深入之new的模拟实现(这个读ya第四声,微软自带的输入法居然打不出来)
  • 我的模拟实现
    1. 能用 new 的一定是内部实现了 [[Call]] 方法的对象,即 typeof 结果为 'function'注意:箭头函数不能做构造器,需排除!
    2. 如果构造函数自身没有返回值,那么会返回一个对象,其原型对象指向构造函数的 prototype
    3. 如果构造函数自身有返回值且该值是对象,那么直接返回
    4. 最难理解的其实是传参给构造函数后,如何让得到的对象其拥有构造函数内部定义的属性以及传过来的值,这里比较费时间,这里要记住改变 this 为返回的对象,并通过 call 或 apply 调用即可,例如
      function test(name){
        this.name = name
      }
      new test('a') // {name: 'a'}
    5. Function, Date 等调用 new,有点特殊,我代码里没有考虑

运行时语义:Evaluation

New表达式new NewExpression

  1. 返回 ? EvaluateNew(NewExpression, empty)

MemberExpressionnew MemberExpression Arguments

  1. 返回 ? EvaluateNew(MemberExpression, Arguments)

EvaluateNew

  1. 断言:constructExprNewExpressionMemberExpression
  2. 断言:arguments 是 empty 或 Arguments
  3. 定义 ref 为计算 constructExpr 结果
  4. 定义 constructor? GetValue(ref)
  5. 如果 arguments 为 empty,定义 argList 为新的空 List
  6. 否则,
    1. 定义 argList? arguments 的参数列表
  7. 如果 constructor 不是构造器,抛类型错误
  8. 返回 ? Construct(constructor, argList)

super 关键字

MDN

运行时语义:Evaluation

SuperPropertysuper [ Expression ]

对应 super[expr] 这种调用

  1. 定义 envGetThisEnvironment()
  2. 定义 actualThis? env.GetThisBinding()
  3. 定义 propertyNameReferenceExpression 运算结果
  4. 定义 propertyNameValue? GetValue(propertyNameReference)
  5. 定义 propertyKey? ToPropertyKey(propertyNameValue)
  6. 如果与此 SuperProperty 匹配的代码是严格模式代码,定义 stricttrue,否则定义 strictfalse
  7. 返回 ? MakeSuperPropertyReference(actualThis, propertyKey, strict)

SuperPropertysuper . IdentifierName

对应 super.IdentifierName 这种调用

  1. 定义 envGetThisEnvironment()
  2. 定义 actualThis? env.GetThisBinding()
  3. 定义 propertyKeyIdentifierName 的字符串值
  4. 如果与此 SuperProperty 匹配的代码是严格模式代码,定义 stricttrue,否则定义 strictfalse
  5. 返回 ? MakeSuperPropertyReference(actualThis, propertyKey, strict)

SuperCallsuper Arguments

  1. 定义 newTargetGetNewTarget()
  2. 断言:newTarget 是对象
  3. 定义 func? GetSuperConstructor()
  4. 定义 argList? Arguments 的参数列表
  5. 定义 resultConstruct(func, argList, newTarget)
  6. 定义 thisERGetThisEnvironment()
  7. 返回 ? thisER.BindThisValue(result)

GetSuperConstructor

  1. 定义 envRecGetThisEnvironment()
  2. 断言:envRec函数环境记录
  3. 定义 activeFunctionenvRec.[[FunctionObject]]
  4. 断言:activeFunction 是ECMAScript 函数对象
  5. 定义 superConstructor! activeFunction.[GetPrototypeOf]
  6. 如果 superConstructor 不是构造器,抛类型错误
  7. 返回 superConstructor

MakeSuperPropertyReference

  1. 定义 envGetThisEnvironment()
  2. 断言:env.HasSuperBinding()true
  3. 定义 baseValue? env.GetSuperBase()
  4. 定义 bv? RequireObjectCoercible(baseValue)
  5. 返回一个 Reference 类型的值,该 ReferenceSuper Reference,其基础值部分是 bv,引用名称部分是 propertyKey,thisValue 部分是 actualThis,且严格引用标记是 strict

可选链

MDN

@babel/plugin-proposal-optional-chaining (babel支持)

Chrome v79 版本支持可选链,但是需要手动设置,浏览器url地址栏输入chrome://flags打开,搜索 Experimental JavaScript,选择启用。

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer.dog?.name;
console.log(dogName); // undefined

console.log(adventurer.someNonExistentMethod?.()) // undefined


// 使用 nullish 合并运算符设置一个默认值
let customer = {
  name: "Carl",
  details: { age: 82 }
};
let customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city

Evaluation

OptionalExpression :

    MemberExpression OptionalChain

  1. 定义 baseReference 为计算 MemberExpression 的结果
  2. 定义 baseValue? GetValue(baseReference)
  3. 如果 baseValueundefinednull
    1. 返回 undefined
  4. 返回执行 带参数 baseValuebaseReferenceOptionalChain 的链运算结果

OptionalExpression :

    CallExpression OptionalChain

  1. 定义 baseReference 为计算 CallExpression 的结果
  2. 定义 baseValue? GetValue(baseReference)
  3. 如果 baseValueundefinednull
    1. 返回 undefined
  4. 返回执行 带参数 baseValuebaseReferenceOptionalChain 的链运算结果

OptionalExpression :

    OptionalExpression OptionalChain

  1. 定义 baseReference 为计算 OptionalExpression 的结果
  2. 定义 baseValue? GetValue(baseReference)
  3. 如果 baseValueundefinednull
    1. 返回 undefined
  4. 返回执行 带参数 baseValuebaseReferenceOptionalChain 的链运算结果

ChainEvaluation 链运算

参数 baseValuebaseReference

OptionalChain : ?. Arguments

  1. 定义 thisChainOptionalChain
  2. 定义 tailCallIsInTailPosition(thisChain)
  3. 返回 ? EvaluateCall(baseValue, baseReference, Arguments, tailCall)

OptionalChain : ?. [ Expression ]

  1. 如果和 OptionalChain 匹配的代码是 严格模式代码,定义 stricttrue,否则定义 strictfalse
  2. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)

OptionalChain : ?. IdentifierName

  1. 如果和 OptionalChain 匹配的代码是 严格模式代码,定义 stricttrue,否则定义 strictfalse
  2. 返回 ? EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)

OptionalChain : OptionalChain Arguments

  1. 定义 optionalChainOptionalChain
  2. 定义 newReference? 带有参数 baseValuebaseReferenceoptionalChain 的链运算
  3. 定义 newValue? GetValue(newReference)
  4. 定义 thisChain 为该 OptionalChain
  5. 定义 tailCallIsInTailPosition(thisChain)
  6. 返回 ? EvaluateCall(newValue, newReference, Arguments, tailCall)

OptionalChain : OptionalChain [ Expression ]

  1. 定义 optionalChainOptionalChain
  2. 定义 newReference? 带有参数 baseValuebaseReferenceoptionalChain 的链运算
  3. 定义 newValue? GetValue(newReference)
  4. 如果和 OptionalChain 匹配的代码是 严格模式代码,定义 stricttrue,否则定义 strictfalse
  5. 返回 ? EvaluatePropertyAccessWithExpressionKey(newValue, Expression, strict)

OptionalChain : OptionalChain . IdentifierName

  1. 定义 optionalChainOptionalChain
  2. 定义 newReference? 带有参数 baseValuebaseReferenceoptionalChain 的链运算
  3. 定义 newValue? GetValue(newReference)
  4. 如果和 OptionalChain 匹配的代码是 严格模式代码,定义 stricttrue,否则定义 strictfalse
  5. 返回 ? EvaluatePropertyAccessWithIdentifierKey(newValue, IdentifierName, strict)

Import 调用

Evaluation

ImportCall : import ( AssignmentExpression )

  1. 定义 referencingScriptOrModule! GetActiveScriptOrModule()
  2. 定义 argRef 为运算 AssignmentExpression 的结果
  3. 定义 specifier? GetValue(argRef)
  4. 定义 promiseCapability! NewPromiseCapability( %Promise% )
  5. 定义 specifierStringToString(specifier)
  6. IfAbruptRejectPromise(specifierString, promiseCapability)
  7. 执行 ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability)
  8. 返回 promiseCapability.[[Promise]]
@lizhongzhen11 lizhongzhen11 added js基础 Good for newcomers 重学js 重学js系列 规范+MDN labels Jan 27, 2020
@lizhongzhen11 lizhongzhen11 changed the title 重学js —— 左侧表达式 重学js —— 左侧表达式(new等) Feb 27, 2020
@lizhongzhen11 lizhongzhen11 changed the title 重学js —— 左侧表达式(new等) 重学js —— 左侧表达式(new、import()等) Mar 23, 2020
@lizhongzhen11 lizhongzhen11 changed the title 重学js —— 左侧表达式(new、import()等) 重学js —— 左侧表达式(new/super/import()/可选链等) Mar 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js基础 Good for newcomers 重学js 重学js系列 规范+MDN
Projects
None yet
Development

No branches or pull requests

1 participant