Watching a tutorial today I came across the following:
var q2Var1 = "hi there.",
q2Var2 = String( "another string here." );
Is q2Var the "constructor notation" and q2Var the "literal notation" for declaring a variable, or am I not drawing the correct conclusion?
Thank you.
No, neither of those use a constructor to create a string object.
The first is just a string primitive, the second is a string primitive that is sent through the String conversion function, which will just return the string primitive unchanged.
The String conversion function is usually used to turn other things into string primitives, for example a number:
var s = String(42);
To create a String object you use the new keyword:
var s = new String("hi there.");
The String object has all the methods that you are used to use on a string, like the length property. The reason that you can use them on string primitives also, is that they are automatically converted to String objects when you use a method on them.
So, this:
var l = "asdf".length;
actually does the same as:
var l = new String("asdf").length;
The String conversion function always returns a string primitive, so if you have a String object, the function will turn it back into a string primitive:
var s = "asdf"; // typeof s returns "string"
var s = new String(s); // typeof s now returns "object"
s = String(s); // typeof s now returns "string"
I never heard those names before, but 'constructor notation' would most likely be the q2Var2 one, since you're passing arguments to the constructor of String. It's not really important how you call them though, is it? :P
Related
Do this:
var x = Object('abc');
now just type x in the console and click enter. It will output:
String {0: "2", 1: "3", 2: "2", 3: "3",....}
now type typeof x, you will get object.
What's happening here?
The Object constructor returns an instance of an object whose type is appropriate to the passed-in value. In your case, you pass in a string primitive value, so you get a String object back. (Note that in JavaScript string primitive values and String instances are two different kinds of values. It can be hard to tell because JavaScript automatically wraps string primitives in String wrappers when circumstances require it.)
The typeof operator returns "object" for String instances.
var x = "";
is a primitive type String.
var x = Object('abc');
is an Object String.
Check the Type section for more :
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
In JavaScript a String is a primitive value.
But is also a String object...
A primitive value is a value put directly into a variable.
So my question is:
var d = "foo";
does d contain directly foo or a reference to a string object like other languages?
Thanks.
If I understand it correctly, d will contain the string literal "foo", and not a reference to an object. However, the JavaScript engine will effectively cast the literal to an instance of String when necessary, which is why you can call methods of String.prototype on string literals:
"some string".toUpperCase(); //Method of String.prototype
The following snippet from MDN may help to explain it further (emphasis added):
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. JavaScript automatically
converts primitives and String objects, so that it's possible to use
String object methods for primitive strings. In contexts where a
method is to be invoked on a primitive string or a property lookup
occurs, JavaScript will automatically wrap the string primitive and
call the method or perform the property lookup.
This is all explained in detail in the specification, but it's not exactly easy reading. I asked a related question recently (about why it is possible to do the above), so it might be worth reading the (very) detailed answer.
if you define
var d = "foo";
than d contains directly foo
but, if you define
var S = new String("foo");
then S is an Object
Example:
var s1 = "1";
var s2 = "1";
s1 == s2 -> true
var S1 = new String("2");
var S2 = new String("2");
S1 == S2 -> false
I think that every variable in Javascript actually represents an Object. Even a function is an Object.
I found two useful articles detailing this, located here and here. Seems like primitive types in JavaScript are passed by VALUE (i.e. when you pass if to a function it gets "sandboxed" within the function and the original variable's value won't change), while reference types are passed, you guessed it, by REFERENCE and passing it through to a function will change the original variable.
Primitive types in JavaScript are text (string), numeric (float / int), boolean and NULL (and the dreaded "undefined" type). Any custom objects, functions or standard arrays are considered reference types. I haven't researched the Date type though, but I'm sure it will fall into the primitive types.
Found this page about javascript variables, seems that:
Primitive type for javascript are booleans, numbers and text.
I believe there are no primitives in Javascript, in the Java sense at least - everything is an object of some kind.
So yes it is a reference to an object - if you extend the String object, d would have that extension.
If you mean primitives as in those types provided by the language, you've got a few, boolean, numbers, strings and dates are all defined by the language.
This question already has answers here:
How is a Javascript string not an object?
(2 answers)
Closed 7 years ago.
Here are two reasons to think strings are objects. First, you can create a string in the following way:
var mystring = new String("asdf");
I'm under the impression that the constructor function following the new operator has to return an object. Second, strings seem to have properties and methods. For example:
mystring.toUpperCase();
BUT, if strings were objects, then we'd expect something like the following to work:
function string_constructor() {
return "asdf";
}
var mystring = new string_constructor();
But it doesn't, and I've been told it doesn't because strings aren't objects. So are strings objects or not? And, either way, how can I make sense of everything I've listed?
Speaking about language types, Strings are values of the String type.
The language has five primitive types, which are String, Number, Boolean, Null and Undefined.
There are String objects (also for Number or Boolean), they are called primitive wrappers, they are created when you use the constructor function associated with them, for example:
typeof new String('foo'); // "object"
typeof 'foo'; // "string"
But don't get confused with them, you will rarely need to use primitive wrappers, because even if primitive values are not objects, you can still access their inherited properties, for example, on a string, you can access all members of String.prototype, e.g.:
'foo'.indexOf('o'); // 2
That's because the property accessor (the dot in this case) temporarily converts the primitive value to an object, for being able to resolve the indexOf property up in the prototype chain.
About the constructor function you have in your question, as you know, it won't return the string.
Functions called with the new operator return an implicit value, which is a new object that inherits from that function's prototype, for example:
function Test () {
// don't return anything (equivalent to returning undefined)
}
new Test() instanceof Test; // true, an object
If an object is returned from the constructor, that newly created object (this within the constructor) will be lost, so the explicit returned object will come out the function:
function Test2() {
return {foo: 'bar'};
}
new Test2().foo; // 'bar'
But in the case of primitive values, they are just ignored, and the new object from the constructor is implicitly returned (for more details check the [[Construct]] internal operation, (see step 9 and 10)).
In JavaScript, strings come in two flavors:
There is a String language type which contains values like "foo" and 'bar'. Those values are primitive values. Read about the String type here
Then there is a String constructor. (A constructor is a function object which is used to create new instances of a certain "class" (or pseudo-class)). So this: new String("foo")
will create a new object (a value of the type Object), which contains the primitive value "foo". Read about the String constructor here
In practice you don't use the new String('foo') notation, but the string literal notation 'foo'.
So to answer your question:
In JavaScript, strings are not objects. They are primitive values. However, there exist String objects which can be used to store string values, but those String objects are not used in practice.
Primitive strings behaves like objects in JavaScript because they are automatically converted to objects when you call an object method:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String
String objects may be created by
calling the constructor new String().
The String object wraps JavaScript's
string primitive data type with the
methods described below. The global
function String() can also be called
without new in front to create a
primitive string. String literals in
JavaScript are primitive strings.
Because JavaScript automatically
converts between string primitives and
String objects, you can call any of
the methods of the String object on a
string primitive. JavaScript
automatically converts the string
primitive to a temporary String
object, calls the method, then
discards the temporary String object.
For example, you can use the
String.length property on a string
primitive created from a string
literal
String are both primitive and object type. Think about int, float, char ... which have real Object classes like Integer, Float and Char in Java.
String is a wrapper around the primitive string datatype. When you do something like var s = "My String" then a String wrapper object is created behind the scenes when needed..
It is interesting however that typeof s = 'string' instead of 'object'. Anybody know why that is?
Strings are objects, but what you are doing in your example is not creating a new String. By using 'new' you are creating an instance of a Object, not a 'string'
var F = function() {
return 'c';
};
var a = new String('a');
var b = 'b';
var c = new F();
alert("a is: " + typeof a + ", b is: " + typeof b + ", c is: " + typeof c);
// alerts: a is: object, b is: string. c is: object
You shouldn't use 'new' for strings regardless (or arrays, or 'simple' objects.)
If I create a String Object by using say,
var temp = new String('ABCD');
Does this creates a memory space for this String object, like Objects in JavaScript? If yes, can I release this object just by assigning this variable 'temp' to null i.e. temp = null?
Does this creates a memory space for this String Object, like Objects in Javascript?
String objects are Objects.
If yes, can I release this object just by assigning this variable 'temp' to null i.e. temp = null ?
Garbage collection works as normal.
Of course, The JavaScript runtime will need to store this String object in memory. Assigning null to the variable might free the memory if the string isn't referenced anymore and if the garbage collector decides to free the memory.
There is no apparent use of creating a string using the constructor (Wrapper Object) unless you intend to check the [[Class]] property, and if your so interested in memory optimization use the primitive type temp = "ABCD"
And yes it takes space in memory, and when you assign null to the variable, and there is no other reference to the string it is collected by the Garbage collecter. But why do want to do that? (null is an object too)
You can use delete temp to delete the variable, hence the string is garbage collected
To answer the question, JS is garbage collected, so there's no need to release memory. If you have a really gigantic string that you're only referencing from one place, setting that reference to null will release that string in the garbage collection pass.
Since you asked about new String() specifically, it's worth mentioning that it's generally considered bad because of two problems:
The string created can't be compared with the equals operator
typeof yields 'object' instead of 'string'
Here's some code you can run to see the behavior
var a = new String('hello'), b = new String('hello');
var strA = String('hello'), strB = String('hello');
var literalA = 'hello', literalB = 'hello';
// Outputs false, because the string is wrapped by an object,
// it's not the primitive
console.log( a == b );
// Proof that it's not the primitive string, outputs 'object'
console.log(typeof a);
// Using String() and the literal yield consistent results
console.log( strA == strB); //outputs true
conole.log( literalA == literalB); // outputs true
console.log( typeof strA); // outputs 'string'
console.log( typeof literalA ); // outputs 'string'
// You can compare literal and string from String(xxxx)
console.log( strA == literalA)
If you're stuck with a string that you don't know how it was created, you can always use valueOf() to compare them. That is
console.log(a.valueOf() == b.valueOf()); // outputs true;
To properly detect that an object is a string, you can check the constructor property.
console.log(a.constructor == String); // outputs true
Just beware that if you're working with frames, popups, iframes, there is a different String constructor for each window object, that is,
// outputs false
console.log( window.frames.frameA.String == window.frames.frameB.String)
Is Object the base class of all objects in Javascript, just like other language such as Java & C#?
I tried below code in Firefox with Firebug installed.
var t = new Object();
var s1 = new String('str');
var s2 = 'str';
console.log(typeof t);
console.log(typeof s1);
console.log(typeof s2);
The console output is
object
object
string
So, s1 and s2 are of diffeent type?
Yes, 'str' is a string literal, not a string object.
A string literal has access to all of a string's objects and methods because javascript will temporarily cast a string literal as a string object in order to run the desired method.
Finally:
Where the two differ is their treatment of new properties and methods. Like all Javascript Objects you can assign properties and methods to any String object. You can not add properties or methods to a string literal. They are ignored by the interpreter.
Read up more here.
The process is called boxing/unboxing.
This means that whenever the interpreter/compiler sees a primitive type used as an Object then it will use
new Object([primitive])
to get a valid instance. And in the same way, as soon as you try to use it as a primitive (as in an expression) it will use
[boxedobject].valueOf()
to get the primitive.
In ECMAScript (javascript) the constructor of Object is able to box all primitives.
Read this: http://skypoetsworld.blogspot.com/2007/11/javascript-string-primitive-or-object.html
and this: https://developer.mozilla.org/en/JavaScript/Glossary#primitive
and this: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String