JavaScript 中 new String("x") 的意义何在?

Posted

技术标签:

【中文标题】JavaScript 中 new String("x") 的意义何在?【英文标题】:What's the point of new String("x") in JavaScript? 【发布时间】:2011-08-10 16:12:33 【问题描述】:

new String("already a string")的用例是什么?

它的全部意义是什么?

【问题讨论】:

【参考方案1】:

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

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

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

更新

虽然它似乎有效,但对它的影响并没有太多了解:

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

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

所以你可以:

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

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

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

【讨论】:

那么检查变量是否为字符串的最佳方法是什么? 仅仅检查constructor 属性是不够的。 javascript 中的 String 子类可能会有奇怪的人。 @mu 太短了,是的,你说得有道理,虽然我想到了 instanceof,但看起来 OP 只是试图区分对象、字符串文字和 new String('blah')。无论如何,想法就在那里,我们可以整天挑剔。 我只是觉得你应该在迂腐中走一半,如果你要迂腐那就一路走:)【参考方案2】:

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"

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

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

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

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

    typeof str == "string".

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

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

    使用duck typing。检查是否存在一个或多个特定于字符串的方法,例如 substring() 或 toLowerCase()。这显然是不精确的,因为它会返回一个误报的对象,该对象恰好有一个与您正在检查的名称相同的方法,但在大多数情况下它已经足够了。

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

【讨论】:

我正在创建一个在其构造函数中接受参数的类。但此参数由用户提供。如果参数是字符串,构造函数将执行某些操作,如果参数不是字符串,则构造函数将执行其他操作,所以我想知道是否有一种方法可以确定参数是否为字符串(由用户提供)。我不能使用 str = "" + str 因为我不能假设参数将只是一个“真实”字符串或字符串对象..它可能是其他一些对象跨度> @Pacerier: “这个参数是用户提供的” - 它是如何提供的?用户是谁?我真的不会担心这个,但我会用选项更新我的答案。 第一句话就说明了一切。 str = "" + str;everything 转换为字符串。如果您只想将 String 对象转换为字符串(以及将 Number 对象转换为数字等),而不管其他事情,您可以编写 str = str.valueOf() console.log(new String('abc')) 没有输出任何东西,为什么??【参考方案3】:

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

var j = new String("x"); j === "x" //假 j == "x" //真

【讨论】:

我真的很喜欢这个答案。【参考方案4】:

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

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

instanceof operator 也能正确处理 String 的子类:

obj instanceof ConstructorFunction 的工作原理是检查 ConstructorFunction.prototype 是否在 obj 的原型链中。

我认为我实际上从未在 JavaScript 中使用过 String 类,但偏执并以正确为目标并没有错。

【讨论】:

【参考方案5】:
Object.prototype.toString.call(aVariable) == '[object String]'

【讨论】:

【参考方案6】:

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

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

【讨论】:

【参考方案7】:

您还可以使用toString 将 String 对象(以及其他任何东西)转换为 String 原语: var str = new String("foo"); typeof str; // object typeof str.toString(); // string

【讨论】:

【参考方案8】:

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

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

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

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

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

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

或指定参数目的:

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];
    

或跟踪对象:

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;

String 对象和字符串原语的存在有效地为您提供了 Javascript 中具有不同行为和用途的两种字符串“类型”。这也适用于 BooleanNumber 对象及其各自的原语。

但是,当使用函数方法bind()call()apply() 时,请注意将字符串(或其他)原语作为this 的值传递,因为该值将被转换为String对象(或BooleanNumber 对象,取决于原语)在用作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;

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

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

【讨论】:

【参考方案9】:

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

JavaScript 有两种类型的数据,

    基元:- 字符串(让 a = 'testStr')、数字、布尔值、空值、未定义、符号和大整数。 对象:- 其他一切(函数、数组、JS 对象……)

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

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

【讨论】:

以上是关于JavaScript 中 new String("x") 的意义何在?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 中 new String("x") 的意义何在?

JavaScript String 对象

JavaScript 中 Date() 和New Date()有啥区别?

JavaScript:String 和 Array 上 indexOf 方法的效率差异

JavaScript学习-js中的数组/Boolean类/字符串String类

前端之路——JavaScript基础