Can I add a property dynamically in javascript? - javascript

Is it okay to add properties to an object at runtime? It seems to run okay but are there any issues I should be aware of?
I'm using a 3rd party javascript API which has an object class, which I've instantiated and added my own property to after instantiation, like the code below:
For example can I do this:
var Car = function (id, type) {
this.id = id;
this.type = type;
};
var myCar = new Car(1,"Nissan");
// CAN I DO THIS: (needsWork not a property of object Car)
myCar.needsWork = true;

Actually, you have two ways to do that in JavaScript:
add a method or property to an instance (this car only)
var myCar = new Car(1,"Nissan");
myCar.needsWork = true;
add a method or property to the car prototype (all cars, even already existing ones)
var myCar = new Car(1, "Nissan");
var biggerCar = new Car(2, "Hummer");
Car.prototype.needsWork = true;
alert( myCar.needsWork && biggerCar.needsWork
? "We need work"
: "Something wrong here"
);
Reference:
Object.prototype

Yea, this is called object augmentation. It is a key feature in JavaScript.

Yes
There is nothing wrong with that.
See Object Augmentation here: http://www.crockford.com/javascript/inheritance.html

Related

Unable to cast object to class in JavaScript ES6

I am creating a map to which I am adding a custom class object,
var member_map = {};
var memberAction = new MemberActions(members.data[i].id, members.data[i].name);
member_map[memberAction.id] = memberAction;
Now when I try to get back a MemberActions object from the map using an ID, i get an Object rather than a MemberActions object.
var memberAction = member_map[fetch_id];
How do I cast the object?
EDIT:
My class defn:
class MemberActions {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
JS doesn't have such a thing as object casting.
When you say you've got an Object this may mean when you try to console.log(memberAction) you get told that it's an Object - however it doesn't mean that isn't a MemberActions object.
To check the name of it, try:
console.log(memberAction.constructor.name)
memberAction.constructor should also contain the constructor you've defined.

Value of constructor and prototype gets changed after over writing the prototype object. Why?

I have the Director() function. I have created 2 instances AlfredH and JohnD out of Director() constructor. I did not write the prototype object.
function Director(){
this.genre = "Thriller";
}
var AlfredH = new Director();
var JohnD = new Director();
If I check the values of JohnD.constructor; and JohnD.constructor.prototype; I get Director() and Object() respectively.
But, if I add properties to prototype object of Director() like the below:
function Director(){
this.genre = "Thriller";
}
Director.prototype = {
noir: true
};
var AlfredH = new Director();
var JohnD = new Director();
and if I check the values of JohnD.constructor; and JohnD.constructor.prototype; I get Object() and Object() respectively. Can anyone explain this behavior? and the same can be extended to the value of JohnD.constructor.prototype.constructor;
var a = {
value:22;
}
then
var a = {
somethingelse:0
}
Can you guess what a.value is?
You are overwriting the prototype with another object.
Then add to that that
console.log({}.constructor)===Object;//=true
Maybe try adding it like this:
Director.prototype.noir = true;
Note that anything on the prototype is shared among instances, this is a good thing because it saves memory and instantiate the object quicker with less cpu.
When assigning a new value the value is assigned to the instance but when manipulating the value through functions it affects all instances
Director.prototype.someArray=[];
var d1=new Director();
var d2=new Director();
d1.someArray.push(22);
console.log(d2.someArray);//=[22]
More info on prototype here: https://stackoverflow.com/a/16063711/1641941

use of prototype in javascript

I am learning prototype in JavaScript and this is the code I am trying -
<script>
function employee(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
var trialcoder = new employee('trialcoder', 26, 'M');
//employee.prototype.salary = null;
trialcoder.salary = 19000;
document.write("salary is "+ trialcoder.salary);
</script>
My thoughts- To add another property we need to use prototype like - employee.prototype.salary = null; so on un commenting this line, I was expecting an error but it was not..let me know where I am wrong in the prototype concept.
Code Source - http://www.w3schools.com/jsref/jsref_prototype_math.asp
Your code is correct, because when you called
var trialcoder = new employee('trialcoder', 26, 'M');
You got an object instance of employee and just like any other object you can add properties to your trialcoder object like
trialcoder.salary = 19000;
In this case, the salary property is only available to your trialcoder object and if you make another instance of employee like var another = new employee() you have no salary property in another object, but, if you do something like
function employee(name, age, sex) { //... }
employee.prototype.salary = 19000;
and then make instances like
var anEmp = new employee();
console.log(anEmp.salary); // 19000
Make another instance
var newEmp = new employee();
console.log(newEmp.salary); // 19000
if you want, you can
newEmp.salary = 10000;
console.log(anEmp.salary); // 10000
Which means, when you add a property in the prototype of a constructor (employee) then every object instance can share the same property and after making an instance from the constructor, you can change the property of an instance but this won't effect other instances. Hope it's clear enough now.
Your code is right and you will not receive error because using prototype your setting property salary of class employee and after creating an object of your class ur are setting the property for that specific object,if you create another object you can set its property salary too
If you set property using prototype then all objects of that class will share that (salary) property .

Adding a property to a "Class" in JavaScript

There are no actual classes in javascript. But you have to work with what you get.
Lets take this example "Class":
var example = function (string) {
this._self = string;
}
With the above, you could do something like:
var ex = new example("Hello People."),
display = ex._self; // returns "Hello People."
I thought that by using something like example.prototype.newFun = function(){} would add a new property to that "Class". But it isn't working in my code.
Here is the full code i'm testing:
var example = function (string) {
this._self = string;//public, var like, storage
}
var showExample = new example("Hello People");
showExample.prototype.display = function (a) {//code stops here, with error "Uncaught TypeError: Cannot set property 'display' of undefined"
return a;
}
console.log(showExample._self);
console.log(showExample.display("Bye"));
What i'm trying to do is add the display function to the example function as a "public function". I might be doing something wrong.
It's not the object that has the prototype, it's the function that you use to create the object:
var example = function (string) {
this._self = string;
}
example.prototype.display = function (a) {
return a;
};
Because there's no prototype for showExample - it's only an instance of example. Try to do this: example.prototype.display = function (a) {} and it will work.
Here's a bit more on classes in JavaScript:
3 Ways to "define" classes
This lovely SO question
I like the way Classy handles this and also how classes are implemented in CoffeeScript.
You can modify to the constructor of showExample ..
ex.
showExample.constructor.prototype.display = function (a) {
return a;
}
You try to add a method to the prototype of the instance of example (showExample). The instance has no prototype. Try example.prototype.display = function() {/*...*/}; (in other words, add the method to the prototype of the constructor of showExample, that is example) and check again. After that, all instances of example 'know' the display method, or in your words, display is 'public' to all instances.
You can add the method to the instance using showExample.display = function() {/*...*/};. Using that, only showExample knows the the display method.
in your case showExample is an object of example...
use
example.prototype.display = function(a)...

Best way to create an object/struct in javascript

I am new to javascript. As far as I can tell there are 5 ways to make an object (really a struct I guess). I was wondering what the best way is. Thanks.
var makeOption = function(name, dataType){
var option = {
name: name,
dataType: dataType
};
return option;
};
var makeOption2 = function(name, dataType){
this.name = name;
this.dataType = dataType;
};
function makeOption3(name, dataType){
this.name = name;
this.dataType = dataType;
};
var makeOption4 = function makeOption4Name(name, dataType){
this.name = name;
this.dataType = dataType;
};
var v1A = makeOption("hannah", "int");
var v1B = new makeOption("hannah", "int");
//var v2A = makeOption2("hannah", "int"); <- undefined.
var v2B = new makeOption2("hannah", "int");
// var v3A = makeOption3("hannah", "int"); <- undefined.
var v3B = new makeOption3("hannah", "int");
// var v4A = makeOption4("hannah" ,"int"); <- undefined.
var v4B = new makeOption4("hannah" ,"int");
This is what is displayed in the firebug DOM Tab:
I'd go with #3.
#1 does not allow the use of prototype.
#2 is anonymous, and anonymous functions don't help in debugging because you don't see what function is causing problems if it is (the variable name the function is stored is not part of the function, whereas the function's name is).
#4 is confusing - two possibilities to access one function.
Whole chapters of books on JavaScript best practices have been written on this subject. That said: If you aren't concerned about inheritance and aren't going to be creating numerous copies of an object with methods, i.e., you are just creating a "struct", then object literal notation, your first example, is the way to go. In that approach, you are using object literal notation, which is lightweight and fast. It doesn't mess with the object prototype or require the use of the new operator.
Start adding methods to your object, however, and the answer changes to "it depends."
By the way, you left out a couple of ways to create an object:
var o = {};
o.name = "hannah";
o.dataType = "int";
and, not recommended:
var o = new Object();
o.name = "hannah";
o.dataType = "int";
The first one is preferable from design standpoint - based on your name.
makeOption implies that it creates and retuens an object.
All your other solutions do NOT actually return an object and require "new" call. They may have similar/identical technical results when used as pure data structures, but only the first one works as a "object maker", as its name implies.
If you want to use #2/3 (#4 makes no sense - why would you clone the function twice), then you need to name it something else - optionPrototype may be.
I personally use makeoption3 I have tried them all and found that makeoption3 is the cleanest and simplest if you are writing multiple objects. Also it has less code than the others keeping your file size down.
function makeOption3(name, dataType){
this.name = name;
this.dataType = dataType;
};
If you don't need inheritance capabilities, just go with #1 (as you're essentially just using it to build and return an object literal). Otherwise I'd go with #3, as it allows for protoype methods and is also a named function rather than an anonymous one.
Taking this from a Post John Resig made about javascript "Class" instatiation, he points out...
// Very fast
function User(){}
User.prototype = { /* Lots of properties ... */ };
// Very slow
function User(){
return { /* Lots of properties */ };
}
which is what we're talking about he posted this snippet of code...
// makeClass - By John Resig (MIT Licensed)
function makeClass(){
return function(args){
if ( this instanceof arguments.callee ) {
if ( typeof this.init == "function" )
this.init.apply( this, args.callee ? args : arguments );
} else
return new arguments.callee( arguments );
};
}
And then using it, leveraging the speed of using the prototype chain..
var User = makeClass();
User.prototype.init = function(first, last){
this.name = first + " " + last;
};
var user = User("John", "Resig");
user.name
// => "John Resig"
This also takes care of the usage of new it allows the use of the keyword, but doesn't require it.
Link to Original Post
Why don't you want to use object literals? It seems like you're really asking about objects and inheritance..?

Categories

Resources