Taken from MDN
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 to 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.
So, I thought (logically) operations (method calls) on string primitives should be slower than operations on string Objects because any string primitive is converted to string Object (extra work) before the method being applied on the string.
But in this test case, the result is opposite. The code block-1 runs faster than the code block-2, both code blocks are given below:
code block-1 :
var s = '0123456789';
for (var i = 0; i < s.length; i++) {
s.charAt(i);
}
code block-2 :
var s = new String('0123456789');
for (var i = 0; i < s.length; i++) {
s.charAt(i);
}
The results varies in browsers but the code block-1 is always faster. Can anyone please explain this, why the code block-1 is faster than code block-2.
JavaScript has two main type categories, primitives and objects.
var s = 'test';
var ss = new String('test');
The single quote/double quote patterns are identical in terms of functionality. That aside, the behaviour you are trying to name is called auto-boxing. So what actually happens is that a primitive is converted to its wrapper type when a method of the wrapper type is invoked. Put simple:
var s = 'test';
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.
So what happens when you do s.charAt(i) for instance?
Since s is not an instance of String, JavaScript will auto-box s, which has typeof string to its wrapper type, String, with typeof object or more precisely s.valueOf(s).prototype.toString.call = [object String].
The auto-boxing behaviour casts s back and forth to its wrapper type as needed, but the standard operations are incredibly fast since you are dealing with a simpler data type. However auto-boxing and Object.prototype.valueOf have different effects.
If you want to force the auto-boxing or to cast a primitive to its wrapper type, you can use Object.prototype.valueOf, but the behaviour is different. Based on a wide variety of test scenarios auto-boxing only applies the 'required' methods, without altering the primitive nature of the variable. Which is why you get better speed.
This is rather implementation-dependent, but I'll take a shot. I'll exemplify with V8 but I assume other engines use similar approaches.
A string primitive is parsed to a v8::String object. Hence, methods can be invoked directly on it as mentioned by jfriend00.
A String object, in the other hand, is parsed to a v8::StringObject which extends Object and, apart from being a full fledged object, serves as a wrapper for v8::String.
Now it is only logical, a call to new String('').method() has to unbox this v8::StringObject's v8::String before executing the method, hence it is slower.
In many other languages, primitive values do not have methods.
The way MDN puts it seems to be the simplest way to explain how primitives' auto-boxing works (as also mentioned in flav's answer), that is, how JavaScript's primitive-y values can invoke methods.
However, a smart engine will not convert a string primitive-y to String object every time you need to call a method. This is also informatively mentioned in the Annotated ES5 spec. with regard to resolving properties (and "methods"¹) of primitive values:
NOTE The object that may be created in step 1 is not accessible outside of the above method. An implementation might choose to avoid the actual creation of the object. [...]
At very low level, Strings are most often implemented as immutable scalar values. Example wrapper structure:
StringObject > String (> ...) > char[]
The more far you're from the primitive, the longer it will take to get to it. In practice, String primitives are much more frequent than StringObjects, hence it is not a surprise for engines to add methods to the String primitives' corresponding (interpreted) objects' Class instead of converting back and forth between String and StringObject as MDN's explanation suggests.
¹ In JavaScript, "method" is just a naming convention for a property which resolves to a value of type function.
In case of string literal we cannot assign properties
var x = "hello" ;
x.y = "world";
console.log(x.y); // this will print undefined
Whereas in case of String Object we can assign properties
var x = new String("hello");
x.y = "world";
console.log(x.y); // this will print world
String Literal:
String literals are immutable, which means, once they are created, their state can't be changed, which also makes them thread safe.
var a = 's';
var b = 's';
a==b result will be 'true' both string refer's same object.
String Object:
Here, two different objects are created, and they have different references:
var a = new String("s");
var b = new String("s");
a==b result will be false, because they have different references.
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.
typeof new String(); // "object"
typeof ''; // "string"
As they are of different types, your JavaScript interpreter may also optimise them differently, as mentioned in comments.
When you declare:
var s = '0123456789';
you create a string primitive. That string primitive has methods that let you call methods on it without converting the primitive to a first class object. So your supposition that this would be slower because the string has to be converted to an object is not correct. It does not have to be converted to an object. The primitive itself can invoke the methods.
Converting it to an full-blown object (which allows you to add new properties to it) is an extra step and does not make the string oeprations faster (in fact your test shows that it makes them slower).
I can see that this question has been resolved long ago, there is another subtle distinction between string literals and string objects, as nobody seems to have touched on it, I thought I'd just write it for completeness.
Basically another distinction between the two is when using eval. eval('1 + 1') gives 2, whereas eval(new String('1 + 1')) gives '1 + 1', so if certain block of code can be executed both 'normally' or with eval, it could lead to weird results
The existence of an object has little to do with the actual behaviour of a String in ECMAScript/JavaScript engines as the root scope will simply contain function objects for this. So the charAt(int) function in case of a string literal will be searched and executed.
With a real object you add one more layer where the charAt(int) method also are searched on the object itself before the standard behaviour kicks in (same as above). Apparently there is a surprisingly large amount of work done in this case.
BTW I don't think that primitives are actually converted into Objects but the script engine will simply mark this variable as string type and therefore it can find all provided functions for it so it looks like you invoke an object. Don't forget this is a script runtime which works on different principles than an OO runtime.
The biggest difference between a string primitive and a string object is that objects must follow this rule for the == operator:
An expression comparing Objects is only true if the operands reference
the same Object.
So, whereas string primitives have a convenient == that compares the value, you're out of luck when it comes to making any other immutable object type (including a string object) behave like a value type.
"hello" == "hello"
-> true
new String("hello") == new String("hello") // beware!
-> false
(Others have noted that a string object is technically mutable because you can add properties to it. But it's not clear what that's useful for; the string value itself is not mutable.)
The code is optimized before running by the javascript engine.
In general, micro benchmarks can be misleading because compilers and interpreters rearrange, modify, remove and perform other tricks on parts of your code to make it run faster.
In other words, the written code tells what is the goal but the compiler and/or runtime will decide how to achieve that goal.
Block 1 is faster mainly because of:
var s = '0123456789'; is always faster than
var s = new String('0123456789');
because of the overhead of object creation.
The loop portion is not the one causing the slowdown because the chartAt() can be inlined by the interpreter.
Try removing the loop and rerun the test, you will see the speed ratio will be the same as if the loop were not removed. In other words, for these tests, the loop blocks at execution time have exactly the same bytecode/machine code.
For these types of micro benchmarks, looking at the bytecode or machine code wil provide a clearer picture.
we can define String in 3-ways
var a = "first way";
var b = String("second way");
var c = new String("third way");
// also we can create using
4. var d = a + '';
Check the type of the strings created using typeof operator
typeof a // "string"
typeof b // "string"
typeof c // "object"
when you compare a and b var
a==b ( // yes)
when you compare String object
var StringObj = new String("third way")
var StringObj2 = new String("third way")
StringObj == StringObj2 // no result will be false, because they have different references
In Javascript, primitive data types such is string is a non-composite building block. This means that they are just values, nothing more:
let a = "string value";
By default there is no built-in methods like toUpperCase, toLowerCase etc...
But, if you try to write:
console.log( a.toUpperCase() ); or console.log( a.toLowerCase() );
This will not throw any error, instead they will work as they should.
What happened ?
Well, when you try to access a property of a string a Javascript coerces string to an object by new String(a); known as wrapper object.
This process is linked to concept called function constructors in Javascript, where functions are used to create new objects.
When you type new String('String value'); here String is function constructor, which takes an argument and creates an empty object inside the function scope, this empty object is assigned to this and in this case, String supplies all those known built in functions we mentioned before. and as soon as operation is completed, for example do uppercase operation, wrapper object is discarded.
To prove that, let's do this:
let justString = 'Hello From String Value';
justString.addNewProperty = 'Added New Property';
console.log( justString );
Here output will be undefined. Why ?
In this case Javascript creates wrapper String object, sets new property addNewProperty and discards the wrapper object immediately. this is why you get undefined. Pseudo code would be look like this:
let justString = 'Hello From String Value';
let wrapperObject = new String( justString );
wrapperObject.addNewProperty = 'Added New Property'; //Do operation and discard
Related
I read this a lot in many JavaScript introductions. I just don't understand it. I always think of objects as something with methods and properties.
Arrays I understand, since it has key value pair.
How about "Strings" or "Numbers" or "functions" ?
These things above listed seem to be like functions to me. This means you input something, you get something out. You don't really get the access properties or anything. There's no dot notation used in arrays or this list of "objects".
Does anyone code some examples of each of these with dot notations which its methods and properties are being accessed? I suspect that definition of object is probably limited since I did start learning about JavaScript...
No, not everything is an object in JavaScript. Many things that you interact with regularly (strings, numbers, booleans) are primitives, not objects. Unlike objects, primitive values are immutable. The situation is complicated by the fact that these primitives do have object wrappers (String, Number and Boolean); these objects have methods and properties while the primitives do not, but the primitives appear to have methods because JavaScript silently creates a wrapper object when code attempts to access any property of a primitive.
For example, consider the following code:
var s = "foo";
var sub = s.substring(1, 2); // sub is now the string "o"
Behind the scenes, s.substring(1, 2) behaves as if it is performing the following (approximate) steps:
Create a wrapper String object from s, equivalent to using new String(s)
Call the substring() method with the appropriate parameters on the String object returned by step 1
Dispose of the String object
Return the string (primitive) from step 2.
A consequence of this is that while it looks as though you can assign properties to primitives, it is pointless because you cannot retrieve them:
var s = "foo";
s.bar = "cheese";
alert(s.bar); // undefined
This happens because the property is effectively defined on a String object that is immediately discarded.
Numbers and Booleans also behave this way. Functions, however, are fully-fledged objects, and inherit from Object (actually Object.prototype, but that's another topic). Functions therefore can do anything objects can, including having properties:
function foo() {}
foo.bar = "tea";
alert(foo.bar); // tea
That’s right: in JavaScript, almost everything is an object. But these objects are bit different from what we see in Java, C++ or other conventional languages. An object in JS is simply a hashmap with key–value pairs. A key is always a string or a symbol, and a value can be anything including strings, integers, booleans, functions, other objects etc. So I can create a new object like this:
var obj = {}; // This is not the only way to create an object in JS
and add new key–value pairs into it:
obj['message'] = 'Hello'; // You can always attach new properties to an object externally
or
obj.message = 'Hello';
Similarly, if I want to add a new function to this object:
obj['showMessage'] = function(){
alert(this['message']);
}
or
obj.showMessage = function() {
alert(this.message);
}
Now, whenever I call this function, it will show a pop-up with a message:
obj.showMessage();
Arrays are simply those objects which are capable of containing lists of values:
var arr = [32, 33, 34, 35]; // One way of creating arrays in JS
Although you can always use any object to store values, but arrays allow you to store them without associating a key with each of them. So you can access an item using its index:
alert(arr[1]); // This would show 33
An array object, just like any other object in JS, has its properties, such as:
alert(arr.length); // This would show 4
For in-depth detail, I would highly recommend John Resig’s Pro JavaScript Techniques.
The sentence "In JavaScript, ALMOST everything is an object" is correct, because the MAIN code-units (objects, functions, arrays) are JavaScript-objects.
JavaScript code uses 9 different-units plus 1 (multiple):
- 01. array
- 02. boolean
- 03. function
- 04. null
- 05. number
- 06. object
- 07. regexp
- 08. string
- 09. undefined
- 10. multiple
BUT JavaScript-objects:
- are NOT same creatures as the 'objects' in other object-oriented-languages.
- they are a collection of name-value-pairs.
- all have a function of creation (its constructor).
- all INHERIT the members of the prototype-object of its constructor and this is its prototype.
- all functions are objects BUT NOT all objects are functions.
- functions have scope, objects NOT (a design flaw in my opinion).
- Object, Function, Array, String, ... with first CAPITAL are functions!!!
- it is more important the differences of JS objects and functions, than its commonnesses.
- the name 'instance' in JS has different meaning with the name 'instance' in knowledge-theory where an instance inherits the attributes of its generic-concept. In JS denotes only its constructor. JavaScript got the name 'instance' from 'class-based-inheritance' ool (java) where it is an appropriate name because those objects inherit the attributes of classes.
A better name for the JS-keyword 'instanceof' is 'objectof'.
JS-functions ARE JS-objects because:
1) they can have members like JS-objects:
> function f(){}
undefined
> f.s = "a string"
"a string"
> f.s
"a string"
2) they have a constructor-function, like all JS-objects, the Function function:
> (function f(){}) instanceof Function
true
3) as all JS-objects, their prototype-object is the same with its constructor prototype:
> (function f(){}).__proto__ === Function.prototype
true
> ({}).__proto__ === Object.prototype
true
> (new Object).__proto__ === Object.prototype
true
4) of course, JS-functions as SPECIFIC JS-objects have and extra attributes, like all functions in programming-languages, that JS-objects do not have like you can call (execute) them with input and output information.
EVERYTHING is NOT an object, because, for example, we can NOT add members to a literal string:
> var s = "string"
undefined
> s.s2 = "s2string"
"s2string"
> s.s2
undefined
Based on developer.mozilla.org and also ECMAScript specification the answer is no. Technically not everything is object.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive
In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 7 primitive data types: string, number, bigint, boolean, null, undefined, symbol
A primitive is not an object and has no methods and It is also immutable. Except for null and undefined, all the other primitive have a wrap object around them to provide you some functions that you can use. For example String for the string primitive.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
So here in the following code when you call toUpperCase() on a primitive data name JavaScript will automatically wrap the string primitive and call toUpperCase function of String object
var name = 'Tom';
console.log(name);
name.toUpperCase();
console.log(name);
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.
Also note that JavaScript distinguishes between String objects and primitive string values.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects
var nameP = 'Tom';
var nameO = new String(nameP);
typeof nameP // "string"
typeof nameO // "object"
Not everything is an object in javaScript. JavaScript has primitives and objects.
There are six primitives-null,undefined,string,number,boolean and symbol.
It might seem like everything is acting as an object because of the properties and function that can be accessed.for example-
var stringvar="this string";
typeof stringvar; // "string"
stringvar.length; //11
now since "stringvar" is a string type ,which is a primitive type,it should not be able to accesss property length.It can do so because of something called Boxing.Boxing is the process where any primitive type is converted to an Object type and the reverse is called Unboxing.These object types or Object wrappers are created with the view that there are some common operations that one might need to perform with the primitive values.They contain useful methods and properties and are prototype linked to the primitives.
As far as the Objects are concerned,key value pairs can be added to every object,even to the arrays.
var arr=[1,2,3];
arr.name="my array";
arr; //[1,2,3,name:'my array']
this does not mean that the fourth element of the array is "name:'my array'"."name" is a property that can be called with dot notation(arr.name) or brackets notation(arr["name"]).
I would say "Everything in Javascript is not an object (because of primitives) but everything in javascript leads back to an object (because of wrappers and Object constructor)"
I am trying to understand what a Javascript immutable variable means. If I can do:
var x = "astring";
x = "str";
console.log(x); //logs str` , then why it is immutable?
The only answer I can think (from the little bit of C I know) is that var x is a pointer to a memory block with the value "astring", and after the 2nd statement it points to another block with the value "str". Is that the case?
And a bonus question: I was confused by the value types of Javascript. Are all variables objects under the hood? Even number and strings?
Values are immutable; variables are not; they hold a reference to their (primitive) values.
The three primitive types string, number and boolean have corresponding types whose instances are objects: String, Number, Boolean.
They are sometimes called wrapper types.
The following values are primitive:
Strings: "hello"
Numbers: 6, 3.14 (all numbers in JavaScript are floating point)
Booleans: true, false
null: usually explicitly assigned
undefined: usually the default (automatically assigned) value
All other values are objects, including wrappers for primitives.
So:
Objects are mutable by default
Objects have unique identities and are compared by reference
Variables hold references to objects
Primitives are immutable
Primitives are compared by value, they don’t have individual identities
You might find The Secret Life of JavaScript Primitives a good explanation.
Also, in ES6 there is a new const keyword, that creates a read-only named constant that cannot change value through assignment or be re-declared while the script is running.
Hope this helps!
First, in C "A string is an array of characters with last elem = '\0' ". They are mutable.
If you declare and initialize a string in C like this:
char str[] = "Foo";
What you are basically doing is reserving 4 bytes ( probably 8bit-byte, don't mind this probably if it hurts you ). The word str serves as a pointer to the first elem of this array. So, if you do like this:
str[0] or *(str) = 'G'
then it will mutate the value at that address instead of creating new array. You can verify it by printing out the address of str. In both cases it will be same.
Now in case of JavaScript string is a primitive type. All operations on string are done by value instead of by reference. So, doing this will produce true.
var str1 = "foo";
var str2 = "foo";
str1 === str2; => true
The initialization of string asks for a buffer to fit "foo" and binds the name str1 to it. What makes them immutable is that you can't change that buffer. So, you can't do this:
str1[0] = 'G'
Executing this command will produce no warning or error in non-strict mode but, it will not change the str1. You can verify it by
console.log(str1) => "foo"
But if you do like this:
str1 = "goo"
what you are actually doing is that you are asking for a new buffer to fit "goo" and bind identifier str1 to it. No change in that old buffer containing "foo".
So, what happens to "foo"?
Java Script has an automatic garbage collector. When it sees some chunk of memory that no longer can be referenced by any identifier or ... then it consider that memory free.
Same happens to number,booleans.
Now, about wrapper objects!
Whenever you try to access a property on string like this:
str1.length;
What JavaScript does it creates a new object using String class and invoke the methods on string. As soon as the function call returns, the object is destroyed.
The below code explains it further:
var str = "nature";
str.does = "nurtures"; //defining a new property;
console.log(str.does) => undefined
because the object has been destroyed.
Try this!
var str = new String("Nature");
str.does = "nurtures";
console.log(str) => ??
this str is really an object...
Conclusion: In C , in a single scope the variable name serves as a pointer. So, int, float, string all are mutable. But in Java Script a primitive type variable name serves as value not as reference
References: C++ primer plus, Java Script The Definitive Guide, C by Stephen Kochan
You are correct. Strings (and numbers) are immutable in java script (and many other languages). The variables are references to them. When you "change the value of a variable" you are changing the string (or whatever) that the variable references, not the value itself.
I think many new programmers believe immutability to mean that primitive values cannot be changed by reassignment.
var str = "testing";
var str = "testing,testing";
console.log(str); // testing, testing
var fruits = ["apple", "banana", "orange"];
fruits[0] = "mango";
console.log(fruits); //["mango", "banana", "orange"]
The values associated with both mutable and immutable types can be changed through reassignment as the above examples with strings and arrays show.
But then, these data types have associated functions(methods) that are used to manipulate the values belonging to each data type. This is where mutability/immutability is seen. Since arrays are mutable, any manipulation by an array method affects the array directly. For example,
var fruits = ["mango","banana", "orange"];
fruits.pop();
console.log(fruits) //["mango", "banana"]
The array.pop() method deleted "orange" from the original fruits array.
But with strings for example,
var name = "Donald Trump";
name.replace("Donald", "President");
console.log(name)//Donald Trump
the original string remains intact!
Immutability disallowed any altering of the original string by the string method. Instead, the method produces a new string if the method operation is assigned to a variable like so:
var name = "Donald Trump";
var newName = name.replace("Donald", "President");
console.log(newName);//President Trump
Let's understand here, first,
let firstString = "Tap";
console.log(firstString); //Output: Tap
firstString[0] = "N";
console.log(firstString) //Output: Tap
This is where we can see the immutable effect!
Immutability in this definition is historic. It's attached to what could be done in OTHER programming languages.
I think that is the first thing to understand. And to programmers who have only used JavaScript the question may seem nonsensical or needlessly pedantic. Describing primitives as immutable is like describing ice cream as not being able to jump. Why would I think it could? It is only in relation to other historic programming languages that the lack of mutability is apparent when dealing with primitive types.
I read this a lot in many JavaScript introductions. I just don't understand it. I always think of objects as something with methods and properties.
Arrays I understand, since it has key value pair.
How about "Strings" or "Numbers" or "functions" ?
These things above listed seem to be like functions to me. This means you input something, you get something out. You don't really get the access properties or anything. There's no dot notation used in arrays or this list of "objects".
Does anyone code some examples of each of these with dot notations which its methods and properties are being accessed? I suspect that definition of object is probably limited since I did start learning about JavaScript...
No, not everything is an object in JavaScript. Many things that you interact with regularly (strings, numbers, booleans) are primitives, not objects. Unlike objects, primitive values are immutable. The situation is complicated by the fact that these primitives do have object wrappers (String, Number and Boolean); these objects have methods and properties while the primitives do not, but the primitives appear to have methods because JavaScript silently creates a wrapper object when code attempts to access any property of a primitive.
For example, consider the following code:
var s = "foo";
var sub = s.substring(1, 2); // sub is now the string "o"
Behind the scenes, s.substring(1, 2) behaves as if it is performing the following (approximate) steps:
Create a wrapper String object from s, equivalent to using new String(s)
Call the substring() method with the appropriate parameters on the String object returned by step 1
Dispose of the String object
Return the string (primitive) from step 2.
A consequence of this is that while it looks as though you can assign properties to primitives, it is pointless because you cannot retrieve them:
var s = "foo";
s.bar = "cheese";
alert(s.bar); // undefined
This happens because the property is effectively defined on a String object that is immediately discarded.
Numbers and Booleans also behave this way. Functions, however, are fully-fledged objects, and inherit from Object (actually Object.prototype, but that's another topic). Functions therefore can do anything objects can, including having properties:
function foo() {}
foo.bar = "tea";
alert(foo.bar); // tea
That’s right: in JavaScript, almost everything is an object. But these objects are bit different from what we see in Java, C++ or other conventional languages. An object in JS is simply a hashmap with key–value pairs. A key is always a string or a symbol, and a value can be anything including strings, integers, booleans, functions, other objects etc. So I can create a new object like this:
var obj = {}; // This is not the only way to create an object in JS
and add new key–value pairs into it:
obj['message'] = 'Hello'; // You can always attach new properties to an object externally
or
obj.message = 'Hello';
Similarly, if I want to add a new function to this object:
obj['showMessage'] = function(){
alert(this['message']);
}
or
obj.showMessage = function() {
alert(this.message);
}
Now, whenever I call this function, it will show a pop-up with a message:
obj.showMessage();
Arrays are simply those objects which are capable of containing lists of values:
var arr = [32, 33, 34, 35]; // One way of creating arrays in JS
Although you can always use any object to store values, but arrays allow you to store them without associating a key with each of them. So you can access an item using its index:
alert(arr[1]); // This would show 33
An array object, just like any other object in JS, has its properties, such as:
alert(arr.length); // This would show 4
For in-depth detail, I would highly recommend John Resig’s Pro JavaScript Techniques.
The sentence "In JavaScript, ALMOST everything is an object" is correct, because the MAIN code-units (objects, functions, arrays) are JavaScript-objects.
JavaScript code uses 9 different-units plus 1 (multiple):
- 01. array
- 02. boolean
- 03. function
- 04. null
- 05. number
- 06. object
- 07. regexp
- 08. string
- 09. undefined
- 10. multiple
BUT JavaScript-objects:
- are NOT same creatures as the 'objects' in other object-oriented-languages.
- they are a collection of name-value-pairs.
- all have a function of creation (its constructor).
- all INHERIT the members of the prototype-object of its constructor and this is its prototype.
- all functions are objects BUT NOT all objects are functions.
- functions have scope, objects NOT (a design flaw in my opinion).
- Object, Function, Array, String, ... with first CAPITAL are functions!!!
- it is more important the differences of JS objects and functions, than its commonnesses.
- the name 'instance' in JS has different meaning with the name 'instance' in knowledge-theory where an instance inherits the attributes of its generic-concept. In JS denotes only its constructor. JavaScript got the name 'instance' from 'class-based-inheritance' ool (java) where it is an appropriate name because those objects inherit the attributes of classes.
A better name for the JS-keyword 'instanceof' is 'objectof'.
JS-functions ARE JS-objects because:
1) they can have members like JS-objects:
> function f(){}
undefined
> f.s = "a string"
"a string"
> f.s
"a string"
2) they have a constructor-function, like all JS-objects, the Function function:
> (function f(){}) instanceof Function
true
3) as all JS-objects, their prototype-object is the same with its constructor prototype:
> (function f(){}).__proto__ === Function.prototype
true
> ({}).__proto__ === Object.prototype
true
> (new Object).__proto__ === Object.prototype
true
4) of course, JS-functions as SPECIFIC JS-objects have and extra attributes, like all functions in programming-languages, that JS-objects do not have like you can call (execute) them with input and output information.
EVERYTHING is NOT an object, because, for example, we can NOT add members to a literal string:
> var s = "string"
undefined
> s.s2 = "s2string"
"s2string"
> s.s2
undefined
Based on developer.mozilla.org and also ECMAScript specification the answer is no. Technically not everything is object.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive
In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 7 primitive data types: string, number, bigint, boolean, null, undefined, symbol
A primitive is not an object and has no methods and It is also immutable. Except for null and undefined, all the other primitive have a wrap object around them to provide you some functions that you can use. For example String for the string primitive.
https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
So here in the following code when you call toUpperCase() on a primitive data name JavaScript will automatically wrap the string primitive and call toUpperCase function of String object
var name = 'Tom';
console.log(name);
name.toUpperCase();
console.log(name);
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.
Also note that JavaScript distinguishes between String objects and primitive string values.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects
var nameP = 'Tom';
var nameO = new String(nameP);
typeof nameP // "string"
typeof nameO // "object"
Not everything is an object in javaScript. JavaScript has primitives and objects.
There are six primitives-null,undefined,string,number,boolean and symbol.
It might seem like everything is acting as an object because of the properties and function that can be accessed.for example-
var stringvar="this string";
typeof stringvar; // "string"
stringvar.length; //11
now since "stringvar" is a string type ,which is a primitive type,it should not be able to accesss property length.It can do so because of something called Boxing.Boxing is the process where any primitive type is converted to an Object type and the reverse is called Unboxing.These object types or Object wrappers are created with the view that there are some common operations that one might need to perform with the primitive values.They contain useful methods and properties and are prototype linked to the primitives.
As far as the Objects are concerned,key value pairs can be added to every object,even to the arrays.
var arr=[1,2,3];
arr.name="my array";
arr; //[1,2,3,name:'my array']
this does not mean that the fourth element of the array is "name:'my array'"."name" is a property that can be called with dot notation(arr.name) or brackets notation(arr["name"]).
I would say "Everything in Javascript is not an object (because of primitives) but everything in javascript leads back to an object (because of wrappers and Object constructor)"
I would love a clear explanation as to better understand what's going on here?
I can create what look like primitive types with Object. It looks like a number but not quite for a string. I was under the impression that Object() was used to create all objects in js (ie of type object) but not primitive types, like number, string boolean.
There are times when a primitive type (Boolean, Number or String) needs to be converted to object albeit temporarily.
Look at this example:
var str = 'javascript';
str = str.substring(4);// You get "script" but how?
How can you call a function on something that is not an object? The reason is that primitive value is wrapped into Object(String) on which substring() method is defined. If it was not done, you would not be able to call the method in the primitive type. Such wrappers are called Primitive Wrappers.
Also, it doesn't mean that str has now become an object. So, if you said:
str.myProp = 10;
and then console.log(str.myProp);//You would get undefined
The difference between a reference type and a primitive wrapper object is lifetime. Primitive wrappers die soon.
So you can think of
var str = 'javascript';
str = str.substring(4);// You get "script" but how?
As these lines:
var str = new String(“javascript”);
str = str.substring(4);
str = null;
Now coming to what you are doing:
number = Object(5);
Here you are wrapping a number primitive into an object. It is as if you had written:
number = new Number(5);
Here, Object(5) is behaving as a factory and depending on the type of the input(number, string), it gives back object by wrapping primitive value into it.
So, Object(5) is equivalent to new Number(5) and Object('test') is as if saying new String('test').
Hope this helps!
The notion of primitives and objects is slightly implementation dependent. But you can think of it like this:
Primitives are not objects. They have their own special semantics, such as the string "hello" is the same no matter how many times you create one. However, the object new String("hello") should return a new string every time.
In many implementations, there is auto-boxing and unboxing of primitives when they need to act like objects and vice-versa. I would suggest reading this question for more details: What is the difference between string literals and String objects in JavaScript?
You can use Object.prototype.valueOf() to get [[PrimitiveValue]] 5 or "test".
var number = new Object(5);
var aString = new Object("test");
console.log(number.valueOf(), aString.valueOf());
5.toString();
As you can see Number is an object. But number is not. In some cases primitives are wrapped by objects to implement object like behaviours...
5 // primitive type
Object(5) // wrapper of that primitive type
5.toString() === Object(5).toString() //...
I am trying to understand what a Javascript immutable variable means. If I can do:
var x = "astring";
x = "str";
console.log(x); //logs str` , then why it is immutable?
The only answer I can think (from the little bit of C I know) is that var x is a pointer to a memory block with the value "astring", and after the 2nd statement it points to another block with the value "str". Is that the case?
And a bonus question: I was confused by the value types of Javascript. Are all variables objects under the hood? Even number and strings?
Values are immutable; variables are not; they hold a reference to their (primitive) values.
The three primitive types string, number and boolean have corresponding types whose instances are objects: String, Number, Boolean.
They are sometimes called wrapper types.
The following values are primitive:
Strings: "hello"
Numbers: 6, 3.14 (all numbers in JavaScript are floating point)
Booleans: true, false
null: usually explicitly assigned
undefined: usually the default (automatically assigned) value
All other values are objects, including wrappers for primitives.
So:
Objects are mutable by default
Objects have unique identities and are compared by reference
Variables hold references to objects
Primitives are immutable
Primitives are compared by value, they don’t have individual identities
You might find The Secret Life of JavaScript Primitives a good explanation.
Also, in ES6 there is a new const keyword, that creates a read-only named constant that cannot change value through assignment or be re-declared while the script is running.
Hope this helps!
First, in C "A string is an array of characters with last elem = '\0' ". They are mutable.
If you declare and initialize a string in C like this:
char str[] = "Foo";
What you are basically doing is reserving 4 bytes ( probably 8bit-byte, don't mind this probably if it hurts you ). The word str serves as a pointer to the first elem of this array. So, if you do like this:
str[0] or *(str) = 'G'
then it will mutate the value at that address instead of creating new array. You can verify it by printing out the address of str. In both cases it will be same.
Now in case of JavaScript string is a primitive type. All operations on string are done by value instead of by reference. So, doing this will produce true.
var str1 = "foo";
var str2 = "foo";
str1 === str2; => true
The initialization of string asks for a buffer to fit "foo" and binds the name str1 to it. What makes them immutable is that you can't change that buffer. So, you can't do this:
str1[0] = 'G'
Executing this command will produce no warning or error in non-strict mode but, it will not change the str1. You can verify it by
console.log(str1) => "foo"
But if you do like this:
str1 = "goo"
what you are actually doing is that you are asking for a new buffer to fit "goo" and bind identifier str1 to it. No change in that old buffer containing "foo".
So, what happens to "foo"?
Java Script has an automatic garbage collector. When it sees some chunk of memory that no longer can be referenced by any identifier or ... then it consider that memory free.
Same happens to number,booleans.
Now, about wrapper objects!
Whenever you try to access a property on string like this:
str1.length;
What JavaScript does it creates a new object using String class and invoke the methods on string. As soon as the function call returns, the object is destroyed.
The below code explains it further:
var str = "nature";
str.does = "nurtures"; //defining a new property;
console.log(str.does) => undefined
because the object has been destroyed.
Try this!
var str = new String("Nature");
str.does = "nurtures";
console.log(str) => ??
this str is really an object...
Conclusion: In C , in a single scope the variable name serves as a pointer. So, int, float, string all are mutable. But in Java Script a primitive type variable name serves as value not as reference
References: C++ primer plus, Java Script The Definitive Guide, C by Stephen Kochan
You are correct. Strings (and numbers) are immutable in java script (and many other languages). The variables are references to them. When you "change the value of a variable" you are changing the string (or whatever) that the variable references, not the value itself.
I think many new programmers believe immutability to mean that primitive values cannot be changed by reassignment.
var str = "testing";
var str = "testing,testing";
console.log(str); // testing, testing
var fruits = ["apple", "banana", "orange"];
fruits[0] = "mango";
console.log(fruits); //["mango", "banana", "orange"]
The values associated with both mutable and immutable types can be changed through reassignment as the above examples with strings and arrays show.
But then, these data types have associated functions(methods) that are used to manipulate the values belonging to each data type. This is where mutability/immutability is seen. Since arrays are mutable, any manipulation by an array method affects the array directly. For example,
var fruits = ["mango","banana", "orange"];
fruits.pop();
console.log(fruits) //["mango", "banana"]
The array.pop() method deleted "orange" from the original fruits array.
But with strings for example,
var name = "Donald Trump";
name.replace("Donald", "President");
console.log(name)//Donald Trump
the original string remains intact!
Immutability disallowed any altering of the original string by the string method. Instead, the method produces a new string if the method operation is assigned to a variable like so:
var name = "Donald Trump";
var newName = name.replace("Donald", "President");
console.log(newName);//President Trump
Let's understand here, first,
let firstString = "Tap";
console.log(firstString); //Output: Tap
firstString[0] = "N";
console.log(firstString) //Output: Tap
This is where we can see the immutable effect!
Immutability in this definition is historic. It's attached to what could be done in OTHER programming languages.
I think that is the first thing to understand. And to programmers who have only used JavaScript the question may seem nonsensical or needlessly pedantic. Describing primitives as immutable is like describing ice cream as not being able to jump. Why would I think it could? It is only in relation to other historic programming languages that the lack of mutability is apparent when dealing with primitive types.