Какой смысл новой строки ("х") в JavaScript? - PullRequest
34 голосов
/ 22 апреля 2011

Каковы варианты использования для new String("already a string")?

В чем весь смысл?

Ответы [ 8 ]

46 голосов
/ 22 апреля 2011

Практически нет практического применения для 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. Использовать Утка набрав . Проверьте наличие одного или нескольких специфичных для String методов, таких как substring () или toLowerCase (). Это явно неточно, так как он возвратит ложное срабатывание для объекта, который, как оказалось, имеет метод с проверяемым именем, но в большинстве случаев он будет достаточно хорош.

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

16 голосов
/ 22 апреля 2011

Создатели Javascript создали обертки для базовых типов, таких как string или int, просто чтобы сделать их похожими на java.К сожалению, если кто-то создаст новую строку («x»), тип элемента будет «объект», а не «строка».

var j = new String("x");
j === "x"  //false
j == "x" //true
6 голосов
/ 24 августа 2016

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 с различным поведением и, следовательно, их использованием.Это относится и к Boolean и Number объектам и их соответствующим примитивам.

Однако остерегайтесь передачи строковых (или других) примитивов в качестве значения 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;

И неожиданные / нелогичные типы возврата:

var aStringObject=new String("I'm a String object");
console.log(typeof aStringObject); //--> object
aStringObject=aStringObject.toUpperCase();
console.log(typeof aStringObject); //--> string
3 голосов
/ 22 апреля 2011

Вы можете использовать instanceof, если вы действительно хотите быть параноиком:

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

Оператор instanceof также будет правильно обрабатывать подклассы String:

obj instanceof ConstructorFunction работает, проверяя, находится ли ConstructorFunction.prototype в цепочке прототипов obj.

Я не думаю, что когда-либо использовал класс String в JavaScript, но нет ничего плохого в том, чтобы быть параноиком и стремиться к правильности.

1 голос
/ 22 апреля 2011

В большинстве случаев вы работаете в одиночку и можете контролировать себя, или в команде, и есть руководство для команды, или можете видеть код, с которым работаете, так что это не должно быть проблемой. Но вы всегда можете быть в большей безопасности:

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 (которое действительно будет совершенно неясным), даже если это не строка ...

0 голосов
/ 08 февраля 2015

Вы также можете преобразовать объект String (вместе со всем остальным) в примитив String с помощью toString: var str = new String("foo"); typeof str; // object typeof str.toString(); // string

0 голосов
/ 26 января 2012

Зачем вам нужно проверять, является ли оно строкой?

Просто проверьте, определено ли оно или имеет значение null, и в противном случае защитно преобразуйте его в любой тип, который вы хотите, либо var bar = new String(foo);, либо var bar = "" + foo;.

0 голосов
/ 22 апреля 2011
Object.prototype.toString.call(aVariable) == '[object String]'
...