This question already has answers here:
What is the difference between string primitives and String objects in JavaScript?
(12 answers)
Closed 9 years ago.
What is the difference between creating a string object like this
var txt = new String("Hello World");
and this
var txt = "Heloo World";
First of all let's bust some myths. String literal is not a syntactic sugar.
> var txt = new String("Hello World");
> typeof x
"string"
> var txt2 = "Hello World";
> typeof txt2
"object"
As you can see these two things are of different type. Even more: one of them is object and the second is not. This has a practical consequence, like:
> new String("Hello World") == new String("Hello World")
false
> "Hello World" == "Hello World"
true
Another difference is that primitives are passed by value while objects by reference. This might save some memory if you are passing around lots of big strings. However both objects and literals are immutable so it really isn't a big deal (why would you pass lots of big strings if you're not going to modify them?).
Also you can add attributes to objects while you can't add them to primitive types. But that's not 100% true. You can add an attribute to the prototype of a primitive. Note that both literals and objects have the same prototype:
> String.prototype.test = 11;
> var x = new String("x");
> x.test;
11
> var y = "x":
> y.test;
11
There's very little practical use for String objects as created by new String("foo"). The only advantage a String object has over a primitive string value is that as an object it can store properties:
var str = "foo";
str.prop = "bar";
alert(str.prop); // undefined
var str = new String("foo");
str.prop = "bar";
alert(str.prop); // "bar"
Hope this helps..
The String constructor function returns an object of type String. Usually, you want a literal string value, because strictly comparing an object to a literal will always return false.
One is a string primitive and the other is a String object.
The advantage of String object over string primitive is that it can store properties
var x = "foobar"
x.y = "hello"
console.log(x.hello) /* Undefinded*/
var z = new String("foobar")
z.y = "hello"
console.log(z.y) /* hello*/
typeof x = "string"
typeof z = object.
also
x==z //true
x===z // false
Nothing much but beware of this,
var s = new String('A');
var s1 = String('A');
var s2 = 'A';
console.log(s === 'A');//fasle -- since type is Object
console.log(s1 === 'A');//true
console.log(s2 === 'A');//true
var txt = "Heloo World";
here 'txt' is a primitive data type. It has no methods, it is nothing more than a pointer to a raw data memory reference, which explains the much faster random access speed.
var txt = new String("Hello World");
If you use new, you're explicitly stating that you want to create an instance of an Object. Therefore, new String is producing an Object wrapping the String primitive, which means any action on it involves an extra layer of work.
The first returns a String object, the second returns a string.
typeof txt; //object
typeof txt2; //string
While they may act similar, txt !== txt2
The primitive data types are:
String
Number
Boolean
If you using:
var txt = "Heloo World";
this is primitive type data type alert(typeof txt); will give you string type.
In JavaScript all variable can be of object type, for each primitive their is a Object type.
var txt = new String("Heloo World");
here typeof will give you object.
For difference see jsfiddle
var str="text";
alert(typeof str); //string
var str2="text";
alert(str === str2); //true
str = new String("text changed");
alert(typeof str); //object
var str2 = new String("text changed");
alert(str === str2); //false
Nothing, really. In the first example you call the constructor of class String and put as a parameter the body of the string, where as in the second example it is done automatically at the interpretation phase.
So basically the second is syntactic sugar, where as the first isn't.
There is no difference in the functionality.
Related
In JavaScript is there any difference between using String() and new String()?
console.log(String('word')); // word
console.log(new String('word')); // word
Using the String() constructor without new gives you the string (primitive) value of the passed parameter. It's like boxing the parameter in a native object if necessary (like a Number or Boolean), and then calling .toString() on it. (Of course if you pass a plain object reference it just calls .toString() on that.)
Calling new String(something) makes a String instance object.
The results look the same via console.log() because it'll just extract the primitive string from the String instance you pass to it.
So: just plain String() returns a string primitive. new String(xyz) returns an object constructed by the String constructor.
It's rarely necessary to explicitly construct a String instance.
String() returns a string primitive and new String() returns a Object String. This has some real consequences for your code.
Using String() returns 'true' with other primitives both with == and === operator.
Using String() gives you a primitive so it cannot use the "instanceOf" method to check its type. You can check only value type with "typeof" operator
Using new String() with "instanceOf" method with String or Object prototypes - both assert to true.
Using new String() will return 'true' with string primitives only by calling valueOf() method. String() has also this method and returns true when compared to string of the same value.
Using new String() allows you to add some other properties and methods to the Object to allow more complex behaviour.
From my coding experience you should avoid using new String() if you have no need for adding special methods to your String Object.
var x = String('word');
console.log(typeof x); // "string"
var y = new String('word');
console.log(typeof y); // "object"
// compare two objects !!!
console.log(new String('') === new String('')) // false!!!
// compare with string primitive
console.log('' == String('')) // true
console.log('' === String('')) // true
//compare with string Object
console.log('' == new String('')) // true
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
console.log('' === new String('')) // false !!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// instance of behavior
console.log(x instanceof String); // false
console.log(x instanceof Object); // false
// please note that only new String() is a instanceOf Object and String
console.log(y instanceof String); // true
console.log(y instanceof Object); // true
//valueOf behavior
console.log('word' == x.valueOf()); // true
console.log('word' === x.valueOf()); // true
console.log('word' == y.valueOf()); // true
console.log('word' === y.valueOf()); // true
//create smart string
var superString = new String('Voice')
superString.powerful = 'POWERFUL'
String.prototype.shout = function () {
return `${this.powerful} ${this.toUpperCase()}`
};
console.log(superString.shout()) //"POWERFUL VOICE"
Strings returned from String calls in a non-constructor context (i.e., without using the new keyword) are primitive strings.
Strings created with new String() (constructor mode) is an object and can store property in them.
Demonstrating the difference:
var strPrimitive = String('word');
strPrimitive.prop = "bar";
console.log(strPrimitive.prop); // undefined
var strObject = new String('word');
strObject.prop = "bar";
console.log(strObject.prop); // bar
Here is an example in addition to the good answers already provided:
var x = String('word');
console.log(typeof x); // "string"
var y = new String('word');
console.log(typeof y); // "object"
The exact answer to your question is here in the documentation.
String literals (denoted by double or single quotes) and strings
returned from String calls in a non-constructor context (i.e., without
using the new keyword) are primitive strings.
Generally it's not recommended to use constructor functions (i.e. using new keyword) because it can lead to unpredictable results.
For example:
if (new Number(0)) { //
console.log('It will be executed because object always treated as TRUE in logical contexts. If you want to treat 0 as falsy value then use Number(0)')
}
Also, as mentioned above, there is another potential problem:
typeof 0; // number
typeof Number(0) // number
typeof new Number(0) // object
This question is based on previous question:
Difference in these 2 Strings (JavaScript)
The people replied that there is a difference by creating string via 2 separate ways:
String Literal creates string (var a = "abc")
new keyword creates string-object, I assume it is a kind of object (var b = new String("def"))
Now, typeof in 1st case will return string. In 2nd case it will return Object. I am okay, there might be certain way of working, of JS engine, by the people who developed it.
But, then, in the following example why the hell I am getting the answer in last line as abcdef. Now, that too should have consoled [object][object], as the line above. Now I am really confused, new String is either creating a string, or object or what? It is just NOT consistent!
Can someone help me explain?
var obj1 = new Object({name: "Peter"});
var obj2 = new Object({age: 29});
var str1 = new String("abc");
var str2 = new String("def");
console.log(obj1);
console.log(obj2);
console.log(str1);
console.log(str2);
console.log(obj1 + obj2);
console.log(str1 + str2);
new String creates a String object, which inherits from Object, but has its own .toString and .valueOf methods, so it will print the string content.
var o = new Object();
var s = new String("foo");
console.log(o.toString === s.toString); // false
console.log(o.valueOf === s.valueOf); // false
You can override them with your own to see that they're invoked. Just be sure to invoke the originals too.
var s = new String("foo");
s.valueOf = function() {
console.log("custom valueOf");
return String.prototype.valueOf.call(this);
}
s.toString = function() {
console.log("custom toString");
return String.prototype.toString.call(this);
}
console.log(s + s);
[""].join(s);
But, then, in the following example why the hell I am getting the answer in last line as abcdef. Now, that too should have consoled [object][object], as the line above.
The difference is a String object has a default valueOf method that returns the string value contained within the object.
The Object object has a more generic valueOf method which simply returns a string of [object Object]
See -
const one =
{ valueOf: _ => 1 }
const two =
{ valueOf: _ => 2 }
console.log(one + two)
// 3
You can define valueOf to be anything -
const foo =
{ valueOf: _ => "foo" }
const bar =
{ valueOf: _ => "bar" }
console.log(foo + bar)
// "foobar"
I am looking for a way to check if two variables refer to the same object in javascript.
ex:
var a = {foo:"bar"};
var b = {foo:"bar"};
var aa = a;
testSame(a, b); //false
testSame(a, aa); //true
var r = "a string";
var s = "a string";
var rr = r;
testSame(r, s); //false
testSame(r, rr); //true
So far there doesn't seem to be a way of getting a way of doing this.
edit: testSame() is not a real function it would be the hypothetical solution.
edit: The answer to the question How to check if two vars have the same reference? does not answer this question as it uses the strict equality operator (===) which does not differentiate between between 2 vars pointing to 2 instances of an identical string.
Just comparing with == or === will do the trick, except for strings. There's no way to do what you ask with strings.
var a = {foo:"bar"};
var b = {foo:"bar"};
var aa = a;
testSame(a, b); //false
testSame(a, aa); //true
var r = "a string";
var s = "a string";
var rr = r;
testSame(r, s); // false <-- this will be true
testSame(r, rr); //true
function testSame(a, b) {
console.log(a === b);
}
The question is correct, but there is a trick in it. The following console code snippet reveals it:
const A = "abc", B = new String(A), C = B
> A == B
true
> A === B
false
> B === C
true
Variable A refers integral primitive that is converted to String object on a demand. JS machine may optimize references to equal primitive strings defined in the code to target exactly the same block of RAM — that's why the question, as defined, has no solution.
You need to manually wrap each integral value to corresponding object class: String, Number, Boolean, — and test them with === operator:
var r = new String("a string");
var s = new String("a string");
var rr = r;
I've applied this trick to track the initially empty controlled input in React, — whether the user had edited it and then erased to be clear, — without involving additional field in the state.
Here's how things work. First, in this code:
var a = {foo:"bar"};
var b = {foo:"bar"};
the variables a and b are initialized with references to two different objects. Thus comparisons with either == or === will report them as being different (i.e., not equal).
Here, however:
var a = "some string";
var b = "some string";
the two variables are initialized to refer to strings that are identical. String values in JavaScript are not objects — they're primitives. Comparisons between a and b with either == or === will therefore return true because the strings are the same. This is exactly the same as things would have been if the variables had been initialized like this:
var a = 17;
var b = 17;
Numbers and strings are primitives, so comparison compares the semantic values of the primitives. Objects, however, are not primitives, and comparison of objects is based on object identity.
It literally is nonsensical in the JavaScript semantic domain to want to know whether two variables pointing to the same identical string refer to two different expressions of that same string, in precisely the same way as it would be nonsensical to want to know whether one 17 were different from another.
This one is already answered in this question:
How to check if two vars have the same reference?
The short version use === instead of ==
As I understand it, === checks the identity of the object. Javascript's strings are immutable, so when you say
var x = "string"
vay y = "string"
x and y are actually referencing the same object in memory. So, unfortunately, what you want is impossible. Symbols provide this functionality:
Symbol('x') === Symbol('x') // => false
I have an object with some properties which are String objects:
var obj = {
foo: new String("bar")
};
I am using String objects because I am needing to store additional sub-properties on the object while still being able to get the string value:
obj.foo.baz = "baz";
"" + obj.foo; //-> "bar";
I feel dumb for asking, but how can I update the value of a String object? Seems like some Array splice magic might need to be applied.
EDIT: Just to be clear, I understand string primitives in JS and immutability therein. This is an object I'm talking about. Here is the test that needs to pass:
assert.equal("" + obj.foo, "foo"); //-> true
assert.equal(obj.foo.baz, "baz"); //-> true
extend(obj, { foo: "foooooo" });
assert.equal("" + obj.foo, "foooooo"); //-> true
assert.equal(obj.foo.baz, "baz"); //-> true
You can't. Strings are immutable, regardless of how you "construct" them (literal or object).
What you should be doing is simply use an actual object to hold your values and your string.
At the most basic level this would be:
var obj = {
foo: "bar"
};
// later...
obj.baz = "baz";
"" + obj.foo; //-> "bar";
You can also consider using a monadic type as an "amplifier" / decorator, but that seems way overkill for this use case.
As a side note, adding properties and "random" functions to a string object is not a good OOP choice. These are strictly not relevant to the value that is the string, and only make sense to a higher level object, which is where they should reside.
You'd need to create a new String object and extend any new properties and values to that String object. I've provided a simple example below. That said, this example can be modified to suit your purposes (you'd create a custom extend or setter function).
Example of a property setter function
var createNewString = function (oldStringObj, string) {
var _new = new String(string);
var keys = Object.keys(oldStringObj); // returns only custom properties (not part of prototype)
for (var i=0,n=keys.length; i<n; i++){
var key = keys[i];
if (Number.isInteger(+key)) {
continue; // skip property if it's a numbered key
}
_new[key] = oldStringObj[key]; // simple assignment (not a deep copy) -- room for improvement
}
return _new;
};
Original object
var obj = {
foo: new String("bar")
};
obj.foo.baz = "baz"; // new property
Update the object
obj.foo = createNewString( obj.foo, 'foot' );
//obj.foo=='foot' and obj.foo.baz=='baz'
I suggest that you use a custom type for this, instead of the default String type. The ES6 spec defines that the underlying value for a String object is stored in its "[[StringData]] internal slot". The only place this slot is assigned is via the new String constructor, so it is implicitly immutable. You can create a new type which has the same string-like behaviours that you require, while being mutable.
class MutableString {
constructor(value) {
this.value = value;
}
toString() {
return this.value;
}
}
var obj = {
foo: new MutableString('bar')
};
obj.foo.baz = "baz";
console.assert("" + obj.foo == "bar");
console.assert(obj.foo + "" == "bar");
console.assert(obj.foo.baz == "baz");
console.assert(Object.keys({[obj.foo]: 1})[0] == "bar");
obj.foo.value = "foooooo";
console.assert("" + obj.foo == "foooooo");
console.assert(obj.foo + "" == "foooooo");
console.assert(obj.foo.baz == "baz");
console.assert(Object.keys({[obj.foo]: 1})[0] == "foooooo");
Because this isn't really a string it won't support any string methods, so it may not be suitable for your use. But it's more flexible and a little clearer, so I suggest considering it if possible.
It may be necessary to define a valueOf() method like toString() to handle some other cases, but I haven't verified.
What does the Object function in JavaScript do?
For example, what happens when we do Object(1)?
It forces something to be an object. I've not seen it being used in this way though.
var num = 1;
var obj = Object(num);
alert(typeof num); //displays "number"
alert(typeof obj): //displays "object"
alert(num + "," + obj); //displays "1,1"
The preferred, faster way to create an empty object on which you can put properties and methods on is by using {}. Three possible ways to create an object:
var emptyObj = {};
var emptyObj = new Object();
var emptyObj = new Object; // Object does not need an argument, so this is valid.
From the Mozilla developer site:
The Object constructor creates an object wrapper for the given value. If the value is null or undefined, it will create and return an empty object, otherwise, it will return an object of type that corresponds to the given value.
When called in a non-constructor context, Object behaves identically.
So Object(1) produces an object that behaves similarly to the primitive value 1, but with support for object features like assigning values to properties (Object(1).foo = 2 will work, (1).foo = 2 will not).
var obj = Object("test");
Creates a String "text", it's pretty similar to
var obj2 = "test";
Notice that the type of obj2 is "String" and of obj1 "Object"
Try this:
<script>
var obj = Object("test");
console.log(obj);
console.log(typeof(obj));
console.log(obj["0"]);
obj2 = "test";
console.log(obj2);
console.log(typeof(obj2));
console.log(obj2["0"]);
</script>
Creates an object http://www.w3schools.com/js/js_objects.asp
Object function is a constructor function, all other types(like Array, String, Number) inheritate it.