I'm using below code.
var emp = function employee(name, sal) {
this.empname = name;
this.sal = sal;
}
emp.prototype.getName = function() {
return this.empname
};
var man = new emp("manish", 100);
console.log(man.getName()); //prints manish
var man1 = Object.create(emp);
man1.empname = "manish1";
console.log(man1.prototype.getName()); //prints undefined.
can some help me to understand why object create is printing undefined instead manish1.
new X() creates a new object with constructor X and prototype X.prototype. Object.create(X) creates a new object with prototype X (and therefore constructor X.constructor).
So you need to call it with the prototype you want:
var man2 = Object.create(emp.prototype);
man2.empname = "manish2";
console.log (man2.getName()); // prints manish2
Related
Can I define an object as a prototype member? If yes then how can I stop the call by reference of an instantiated object?
function MediaUser (){
}
MediaUser.prototype.oThumb = {sUrl: 'noImage.png'};
var oMediaUser = new MediaUser();
var oMediaUser2 = new MediaUser();
oMediaUser.oThumb.sUrl = "a.png";
console.log(oMediaUser2.oThumb.sUrl); // prints a.png
Everything you define in prototype is shared by all objects. You have to put that inside the constructor if you want it to be different for all instances:
function MediaUser (){
this.oThumb = {sUrl: 'noImage.png'}
}
var oMediaUser = new MediaUser();
var oMediaUser2 = new MediaUser();
oMediaUser.oThumb.sUrl = "a.png";
console.log(oMediaUser2.oThumb.sUrl); // prints noImage.png
In fact when you are looking for separate value for each object , get rid of thet prototype property altogether
function MediaUser (url){
this.sUrl = url || 'noImage.png';
}
var oMediaUser = new MediaUser("a.png");
var oMediaUser2 = new MediaUser();
console.log(oMediaUser.sUrl); // prints a.png
console.log(oMediaUser2.sUrl); // prints noImage.png
I have this block of code that will create a new instance of MyClass, I want each instances of this class to have an id. So I have a function that will return cnt, and every time the new object is initialized the id value will increase.
var MyClass = (function () {
var Constr, cnt = 0;
Constr = function () {};
Constr.id = function () {
return cnt;
};
Constr.prototype = {
constructor: Constr,
id: Constr.id
};
cnt++
return Constr;
}());
var x = new MyClass();
console.log(x.id);
document.getElementById("1").innerHTML = x.id;
The problem is, I obviously want the value of cnt to be returned, but everything I do returns function() { return cnt; }
Update, deleted fiddle, posted incorrect one.
If you want each instance to have a unique value, then you need to set that value in the constructor for the instance.
You can't inherit the value on the prototype chain. That is what you do when you want every object to have the same value.
You also need to assign the value you want and not a function which will return the value.
Constr = function () {
this.id = cnd;
};
If you want the id to be uniquely assigned for each new instance of your class, then you need to assign the id to your instance data in the Const constructor:
var MyClass = (function () {
var cnt = 0;
// constructor for our object
function Constr() {
// assign a unique id to this object when it is created
this.id = cnt++;
};
// static method (not an instance method) - get current global cnt value
Constr.id = function () {
return cnt;
};
Constr.prototype = {
constructor: Constr,
};
return Constr;
}());
var x = new MyClass();
console.log(x.id);
document.getElementById("1").innerHTML = x.id;
This question shows that perhaps you didn't really understand my comments on your earlier question about the outer function only getting called once. I'd suggest you reread those.
When you do:
x = new MyClass()
it is ONLY executing the Constr function, nothing else. Plus, the .prototype is shared among all instances (that is the point of it) so you can never put a counter there that is unique for each instance.
It seem like all You need is:
var MyClass = (function () {
var cnt = 0;
function Constr() {
this.id = cnt++;
};
Constr.prototype = {
constructor: Constr
};
return Constr;
}());
The following one was my previous BAD answer,
You could replace Constr.id with:
....
Constr.id = new function () {
this.toString = function () {
return ++cnt;
}
};
....
and then You should get it from the instance with
var x = new MyClass();
console.debug(x.id);
but take care that it will be an object and only when used as a string, (like in console.debug, or with .innerHTML= "..." ) will be a string.
Hope it helps.
How come newperson4 is created, and not errored? code below -
function person() {
}
var p = new person();
var q = null;
var r = "some string";
var newperson1 = Object.create(p); //Runs fine.
var newperson2 = Object.create(q); //Runs fine.
var newperson3 = Object.create(r); //Errors - Object.prototype requires to be an Object or Null only. Fine!
var newperson4 = Object.create(person); //Based on above error, person is a function, not an object. How is it working?
Every function is an object in javascript (like arrays are objects), not a primitive value. It can have properties, and you can inherit from it.
I am having some trouble understanding function scope in JavaScript:
function Person() {
var _firstName;
var _lastName;
}
personOne = new Person();
personOne._firstName = "Fred";
alert(personOne._firstName);
This outputs "Fred", but I thought the variables of the Person function would only be accessible inside the function. Why does it work?
In JavaScript, objects are dynamically-expandable.
For example:
var obj = {};
obj.firstName = "MatÃas"; // <-- This adds the property even if it doesn't exist
In the other hand, if you want to declare properties that should be part of the object in the constructor function you need to qualify them with this:
function Person() {
this._firstName = null;
this._lastName = null;
}
Extra info
If you want to avoid objects from being dynamically-expandable, you can use the ECMA-Script 5 Object.preventExtensions function:
var obj = {};
Object.preventExtensions(obj);
// This property won't be added!
obj.text = "hello world";
Because in the line:
personOne._firstName = "Fred";
You assigned a new property to the object with a value of "Fred". It has nothing to do with the (internally-scoped) variable you declared inside the function.
And in the following line, you're actually alerting the value of the newly-created property and not the variable.
See MDN
It works because you create the property _firstName for the object Person.
personOne._firstName = "Fred"; // here you create the property
In the example below I highlighted the fact that _firstName is innacesible.
function Person() {
var _firstName= "Fred";;
var _lastName;
}
personOne = new Person();
alert(personOne._firstName); // output: "undefined"
If you want to make them accesible you can make use of this to add a new property to the object.
function Person() {
var self = this;
self._firstName= "Fred";
var _lastName;
return self;
}
var personOne = new Person();
alert(personOne._firstName); // output: "Fred"
In this line:
personOne._firstName = "Fred";
you are actually creating the property _firstName of the object. it is not the same as the var you created in the constructor function. You can always add new properties to a JavaScript object. Each property of an object is accessible. There is no such thing as a private property.
Due to function scope you will not be able to change the variables inside Person() from outside if you do not make methods available in Person to set the values of those variables.
function Person(firstName, lastName) {
var _firstName = firstName, _lastName = lastname;
this.getFullName = function () {
return _firstName + " " + _lastName;
};
}
var someone = new Person("Some", "one");
someone._firstName = "something else"; // creates new property in the object someone
var fullName = someone.getFullName(); // still returns "some one"
You cannot reference _firstName inside the object declaration. If you want to access the object property you need to declare with this, otherwise the _firstName or _lastName are considered local variables.
So to access the _firstName or _lastName as object properties, you have to declare as in the following way:
function Person() {
this._firstName = "John";
this._lastName = "Doe";
}
You may access _firstName and _lastName after you instantiate the Person.
personOne = new Person();
personOne._firstName = "Fred";
This way you will override the properties already defined in the object constructor. In your case because _firstName is declared inside the Object definition the scope of that variable is bind locally to that object. But when you instantiate the object you assign a new property which extends the originally declared object.
The most widely accepted pattern is to bind the object properties on the object declaration, but declare the object methods on their prototype level.
Like so:
function Person() {
this._firstName;
//...
}
Person.prototype = function() {
getName : function() {
//...
},
setName : function(name) {
this._firstName = name;
}
}
JS objects objects are "expandable", you can add properties dinamically.
function Person() {
var _firstName;
var _lastName;
}
var personOne = new Person();
console.log(personOne); // Person {}
personOne._firstName = "Fred";
personOne._age = 20;
console.log(personOne); // Person {_firstName: "Fred", _age: 20}
You don't actually have access to the _firstName created inside the function scope, but rather you create a property with that name on your newly created object.
In order to expose a property, you attach it using this keyword (which is a reference to the newly created object).
function Person() {
console.log(this); // Person {}
this._firstName = "Sam";
console.log(this); // Person {_firstName: "Sam"}
}
I am trying inherit objects in JavaScript. Take a look at this example:
var BaseObject = function() {
};
var ChildObject = function() {
};
ChildObject.prototype.childMethod = function() {
};
ChildObject.prototype = new BaseObject();
ChildObject.prototype.constructor = ChildObject();
However, as soon as I do prototypal inheritance, the childMethod() disappears. What am I doing wrong here?
You are overwriting the prototype when you assign it to BaseObject and BaseObject's prototype has no childMethod method.
To get the desired behavior you have to add childMethod after assigning the prototype to BaseObject:
var BaseObject = function() {
};
var ChildObject = function() {
};
ChildObject.prototype = new BaseObject();
ChildObject.prototype.constructor = ChildObject;
ChildObject.prototype.childMethod = function() {
return 'childMethod';
};
c = new ChildObject();
alert(c.childMethod());
Basically when you set create ChildObject
var ChildObject = function() {
};
ChildObject.prototype is pointing to a instance of Object, so when you add childMethod to prototype of ChildObject this method is added to that object.
But in this 2 lines you are replacing ChildObject prototype with new instance of BaseObject which does not know anything about childMethod
ChildObject.prototype = new BaseObject();
ChildObject.prototype.constructor = ChildObject();
Also I believe it should be
ChildObject.prototype.constructor = ChildObject;
So it creates circular reference.