JavaScript中的字符串原语和String对象有什么区别? [英] What is the difference between string primitives and String objects in JavaScript?

查看:156
本文介绍了JavaScript中的字符串原语和String对象有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

取自 MDN


字符串文字(用双引号或单引号表示)和字符串在非构造函数上下文中从String调用返回的
(即,使用new关键字没有
)是原始字符串。 JavaScript自动
将原语转换为String对象,因此可以对原始字符串使用
String对象方法。在要在原始字符串或属性查找
上调用
方法的上下文中,JavaScript将自动换行字符串原语,
调用该方法或执行属性查找。

String literals (denoted by double or single quotes) and strings returned from String calls in a non-constructor context (i.e., without using the new keyword) are primitive strings. JavaScript automatically converts primitives to String objects, so that it's possible to use String object methods for primitive strings. In contexts where a method is to be invoked on a primitive string or a property lookup occurs, JavaScript will automatically wrap the string primitive and call the method or perform the property lookup.

所以,我认为(逻辑上)字符串基元上的操作(方法调用)应该比字符串对象上的操作慢,因为任何字符串基元都被转换在字符串上应用方法之前串起来对象(额外的工作)。

So, I thought (logically) operations (method calls) on string primitives should be slower than operations on string Objects because any string primitive is converted to string Object (extra work) before the method being applied on the string.

但是在这个测试用例,结果相反。 代码块-1 运行速度比代码块-2 快,两个代码块如下所示:

But in this test case, the result is opposite. The code block-1 runs faster than the code block-2, both code blocks are given below:

代码区块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 总是更快。任何人都可以解释一下,为什么代码块-1 代码块-2 更快。

The results varies in browsers but the code block-1 is always faster. Can anyone please explain this, why the code block-1 is faster than code block-2.

推荐答案

JavaScript有两个主要类型,即原始对象和对象。

JavaScript has two main type categories, primivites and objects.

var s = 'test';
var ss = new String('test');

单引号/双引号模式在功能方面完全相同。除此之外,您尝试命名的行为称为自动装箱。所以实际发生的是,当调用包装类型的方法时,将基元转换为其包装类型。简单来说:

The single quote/double quote patterns are identical in terms of functionality. That aside, the behaviour you are trying to name is called auto-boxing. So what actually happens is that a primitive is converted to its wrapper type when a method of the wrapper type is invoked. Put simple:

var s = 'test';

是原始数据类型。它没有方法,只不过是指向原始数据存储器引用的指针,这解释了随机访问速度更快的速度。

Is a primitive data type. It has no methods, it is nothing more than a pointer to a raw data memory reference, which explains the much faster random access speed.

那么当你做什么时会发生什么? code> s.charAt(i)例如?

So what happens when you do s.charAt(i) for instance?

因为 s 不是 String 的实例,JavaScript将自动装箱 s ,其中包含 typeof string 到它的包装类型, String typeof object 或者更确切地说是 s.valueOf(s).prototype.toString.call = [object String]

Since s is not an instance of String, JavaScript will auto-box s, which has typeof string to its wrapper type, String, with typeof object or more precisely s.valueOf(s).prototype.toString.call = [object String].

自动装箱行为根据需要来回转换 s 到其包装类型,但标准操作是因为你正在处理一个更简单的数据类型,所以速度非常快。但是,自动装箱和 Object.prototype.valueOf 具有不同的效果。

The auto-boxing behaviour casts s back and forth to its wrapper type as needed, but the standard operations are incredibly fast since you are dealing with a simpler data type. However auto-boxing and Object.prototype.valueOf have different effects.

如果你想强制自动装箱或将基元转换为其包装类型,您可以使用 Object.prototype.valueOf ,但行为不同。基于各种测试场景,自动装箱仅应用必需方法,而不改变变量的原始性质。这就是为什么你获得更好的速度。

If you want to force the auto-boxing or to cast a primitive to its wrapper type, you can use Object.prototype.valueOf, but the behaviour is different. Based on a wide variety of test scenarios auto-boxing only applies the 'required' methods, without altering the primitive nature of the variable. Which is why you get better speed.

这篇关于JavaScript中的字符串原语和String对象有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