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