JavaScript中新String(“x”)的重点是什么?

时间:2011-04-21 22:57:06

标签: javascript string types instanceof typeof

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

它的重点是什么?

9 个答案:

答案 0 :(得分:45)

String创建的new 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;

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

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

    typeof str == "string"

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

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

  3. 使用duck typing 。检查是否存在一个或多个特定于String的方法,例如substring()或toLowerCase()。这显然是不精确的,因为它会为碰巧有一个带有你正在检查的名称的方法的对象返回误报,但在大多数情况下它会足够好。

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

答案 1 :(得分:15)

Javascript创建者为string或int等基本类型创建了包装器,以使其与java类似。不幸的是,如果someome创建了新的String(“x”),那么元素的类型将是“object”而不是“string”。

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

答案 2 :(得分:6)

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个对象及其各自的原语。

请注意,在使用函数方法thisbind()call()作为值时,将字符串(或其他)基元作为apply()的值传递在用作String之前,将转换为Boolean对象(或Numberthis对象,具体取决于原语):

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

答案 3 :(得分:3)

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

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

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

  

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

我不认为我曾经在JavaScript中实际使用过String类,但是对于偏执和瞄准正确性并没有错。

答案 4 :(得分: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(这确实是完全模糊的),即使它不是一个字符串......

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

谢谢,即使经过这么多年,这个问题也没有确切的答案。

JavaScript有两种类型的数据,

  1. 原语:-字符串(让a ='testStr'),数字,布尔值,null,未定义,符号和bigint。
  2. 对象:-其他所有内容(函数,数组,JS对象等)

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

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