试图让我的JavaSscript基础变得强大。所以问题是关于字符串文字。他们不是Objects
吗?如果您的答案为“是”,那么我的问题是为什么instanceof
会返回false
?
> var s = new String
> s.constructor.toString()
function String() { [native code] }
> typeof s
object
> s instanceof String
true
> s instanceof Object
true
> s instanceof Number
false
到目前为止一切顺利。
> typeof 'c'
string
> 'c' instanceof Object
false
> 'c' instanceof String
false
> 'c'.length
1
> 'c'.charAt(0)
c
> 'c'.constructor.toString()
function String() { [native code] }
答案 0 :(得分:5)
字符串文字是基元(String values),String objects可以使用new
表达式中的String constructor创建:
"foo" instanceof String // false
new String("foo") instanceof String // true
编辑:似乎令人困惑的事情(通过查看已接受的答案here),您仍然可以访问原型对象上定义的属性原始值>,例如:
"foo".indexOf == String.prototype.indexOf // true
"foo".match == String.prototype.match // true
String.prototype.test = true;
"foo".test // true
true.toString == Boolean.prototype.toString
(3).toFixed == Number.prototype.toFixed // true
// etc...
这样做的原因取决于Property Accessors,点符号.
和括号符号[]
。
让我们看一下ECMA-262规范中的算法:
生产MemberExpression:MemberExpression [Expression](或MemberExpression。标识符)的评估如下:
评估MemberExpression
。
致电GetValue(Result(1))
。
评估表达。
致电GetValue(Result(3))
。
致电ToObject(Result(2))
。
致电ToString(Result(4))
。
返回Reference类型的值,其基础对象为Result(5),其属性名称为Result(6)
。
在第5步中,ToObject
内部运算符类型 - 将MemberExpression转换为object,具体取决于它的类型。
基元在没有注意的情况下转换为对象,这就是为什么你可以访问原型上定义的属性。
答案 1 :(得分:0)
对此here的详细解释。复制以供参考。
那是因为那些东西是原语,除非它们需要用作对象(例如,当你在它们上调用方法时),它们仍然如此。他们“成为”物品的唯一时间是他们需要被包裹的时候。如果你熟悉.NET中“装箱”的概念,那么就这样想吧。
这是一个例子 - 看一下这段代码:
Number.prototype.times = function(func) {
for(var index = 1; index <= this; index++) {
func(index);
}
};
因此,以下代码将失败:
3.times(print); // assume 'print' writes to standard out
3,本身就是一个原始的。也就是说,以下内容将起作用:
(3).times(print); // assume 'print' writes to standard out
这将显示数字1,2和3.由于括号,JavaScript解释器将暂时将基元3包装在Number对象中,调用该方法,然后垃圾收集该对象,因为它不需要不再。
中找到对此的完整讨论