JavaScript 中的 new String("x") 有什么意义?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5750656/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:41:18  来源:igfitidea点击:

What's the point of new String("x") in JavaScript?

javascriptstringtypesinstanceoftypeof

提问by Pacerier

What are the use cases for doing new String("already a string")?

有哪些用例new String("already a string")

What's the whole point of it?

它的全部意义是什么?

回答by Tim Down

There's very little practical use for Stringobjects as created by new String("foo"). The only advantage a Stringobject has over a primitive string value is that as an object it can store properties:

Stringnew String("foo").创建的对象几乎没有实际用途。String对象相对于原始字符串值的唯一优势是它可以存储属性:

var str = "foo";
str.prop = "bar";
alert(str.prop); // undefined

var str = new String("foo");
str.prop = "bar";
alert(str.prop); // "bar"

If you're unsure of what values can be passed to your code then I would suggest you have larger problems in your project. No native JavaScript object, major library or DOM method that returns a string will return a Stringobject rather than a string value. However, if you want to be absolutely sure you have a string value rather than a Stringobject, you can convert it as follows:

如果您不确定可以将哪些值传递给您的代码,那么我建议您在项目中遇到更大的问题。返回字符串的原生 JavaScript 对象、主要库或 DOM 方法都不会返回String对象而不是字符串值。但是,如果您想绝对确定您有一个字符串值而不是一个String对象,您可以按如下方式转换它:

var str = new String("foo");
str = "" + str;

If the value you're checking could be any object, your options are as follows:

如果您检查的值可以是任何对象,您的选项如下:

  1. Don't worry about String objects and just use typeof. This would be my recommendation.

    typeof str == "string".

  2. Use instanceof as well as typeof. This usually works but has the disadvantage of returning a false negative for a String object created in another window.

    typeof str == "string" || str instanceof String

  3. Use duck typing. Check for the existence of one or more String-specific methods, such as substring() or toLowerCase(). This is clearly imprecise, since it will return a false positive for an object that happens to have a method with the name you're checking, but it will be good enough in most cases.

    typeof str == "string" || typeof str.substring == "function"

  1. 不要担心 String 对象,只需使用 typeof。这将是我的建议。

    typeof str == "string".

  2. 使用 instanceof 和 typeof。这通常有效,但有一个缺点,即为在另一个窗口中创建的 String 对象返回假阴性。

    typeof str == "string" || str instanceof String

  3. 使用鸭子打字。检查是否存在一种或多种特定于字符串的方法,例如 substring() 或 toLowerCase()。这显然是不精确的,因为对于碰巧具有您正在检查的名称的方法的对象,它会返回误报,但在大多数情况下它已经足够了。

    typeof str == "string" || typeof str.substring == "function"

回答by Lucia

Javascript creators created wrappers for basic types like string or int just to make it similar to java. Unfortunately, if someome makes new String("x") the type of the element will be "object" and not "string".

Javascript 创建者为 string 或 int 等基本类型创建了包装器,只是为了使其类似于 java。不幸的是,如果有人创建 new String("x") 元素的类型将是“对象”而不是“字符串”。

var j = new String("x");
j === "x"  //false
j == "x" //true

回答by RobF

Stringobjects can have properties, while string primitives can not:

String对象可以有属性,而字符串原语不能:

var aStringObject=new String("I'm a String object");
var aStringPrimitive="I'm a string primitive";

aStringObject.foo="bar";
console.log(aStringObject.foo); //--> bar

aStringPrimitive.foo="bar";
console.log(aStringPrimitive.foo); //--> undefined

And Stringobjects can be inherited from, while string primitives can not:

String对象可以被继承,而字符串元不能:

var foo=Object.create(aStringObject);
var bar=Object.create(aStringPrimitive); //--> throws a TypeError

Stringobjects are can only be equal to themselves, not other Stringobjects with the same value, while primitives with the same value are considered equal:

