路过
挺有意思的,如果是个基础知识面试题,大概有这几个层次的问题要回答。
首先,浏览器环境中,name 是 window 对象的属性,在没有 let 同名变量声明时,会get window.name 属性值。
window.name 的 idl 定义中它是个 DOMString
因此,存在设置值 V converted to DOMString 的过程
这个过程中,如果没有 idl 中特征值 [LegacyNullToEmptyString] 的情况下,会执行 ES 的 ToString(V) 方法将设置值将 V 转为 String
name 的 idl 声明中没有 [LegacyNullToEmptyString] ,因此执行 ToString(V) 后为字符串 "null",而非空或 null
具有 [LegacyNullToEmptyString] idl 定义的 DOMString 定义,则会将 null 直接转为空字符,而非执行 ToString(V)
这些特殊的 DOMString 可以看 whatwg 的 HTML5 规范中相关 idl 定义梳理,或者直接搜浏览器源码获得,比如 chromium 的
看起来也不是特别多,毕竟椒 Legacy …… 太多会交税的……
因为 name 是预设变量
var name = fun();
会把 name 挂载到 Window 下,所以实际上是 Window.name。而 Window.name 是一个预设的变量,这个变量返回浏览器上下文的名字( Browser context name),现代浏览器会默认返回一个空字符串。但任何给 name 新赋予的值,都会被自动 toString(),这是浏览器行为。
所以你的 console.log 里,其实是 "null" === null,当然返回就是 false 了。
举例子
name = 123; console.log(name); // "123" name = /abc/; console.log(name); // "/abc/"; name = { foo: 'bar' }; console.log(name); // [object Object] name = null; console.log(null); // "null"
所以解决方法很简单,换个变量名就行了