Какая точка нового String ( "x" ) в JavaScript?
Каковы варианты использования new String("already a string")
?
Что все это значит?
Ответы
Ответ 1
Практически не используется для объектов 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;
Если значение, которое вы проверяете, может быть любым объектом, ваши параметры следующие:
-
Не волнуйтесь о объектах String и просто используйте typeof. Это была бы моя рекомендация.
typeof str == "string"
.
-
Использовать instanceof, а также typeof. Обычно это работает, но имеет недостаток в возврате ложного отрицательного значения для объекта String, созданного в другом окне.
typeof str == "string" || str instanceof String
-
Используйте утиную печать. Проверьте наличие одного или нескольких методов, специфичных для String, таких как substring() или toLowerCase(). Это явно неточно, так как оно вернет ложный положительный результат для объекта, у которого есть метод с именем, которое вы проверяете, но в большинстве случаев оно будет достаточно хорошим.
typeof str == "string" || typeof str.substring == "function"
Ответ 2
Создатели Javascript создавали обертки для базовых типов, таких как string или int, чтобы сделать их похожими на java. К сожалению, если кто-то создает новый String ( "x" ), тип элемента будет "объектом", а не "строкой".
var j = new String("x");
j === "x" //false
j == "x" //true
Ответ 3
Вы можете использовать instanceof
, если вы действительно хотите быть параноидальным:
if(typeof x === "string" || x instanceof String)
Оператор instanceof
будет корректно обрабатывать также подклассы String:
obj instanceof ConstructorFunction
работает, проверяя, находится ли ConstructorFunction.prototype
в цепочке прототипов obj
.
Я не думаю, что когда-либо использовал класс String в JavaScript, но нет ничего плохого в том, чтобы быть параноидальным и стремиться к правильности.
Ответ 4
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
Ответ 5
В большинстве случаев вы работаете в одиночку и можете контролировать себя или в команде, а также руководство для команды или можете видеть код, с которым работаете, поэтому это не должно быть проблемой. Но вы всегда можете быть в безопасности:
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
(который действительно был бы полностью неясным), хотя это не строка...
Ответ 6
Object.prototype.toString.call(aVariable) == '[object String]'
Ответ 7
Зачем вам нужно проверить, является ли это строкой?
Просто проверьте, не определено ли это или нет, и в противном случае защитите его до любого типа, который вы хотите, либо var bar = new String(foo);
, либо var bar = "" + foo;
.
Ответ 8
Вы также можете преобразовать объект String (вместе с чем-либо еще) в примитив String с помощью toString
:
var str = new String("foo");
typeof str; // object
typeof str.toString(); // string