String对象只能等于自己,不能等于其他String具有相同值的对象,而具有相同值的基元被认为是相等的:

var aStringObject=new String("I'm a String object");
var anotherStringObject=new String("I'm a String object");

console.log(aStringObject==anotherStringObject); //--> false

var aStringPrimitive="I'm a string primitive";
var anotherStringPrimitive="I'm a string primitive";

console.log(aStringPrimitive==anotherStringPrimitive); //--> true

You could implement overloading-likebehavior:

您可以实现类似重载的行为:

function overloadedLikeFunction(anArgument){
    if(anArgument instanceof String){
        //do something with a String object
    }
    else if(typeof anArgument=="string"){
        //do something with a string primitive
    }
}

Or specify argument purpose:

或指定参数目的:

function aConstructorWithOptionalArugments(){
    this.stringObjectProperty=new String("Default stringObjectProperty value");
    this.stringPrimitiveProperty="Default stringPrimitiveProperty value";
    for(var argument==0;argument<arguments.length;argument++){
        if(arguments[argument] instanceof String)
            this.stringObjectProperty=arguments[argument];
        if(typeof arguments[argument]=="string")
            this.stringPrimitiveProperty=arguments[argument];
    }
}

Or track objects:

或跟踪对象:

var defaultStringValue=new String("default value");
var stringValue=defaultStringValue;

var input=document.getElementById("textinput") //assumes there is an text <input> element with id equal to "textinput"
input.value=defaultStringValue;
input.onkeypress=function(){
    stringValue=new String(this.value);
}

function hasInputValueChanged(){
    //Returns true even if the user has entered "default value" in the <input>
    return stringValue!=defaultStringValue;
}

The existence of Stringobjects and string primitives effectively gives you two string "types" in Javascript with different behaviors and, consequently, uses. This goes for Booleanand Numberobjects and their respective primitives too.

String对象和字符串原语的存在有效地为您提供了 Javascript 中具有不同行为的两种字符串“类型”,因此,使用。这同样适用于BooleanNumber对象以及它们各自的元太。

Beware, however, of passing string (or other) primitives as the value of thiswhen using the function methods bind(), call()and apply(), as the value will be converted to a Stringobject (or a Booleanor a Numberobject, depending on the primitive) before being used as this:

当心,然而,传递字符串(或其他)基元作为对值的this使用功能的方法时bind()call()apply(),作为值将被转换为一个String对象(或一个Boolean或一个Number对象,这取决于原始)之前被用作this

function logTypeofThis(){
    console.log(typeof this);
}

var aStringPrimitive="I'm a string primitive";
var alsoLogTypeofThis=logTypeofThis.bind(aStringPrimitive);

console.log(typeof aStringPrimitive); //--> string;
logTypeofThis.call(aStringPrimitive); //--> object;
logTypeofThis.apply(aStringPrimitive); //--> object;
alsoLogTypeofThis(); //--> object;

And unexpected/counter-intuitive return types:

以及意外/违反直觉的返回类型:

var aStringObject=new String("I'm a String object");
console.log(typeof aStringObject); //--> object
aStringObject=aStringObject.toUpperCase();
console.log(typeof aStringObject); //--> string

回答by mu is too short

You could use instanceofif you really want to be paranoid:

instanceof如果你真的想变得偏执,你可以使用:

if(typeof x === "string" || x instanceof String)

The instanceofoperatorwill properly handle subclasses of String too:

instanceof运营商将妥善处理字符串的子太:

obj instanceof ConstructorFunctionworks by checking if ConstructorFunction.prototypeis in the prototype chain of obj.

obj instanceof ConstructorFunction通过检查是否ConstructorFunction.prototype在 的原型链中来工作obj

I don't think I've ever actually used the String class in JavaScript but there's nothing wrong with being paranoid and aiming for correctness.

我认为我从来没有真正在 JavaScript 中使用过 String 类,但是偏执和追求正确性并没有错。

回答by davin

