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 —— 全局对象:值属性与函数属性(globalThis/Infinity/NaN/undefined/eval/isFinite/isNaN) #101

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

Comments

@lizhongzhen11
Copy link
Owner

lizhongzhen11 commented Apr 24, 2020

全局对象:值属性与函数属性(globalThis/Infinity/NaN/undefined/eval/isFinite/isNaN)

全局对象:

  • 在控制进入任何 执行上下文 之前创建
  • 没有 [[Construct]] 内置方法;不能被 new 操作符当成 构造器 调用
  • 没有 [[Call]] 内置方法;不能被当成函数调用
  • [[Prototype]] 内置插槽,其值依赖于具体实现
  • 可能存在除规范中已定义的、由主机环境定义的额外的属性。可能包含一个属性其值为全局对象本身

全局对象的值属性

全局对象的函数属性

eval(x)

  • MDN
  • 不要用,了解即可

eval 函数就是 %eval% 固有对象。

  1. 断言:执行上下文栈 至少有两个元素
  2. 定义 callerContext执行上下文栈 倒数第二个元素
  3. 定义 callerRealmcallerRealm领域
  4. 返回 ? PerformEval(x, callerRealm, false, false)

PerformEval( x, callerRealm, strictCaller, direct )

  1. 断言:如果 directfalse,那么 strictCaller 也是 false
  2. 如果 x 不是 String 类型,返回 x
  3. 定义 evalRealm当前领域记录
  4. 执行 ? HostEnsureCanCompileStrings(callerRealm, evalRealm)
  5. 定义 inFunctionfalse
  6. 定义 inMethodfalse
  7. 定义 inDerivedConstructorfalse
  8. 如果 directtrue
    1. 定义 thisEnvRec! GetThisEnvironment()
    2. 如果 thisEnvRecFunction Environment Records
      1. 定义 FthisEnvRec.[[FunctionObject]]
      2. 设置 inFunctiontrue
      3. 设置 inMethodthisEnvRec.HasSuperBinding()
      4. 如果 F.[[ConstructorKind]]derived,设置 inDerivedConstructortrue
  9. 以依赖于实现的顺序执行下面的子步骤,可能交叉解析和错误检测:
    1. 定义 script 为ECMAScript代码,其为 ! UTF16DecodeString(x) 解析结果,用于 目标符号 Script。如果解析失败,抛 SyntaxError 异常。如果检测到早期错误,抛 SyntaxError 异常(根据 错误处理和语言扩展)。
    2. 如果 script 包含 ScriptBodyfalse,返回 undefined
    3. 定义 bodyscriptScriptBody
    4. 如果 inFunctionfalse,且 body 包含 NewTarget,抛 SyntaxError 异常
    5. 如果 inMethodfalse,且 body 包含 SuperProperty,抛 SyntaxError 异常
    6. 如果 inDerivedConstructorfalse,且 body 包含 SuperCall,抛 SyntaxError 异常
  10. 如果 strictCallertrue,定义 strictEvaltrue
  11. 否则,定义 strictEvalscriptIsStrict
  12. 定义 runningContext运行时执行上下文
  13. 注意:如果 directtruerunningContext 将成为执行 直接eval执行上下文。如果 directfalserunningContext 将成为调用 eval 函数的 执行上下文
  14. 如果 directtrue
    1. 定义 lexEnvNewDeclarativeEnvironment(runningContext's LexicalEnvironment)
    2. 定义 varEnvrunningContext's VariableEnvironment
  15. 否则,
    1. 定义 lexEnvNewDeclarativeEnvironment(evalRealm.[[GlobalEnv]])
    2. 定义 varEnvevalRealm.[[GlobalEnv]]
  16. 如果 strictEvaltrue,设置 varEnvlexEnv
  17. 如果 runningContext 没有挂起暂停,则暂停 runningContext
  18. 定义 evalContext 为新的ECMAScript代码 执行上下文
  19. 设置 evalContext's Functionnull
  20. 设置 evalContext's 领域evalRealm
  21. 设置 evalContext's ScriptOrModulerunningContext's ScriptOrModule
  22. 设置 evalContext's VariableEnvironmentvarEnv
  23. 设置 evalContext's LexicalEnvironmentlexEnv
  24. evalContext 推入 执行上下文栈evalContext 现在是 运行时执行上下文
  25. 定义 resultEvalDeclarationInstantiation(body, varEnv, lexEnv, strictEval)
  26. 如果 result.[[Type]]normal
    1. 设置 result 为求值 body 的结果
  27. 如果 result.[[Type]]normalresult.[[Value]]empty
    1. 设置 resultNormalCompletion(undefined)
  28. 暂停 evalContext 且将其从 执行上下文栈 中移除
  29. 恢复 执行上下文栈 顶上下文为 运行时执行上下文
  30. 返回 Completion(result)

注意:如果调用上下文正在对形参初始化器求值或调用上下文的代码或者eval代码是 严格模式,那么eval代码不能在调用eval的上下文变量环境中实例化变量或函数绑定。上述绑定会在新的只有eval代码才能访问的变量环境中实例化。let, const, class 声明总是在新的词法环境进行实例化绑定。

isFinite( number )

先转 Number

isFinite(Infinity) // false
isFinite(NaN) // false
isFinite(-Infinity) // false
isFinite(0) // true
isFinite(2e64) // true
isFinite("0") // true
isFinite(9n) // Uncaught TypeError: Cannot convert a BigInt value to a number
isFinite(undefined) // false
isFinite(null) // true
isFinite({}) // false
isFinite([]) // true

isFinite 函数就是 %isFinite% 固有对象。

  1. 定义 num? ToNumber(number)
  2. 如果 numNaN+∞-∞,返回 false
  3. 否则返回 true

由于内部用的是 ToNumber 算法,所以对于对象,改写其 toString 方法返回有限值就能得到 true

const obj = {
  toString() {
    return 1
  }
}
Number(obj) // 1
isFinite(obj) // true

isNaN

对应 %isNaN% 固有对象。

isNaN(NaN) // true
isNaN({}) // true
  1. 定义 num? ToNumber(number)
  2. 如果 numNaN,返回 true
  3. 否则返回 false

内部用的是 ToNumber 算法,所以对于对象,改写其 toString 方法返回非 NaN 值就能得到 true

本篇结束,后续见下一篇

@lizhongzhen11 lizhongzhen11 added js基础 Good for newcomers 重学js 重学js系列 规范+MDN labels Apr 24, 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