为何JS中"string".abcd返回undefined而非报错?附代码分析
嘿,我来帮你把这几个JavaScript里的问题掰扯清楚,尤其是第三个容易混淆的点~
先理清前两个代码片段的错误原因
代码片段1:执行
var a=aaa;时抛出Uncaught ReferenceError: aaa is not defined
这是因为你直接读取了一个完全没声明过的变量。JavaScript里,当你尝试访问一个既没通过var/let/const声明、也不是全局对象属性的标识符时,引擎找不到这个变量的绑定,就会抛出ReferenceError。代码片段2:执行
var a="string".abcd();时抛出"string".abcd is not a function错误
这里分两步:首先你访问字符串的abcd属性,JS引擎找了一圈没找到,返回undefined;接着你试图把undefined当作函数来调用,这自然就触发了TypeError——毕竟undefined根本不是函数类型。
重点解答第三个疑问:为什么"string".abcd不报错反而返回undefined?TypeScript又为什么警告?
这核心是变量访问和属性访问的机制完全不同:
JavaScript的属性查找逻辑:
当你访问对象的某个属性时,JS引擎会沿着该对象的原型链逐层向上查找。如果一直查到原型链的顶端(也就是null)都没找到这个属性,不会抛出错误,而是直接返回undefined。
你这里的"string"是字符串基本类型,访问属性时会被自动装箱成String对象实例,它的原型链是String.prototype -> Object.prototype -> null,这条链上压根没有abcd属性,所以最终返回undefined。
而变量访问是直接在词法环境/全局环境里找标识符,找不到就直接报错,和属性访问是两套完全独立的规则。TypeScript警告的原因:
TypeScript是静态类型语言,它会在编译阶段就做严格的类型检查。string类型在TS的标准类型定义里,并没有abcd这个属性,所以TS会直接给你抛出警告:属性“abcd”在类型“string”上不存在——这是TS在帮你提前规避运行时可能出现的问题,毕竟你访问一个不存在的属性十有八九是写代码时的疏漏。
内容的提问来源于stack exchange,提问作者Ramesh Rajendran

