I'm currently learning JS, and while working on my project, I was wondering if a variable is by definition an object, or a kind of object, or nothing a all.
I know we can create objects through var, but I'm not sure if a var is always an object.
Thanks for the answers !
Variables are not classified as objects. They are their own classification as a storage address. Now as Nina said in the comment, objects are types which are in the same category as: array, string, number, and boolean. A variable can hold any of these types and be referenced to in your code.
A variable is rather like a bucket, where different values can be put in. An object is such a value.
I know we can create objects through var
Not really. With the var keyword you can declare a variable (a bucket), to create an object you could use an object literal.
Think of var as a mechanism to create a memorable handle for your primitive and reference values like your object. The var keyword itself doesn't do anything other than declare a handle in a scope and allow you to initialize the handle to the value you desire.
Related
So I learned a bit about the hidden class concept in v8. It is said that you should declare all properties in the constructor (if using prototype based "pseudo classes") and that you should not delete them or add new ones outside of the constructor. So far, so good.
1) But what about properties where you know the type (that you also shouldn't change) but not the (initial) value?
For example, is it sufficient to do something like this:
var Foo = function () {
this.myString;
this.myNumber;
}
... and assign concrete values later on, or would it be better to assign a "bogus" value upfront, like this:
var Foo = function () {
this.myString = "";
this.myNumber = 0;
}
2) Another thing is with objects. Sometimes I just know that an object wont have a fixed structure, but I want to use it as a hash map. Is there any (non verbose) way to tell the compiler I want to use it this way, so that it isn't optimized (and deopted later on)?
Update
Thanks for your input! So after reading your comments (and more on the internet) I consider these points as "best practices":
Do define all properties of a class in the constructor (also applies for defining simple objects)
You have to assign something to these properties, even if thats just null or undefined - just stating this.myString; is apparently not enough
Because you have to assign something anyways I think assigning a "bogus" value in case you can't assign the final value immediatly cannot hurt, so that the compiler does "know" ASAP what type you want to use. So, for example this.myString = "";
In case of objects, do assign the whole structure if you know it beforehand, and again assign dummy values to it's properties if you don't know them immediatly. Otherwise, for example when intending to use the Object as a hashmap, just do: this.myObject = {};. Think its not worth indicating to the compiler that this should be a hashmap. If you really want to do this, I found a trick that assigns a dummy property to this object and deletes it immediatly afterwards. But I won't do this.
As for smaller Arrays it's apparently recommended (reference: https://www.youtube.com/watch?v=UJPdhx5zTaw&feature=youtu.be&t=25m40s) to preallocate them especially if you know the final size, so for example: this.myArray = new Array(4);
Don't delete properties later on! Just null them if needed
Don't change types after assigning! This will add another hidden class and hurt performance. I think thats best practice anyways. The only case where I have different types is for certain function arguments anyways. In that case I usually convert them to the same target type.
Same applies if you keep adding additional properties later on.
That being said, I also think doing this will lean to cleaner and more organized code, and also helps with documenting.
Yeah, so one little thing I am unsure remains: What if I define properties in a function (for example a kind of configure() method) called within the constructor?
Re 1): Just reading properties, like in your first snippet, does not do anything to the object. You need to assign them to create the properties.
But for object properties it doesn't actually matter much what values you initialise them with, as long as you do initialise them. Even undefined should be fine.
The concrete values are much more relevant for arrays, where you want to make sure to create them with the right elements (and without any holes!) because the VM tries to keep them homogeneous. In particular, never use the Array constructor, because that creates just holes.
Re 2): There are ways to trick the VM into using a dictionary representation, but they depend on VM and version and aren't really reliable. In general, it is best to avoid using objects as maps altogether. Since ES6, there is a proper Map class.
I'm currently in the learning process of JavaScript and really get confused about immutable values. What I understand is, when a value is created (stings/numbers/booleans), it can never be changed.
Now my question is, the variable that I assign values, the value of that variable is changeable. I can assign new values to that variable. So why immutability is important?
Also, when I assign a new value to a variable, what happen to the previous value? Does it stay in memory and block some spaces? Does it lost its pointer from that variable? Actually what happen?
Please help me to understand what is the actual use of the concepts "Mutable" and "Immutable" in JavaScript. Thanks in advance.
What You Seem Confused About
Assignment of a variable has nothing to do with immutable or mutable objects. A variable is simply an alias: it refers to an object in memory. When you change a variable's value, all you've done is tell the compiler to stop associating that object with this variable and associate it with another object instead. Assignment does not affect the underlying object - the object never changes, you just no longer have a way to access it anymore.
Usually, when all references to an object are lost, they are garbage collected i.e. the memory allocated for the object is released and the object is lost forever. However, this also has nothing to do with the difference between immutable and mutable objects.
The Real Difference Between Immutable and Mutable Objects
Immutable objects do not modify the object in place (i.e change what it looks like) - they return a new copy of the data with the variables changed.
Mutable objects in Javascript do not return a copy, but let you change the object itself.
I liken it to the difference between array.splice() and array.slice(). splice() will change the original array by removing/inserting elements where needed - slice() will create a new array with just the elements you want. They can be made to do the same things - but one mutates the array in place, the other one creates a copy.
An immutable object is forced to always return a new copy when changed - it will not by itself be changed. A mutable object can - but does not have to - be mutated in place. Primitive types in Javascript are mostly immutable - you cannot change the form of a string once created (if you call replace on the JS string, you will receive a new string with the values you asked for replaced, not the same string with the value changed). Objects are mostly mutable: for instance you can do object[key] = value and change the object everywhere it is referenced.
tl;dr
When you change a mutable object, it is changed everywhere it is referenced. When you change an immutable object, it isn't changed at all - a new object is created, and all the old references to the object will give you the original object with nothing different about it.
I have something like this:
$scope.last_good_configuration = $scope.storage;
In $scope.last_good_configuration I keep last good settings.
And when user type in input bad value, for example too big integer i want to do:
$scope.storage = $scope.last_good_configuration;
But my $scope.last_good_configuration is all the time the same as $scope.storage. How to stop updating $scope.last_good_configuration? I have to evaluate my scope somehow?
You need to make a copy or clone of the original object. Angular has a built in method for this: angular.copy.
$scope.last_good_configuration = angular.copy($scope.storage);
//Edits must be at least 6 characters workaround
You can create a new object using angular.copy() so when you make changes to storage it won't affect last_good_configuration
$scope.last_good_configuration = angular.copy($scope.storage);
Since objects are passed by reference, you need to create a new object to store default configuration in. Otherwise, when you modify $scope.last_good_configuration it also affects $scope.storage since they both point to the same object.
Use angular.extend method which will copy all properties from $scope.storage into the new object {}:
$scope.last_good_configuration = angular.extend({}, $scope.storage);
UPD. I totally forgot about dedicated angular.copy which is probably more appropriate in this case, especially is $scope.storage has nested object structure: angualar.extend will make a shallow copy, in this case you should use angular.copy (see Satpal answer).
In a JS function, I'll be using an object resultModel, with two properties idArray and nameArray. What would be the proper way to declare this?
Currently I declare the object with var resultModel together with other variables at the top of the function, but the properties I simply start using by assigning them a value in a loop later in the function:
resultModel.idArray.push(someValue[i][0]);
resultModel.nameArray.push(someValue[i][1]);
Of course, I know that the var keyword is important for scoping, and as the "root" identifier is declared in the function I avoid any global tampering and this is all good. But I have an expectation that the properties of the value really should also be declared somehow, for other reasons than scoping - memory allocation springs to mind, possibly type hinting via JSDoc comments, readability and sheer completeness of declaration.
So, my question is: should I declare such properties, and what would in that case be the proper way to do that?
Like this:
var resultModel = {
idArray: [],
nameArray: []
};
Assignment is considerably slower than just putting the properties on the object in the first place, so this is the best way to go.
The objects in javascript are allocated memory dynamically ,like in a linked list so i do not think we should concern about the memory allocation here.
For better readability you could initialise them with null value like abhitalks mentioned above.
Put the property as a default value of same datatype .e.g for array -> Array(), for integers : 0 or -1 etc :
var resultModel = { "idArray": DEFAULT_VALUE , "nameArray" : DEFAULT_VALUE }
What does this mean?
var settings = {
"column-1" : ["block-1"],
"column-2" : ["block-2"]
};
It means one should [likely] read a tutorial/book on JavaScript before asking questions like this on SO ;-) (Explaining what "it means" will likely have not much "practical meaning" by itself.)
Like Eloquent JavaScript: A Modern Introduction to Programming
I believe the exact construct/term that is being sought is "object literals" -- {...} is for objects and [...] is for arrays.
Happy coding.
This will create a new object and store it in the settings variable.
The object is created by an Object literal and consist out of two propertys (column-1 and column-2) which are both assigned an Array with a single String value.
It defines an object containing two properties (column-1 and column-2) which both contain arrays which both contain a single value (block-1 an block-2).
Due to the - in the property name it will be impossible to access them using the object.property syntax so you'll have to use the array syntax: object['property']
Initialized a variable named settings and assigned the value {"column-1": ["block"], "column-2": ["block-2"]}, which is an object, to the settings.