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

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

问题描述

取自 MDN

字符串文字(用双引号或单引号表示)和字符串从非构造函数上下文中的 String 调用返回(即,没有使用 new 关键字)是原始字符串.JavaScript 自动将原语转换为 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.

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

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 总是更快.谁能解释一下,为什么 code block-1code block-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, primitives 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.

例如,当您执行 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 中的字符串基元和字符串对象有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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