为何'abc'.hasOwnProperty('length')返回true,'length' in 'abc'却报错?
为什么字符串字面量
'abc'调用hasOwnProperty('length')返回true,但'length' in 'abc'会报错? 这个问题真的问到点子上了!刚好能帮你理清JavaScript里原始类型和包装对象的核心差异——这也是很多JS开发者容易懵的点。
核心逻辑:字符串字面量不是对象,但调用方法时会被临时“包装”
JavaScript里的字符串、数字、布尔都是原始值,本身不是对象,没有属性和方法。但当你尝试调用它们的方法时,JS引擎会偷偷做一件事:自动创建一个对应的包装对象(比如new String('abc')),用这个对象来执行方法,执行完立刻销毁这个临时对象。
1. 'abc'.hasOwnProperty('length')能正常返回true的原因
当你写这段代码时,JS引擎的步骤是:
- 把原始字符串
'abc'临时包装成String实例对象 - 调用这个对象的
hasOwnProperty方法(这个方法来自Object.prototype,String原型继承了它) length是String实例的自有属性(每个字符串实例都自带length),所以hasOwnProperty返回true- 临时的
String对象被销毁,你拿到的还是原始字符串
2. 'length' in 'abc'报错的原因
in运算符有个硬规则:它的右操作数必须是对象。和方法调用不同,in是运算符,JS引擎不会为它的右操作数自动创建包装对象。
所以当你写'length' in 'abc'时,右操作数是原始字符串,不是对象,直接触发TypeError: Cannot use 'in' operator on a non-object。
小技巧:如果想用in检测字符串的length怎么办?
你可以手动把字面量转成包装对象:
// 方法1:用new String创建包装对象 'length' in new String('abc') // 返回true // 方法2:用Object()强制转换(不会创建构造函数实例,更轻量) 'length' in Object('abc') // 同样返回true
额外补充:为什么hasOwnProperty能识别length?
因为length是String实例的自有属性,不是从原型链继承来的。如果是继承的属性(比如toString),你会看到这样的结果:
'abc'.hasOwnProperty('toString') // 返回false,因为toString是从String.prototype继承的 'toString' in new String('abc') // 返回true,因为in会检查整个原型链
内容的提问来源于stack exchange,提问作者sliptype
相关产品推荐
相关产品推荐