In most cases you work alone and can control yourself, or on a team and there is a team guideline, or can see the code you're working with, so it shouldn't be a problem. But you can always be extra safe:

在大多数情况下,您可以单独工作并且可以控制自己,或者在团队中工作并且有团队指南,或者可以看到您正在使用的代码,所以这应该不是问题。但你总是可以更加安全:

var obj = new String("something");
typeof obj; // "object"

obj = ""+obj;
typeof obj; // "string"

Update

更新

Haven't though much about the implications of this, although it seems to work:

虽然它似乎有效:

var obj = new String("something"), obj2 = "something else";
obj.constructor === String; // true
obj2.constructor === String; // true

Of course, you should check if the object has a constructor (i.e. if it is an object).

当然,你应该检查对象是否有构造函数(即它是否是一个对象)。

So you could have:

所以你可以有:

isString(obj) {
   return typeof obj === "string" || typeof obj === "object" && obj.constructor === String;
}

Although I suggest you just use typeof and "string", a user should know to pass through a normal string literal.

虽然我建议你只使用 typeof 和“string”,但用户应该知道传递一个普通的字符串文字。

I should note this method is probably susceptible to someone creating an object and setting it's constructor to be String(which would indeed be completely obscure), even though it isn't a string...

我应该注意到这个方法可能容易受到创建对象并将它的构造函数设置为String(这确实是完全模糊的)的人的影响,即使它不是一个字符串......

回答by Sumer

Thanks All, Even after so many years this question doesn't have a precise answer.

谢谢大家,即使过了这么多年,这个问题也没有准确的答案。

JavaScript has got two type of data,

JavaScript 有两种类型的数据,

  1. Primitives :- string (let a = 'testStr'), number, boolean, null, undefined,symbol and bigint.
  2. Objects :- Everything else (Functions, Arrays, JS Objects, ....)
  1. 原语:- string (let a = 'testStr'), number, boolean, null, undefined,symbol 和 bigint。
  2. 对象:- 其他一切(函数、数组、JS 对象,....)

Its the way JS is designed for efficiency(you know JS on V8 is like rocket) that all primitives are immutable(changing a str of num creates a new variable behind the scene) and objects are mutable.

它的 JS 为效率而设计的方式(你知道 V8 上的 JS 就像火箭一样)所有原语都是不可变的(改变 num 的 str 会在幕后创建一个新变量)并且对象是可变的。

To support primitives to used like objects JS has this feature of AutoBoxing. So when we use any method (say toString() for number) with primitives, JS automatically converts it to the corresponding Object and then executes the method and converts it back to primitive. Normally we should never use the constructor(with new) and use it like a primitive only(let str = 'testStr'). Using constructor object instead of primitive might cause slow execution and complications.

为了支持像对象一样使用原语,JS 具有 AutoBoxing 的这个特性。所以当我们使用任何带有原始类型的方法(比如 toString() 表示数字)时,JS 会自动将其转换为相应的 Object,然后执行该方法并将其转换回原始类型。通常我们永远不应该使用构造函数(带有 new)并且只像原始类型一样使用它(let str = 'testStr')。使用构造函数对象而不是基元可能会导致执行缓慢和复杂化。

回答by omtester

Object.prototype.toString.call(aVariable) == '[object String]'

回答by jazmit

You can also convert a String object (along with anything else) to a String primitive with toString: var str = new String("foo"); typeof str; // object typeof str.toString(); // string

您还可以使用以下命令将 String 对象(以及其他任何内容)转换为 String 原语toStringvar str = new String("foo"); typeof str; // object typeof str.toString(); // string

回答by bartosz.r

Why do you need to check if it is string?

为什么你需要检查它是否是字符串?

Just check if it is defined or null, and otherwise defensively convert it to any type you want, either the var bar = new String(foo);or var bar = "" + foo;.

只需检查它是否已定义或为空,否则防御性地将其转换为您想要的任何类型,var bar = new String(foo);或者var bar = "" + foo;.