摘自MDN
新字符串文字(用双引号或单引号表示)和从非构造函数上下文中的字符串调用返回的字符串(即,不使用
关键字)是原始字符串。JavaScript自动将原语转换为String对象,因此可以对原语字符串使用String对象方法。在要对原语字符串调用方法或进行属性查找的上下文中,JavaScript将自动包装字符串原语并调用该方法或执行属性查找。
因此,我认为(逻辑上)对string基元的操作(方法调用)应该比对string对象的操作慢,因为在对string应用method之前,任何string基元都会转换为string对象(额外的工作)。
但在这个test case中,结果正好相反。-1\f25-1\f6编码块-1\f25-1\f6比-1\f25-2\f6编码块-2\f25-1\f6运行得更快,两个编码块如下:
代码块-1 :
var s = '0123456789';
for (var i = 0; i < s.length; i++) {
s.charAt(i);
}代码块-2 :
var s = new String('0123456789');
for (var i = 0; i < s.length; i++) {
s.charAt(i);
}结果因浏览器而异,但代码块-1\f25-1\f6总是更快。谁能解释一下,为什么代码块-1\f25-1比-1\f25-1代码块-2\f25-1快。
发布于 2013-06-23 07:34:20
JavaScript有两个主要的类型类别,原语和对象。
var s = 'test';
var ss = new String('test');单引号/双引号模式在功能方面是相同的。除此之外,您尝试命名的行为称为自动装箱。因此,实际发生的情况是,当调用包装器类型的方法时,原语被转换为包装器类型。简单地说:
var s = 'test';是一种原始数据类型。它没有方法,它只是一个指向原始数据内存引用的指针,这解释了更快的随机访问速度。
例如,当你使用s.charAt(i)的时候会发生什么呢?
因为s不是String的实例,所以JavaScript将自动装箱s,它的包装器类型typeof string为String,带有typeof object,或者更准确地说是s.valueOf(s).prototype.toString.call = [object String]。
自动装箱行为根据需要将s来回转换为其包装器类型,但标准操作的速度非常快,因为您正在处理更简单的数据类型。然而,自动装箱和Object.prototype.valueOf有不同的效果。
如果你想强制自动装箱或者将一个原语转换为它的包装器类型,你可以使用Object.prototype.valueOf,但是行为是不同的。基于各种各样的测试场景,自动装箱只应用“必需的”方法,而不改变变量的原始性质。这就是为什么你会获得更快的速度。
发布于 2013-06-23 07:45:52
这在很大程度上依赖于实现,但我会尝试一下。我将以V8为例,但我假设其他引擎也使用类似的方法。
字符串原语被解析为v8::String对象。因此,就像jfriend00提到的那样,可以直接在它上面调用方法。
另一方面,String对象被解析为扩展Object的v8::StringObject,除了是一个完全成熟的对象外,它还充当v8::String的包装器。
现在这是合乎逻辑的,在执行方法之前,对new String('').method()的调用必须对此v8::StringObject的v8::String进行拆箱,因此速度较慢。
在许多其他语言中,原始值没有方法。
MDN的方式似乎是解释原语的自动装箱如何工作的最简单的方法(在flav的回答中也提到了),即JavaScript的原语-y值如何调用方法。
但是,智能引擎不会在每次需要调用方法时都将字符串原语-y转换为字符串对象。关于解析原始值的属性(和“方法”),Annotated ES5 spec.中也提到了这一点:
备注在上述方法之外,无法访问在步骤1中创建的对象。实现可能会选择避免实际创建对象。..。
在非常低的级别上,字符串通常被实现为不可变的标量值。示例包装器结构:
StringObject > String (> ...) > char[]你离原语越远,到达原语的时间就越长。在实践中,String原语比StringObject要频繁得多,因此引擎将方法添加到String原语的相应(解释的)对象的类中并不奇怪,而不是像MDN的解释所建议的那样在String和StringObject之间来回转换。
?在JavaScript中,“方法”只是一个属性的命名约定,它解析为函数类型的值。
发布于 2016-04-14 14:01:15
对于字符串文字,我们不能赋值属性
var x = "hello" ;
x.y = "world";
console.log(x.y); // this will print undefined而在String对象的情况下,我们可以分配属性
var x = new String("hello");
x.y = "world";
console.log(x.y); // this will print worldhttps://stackoverflow.com/questions/17256182
复制相似问题