javascript inheritance for namespace - javascript

i am new to oop in javascript.
var obj1 = {
name : 'honda',
getName : function(){
console.log(this.name);
}
}
var obj2 = {name:'maruti'};
I want to access getName of obj1 with scope of obj2, like obj2.getName().

Is this what you want:
obj1.getName.call(obj2);
As #roland said, you can also use .apply(obj2, [arr of args]) if you want to provide an array of arguments to the method.
EDIT:
If you want to import all obj1 methods into obj2, you can do that with pure JavaScript:
for (var m in obj1) {
// if you want to copy obj1's attributes, remove this line
if (obj1[m] instanceof Function) {
obj[2][m] = obj1[m];
}
}
Or you can do it with jQuery:
$.extend(obj2, obj1);

If are looking to use obj1 as a template for creating new objects, you can use Object.create to do this.
var obj1 = {
name : 'honda',
getName : function(){
console.log(this.name);
}
}
var obj2 = Object.create(obj1);
obj2.name = 'bob';
obj2.getName(); // outputs 'bob'

Related

Construct an object that has member functions from an object that has no member function with their properties are the same?

I am trying to build a javascript app with a document database that can store and retrieve object data (provided as api) without function members.
Now I have a class which have many properties and some functions as prototype.
Project: function(){
this.a= 'abc';
this.f = function(){
console.log(this.a);
}
}
//object from the databse
p0 = {
a: 'abc';
}
I want to convert a plain object to an object with member function usable.
When I try something like this, it won't work:
// It won't work:
// for it needs a map that have many properties such as writable etc.
var pobj = Object.create(new Project(), p0);
I tried to search this question with different keywords on the internet, but I didn't find one related.
The function you probably want to use is Object.assign.
So you can use Object.create to create an instance of the class (using the prototype), then assign the values from the data onto the new instance and then call the constructor (make sure to not override the values).
function Project() {
if (this.foo === undefined) this.a = 'foobar';
return this;
}
Project.prototype.print = function() {
console.log(this.foo);
};
var data = {
foo: 'bar'
};
var obj = Object.create(Project.prototype); // empty instance
obj = Object.assign(obj, data); // copy data
obj = obj.constructor(); // start constructor
obj.print();
Alternatively you could create a new instance using the new operator and then assign the data.
function Project() {
this.a = 'foobar';
return this;
}
Project.prototype.print = function() {
console.log(this.foo);
};
var data = {
foo: 'bar'
};
var obj = Object.assign(new Project(), data);
obj.print();
Unrelated note
It's usually a good idea to declare public functions that don't require closure outside the function body using class.prototype.functionName = function(){...}

undefined output while printing object in console

Suppose i have a object with properties and method.
When i assign this object to another object, and i execute following code. Its giving me undefined undefined output while printing object obj1 in console, can anyone please help me on this, and explain me this behaviour.
thank you.
var emp = {
fname: "sachin",
lname: "pawar",
getname: function() {
return this.fname + " " + this.lname;
}
};
var obj = emp.getname;
var obj1 = obj();
var obj3 = emp.getname();
console.log(obj1);
The issue is that this in your getname method is undefined when called via the line:
var obj1 = obj();
In JavaScript this is dependent upon the context in which the function is called. So, when you call it as a 'dot method' against the emp object this refers to its containing object. Where you call it 'stand alone' it has no contect and this is undefined.
You can bind a standalone call to give it a context, as follows:
var obj=emp.getname.bind(emp);
var obj1=obj();
Then when it executes it will use emp to get its context for this.
When you do obj = emp.getname, its reference is copied and when you call it, there is a difference in obj.function() and function().
When you do obj.function, function's this is set as obj, but when you copy reference and call it, since no object is associated to this call, it takes global scope(window). Hence it returns undefined.
Sample
window.fname = "Foo";
window.lname = "Bar";
var emp = {
fname: "sachin",
lname: "pawar",
getname: function() {
return this.fname + " " + this.lname;
}
};
var obj = emp.getname;
var obj1 = obj();
var obj3 = emp.getname();
console.log(obj1);
console.log(obj3);
Alternate implementation
var emp = (function() {
// private properties
var fname = "sachin"
var lname = "pawar"
var getname = function() {
return fname + " " + lname;
}
// Selected properties exposed
return {
getname: getname
}
})()
var obj = emp.getname;
var obj1 = obj();
var obj3 = emp.getname();
console.log(obj1);
console.log(obj3);

JavaScript's Object.create method

i have created an object as follows
var lassie = {
name: 'Lassie',
breed: 'Collie',
speak: function () {
return 'Woof! Woof!'; }
};
I create another object by using Object.create method of javascript as
var obj = Object.create(lassie);
now when i console obj it gives me a blank object.
But when i console obj.speak() it gives me 'Woof! Woof!' .
can someone please explain why?
Pass lassie as first parameter to Object.create() to set prototype of obj to lassie; iterate lassie return properties as second parameter
var lassie = {
name: 'Lassie',
breed: 'Collie',
speak: function() {
return 'Woof! Woof!';
}
};
var obj = Object.create(lassie, (function() {
var _obj = {};
for (var prop in lassie) {
_obj[prop] = {
value: lassie[prop],
writable: true,
enumerable: true,
configurable: true
}
}
return _obj
}()));
alert(obj.speak())
var obj = Object.create(lassie);
By doing this you have created a new object which inherits the properties from lassie.
if you do
obj.name; //this prints "Lassie" too.
Basically Object.create will create an object that would have no own properties. That means the passed object's own properties would be assigned as the prototype properties of the newly created object and that would be returned.
A sample structure of the object returned from Object.create(),
var obj = {a:10};
var obj1 = Object.create(obj);
console.log(obj1); // {... __proto__ : {a : 10 ...}}
If you want to copy the own propties(enumerable) of the passed object to another one object, then you have to can Object.assign(obj) as an alternate to passing second parameter as property descriptor properties for Object.create
var lassie = {
name: 'Lassie',
breed: 'Collie',
speak: function () {
return 'Woof! Woof!'; }
};
var obj = Object.create(lassie);
Now your concern is now when You console obj it gives me a blank object. But when you console obj.speak() it gives you 'Woof! Woof!' .
Actually here obj has now all the properties of lassie ,but these are not the obj own properties.
Here you will see all the properties of obj:
for(var a in obj){
console.log(a);
}
Here you will see obj's own property:
for(var b in obj){
if (obj.hasOwnProperty(b)) {
console.log(b);
}
}
This is actually because when we use var target = Object.create(obj);
then all the properties are added to target as a prototype properties.

Neat way to handle this inheritance code in javascript?

Say I have the following code:
function MyObject() {
EventTarget.call(this);
}
MyObject.prototype = new EventTarget();
MyObject.prototype.constructor = MyObject;
MyObject.prototype.foo = someFunction;
MyObject.prototype.bar = someOtherFunction
Is there a neat way to avoid defining MyObject.prototype.something = something in each line.
Do I have to define two objects and merge them? or is there some cleaner way to do the same thing?
Declare the functions inside the controller and you won't have to attach them to the prototype. Is this what you were after?
function EventTarget() {
this.baz = function() {console.log("baz")};
this.foobar = "foobar";
}
function MyObject() {
EventTarget.call(this);
this.foo = function() {console.log("foo")};
this.bar = function() {console.log("bar")};
}
MyObject.prototype = new EventTarget();
MyObject.prototype.constructor = MyObject;
thisObject = new MyObject();
thisObject.foo(); // outputs 'foo'
thisObject.bar(); // outputs 'bar'
thisObject.baz(); // outputs 'baz' via inheritance
console.log(thisObject.foobar); // outputs 'foobar' via inheritance
http://jsfiddle.net/kFUDy/
See the various links mentioned in this answer: Extending an Object in Javascript

Argument in reference

I have an object:
obj = {
obj1: {
name: "Test";
}
}
and function:
var anon = function(a) {
alert(obj.a.name);
}
I want to give as an argument "obj1". Im newbie to programming so I think I should get alert with "Test" but it doesn't work. How to give reference with argument?
You can do this way: You can always access properties of the object as obj[key], thats what we are doing here.
var anon = function(a) {
alert(obj[a].name);
}
and remove ; from the inline object property definision syntax.
obj = {
obj1: {
name: "Test"; //<-- Here
}
}
http://jsfiddle.net/RuCnU/
This Link can provide you some basic insight on object and keys.
var anon = function(a) {
alert(obj[a].name);
}
When you are looking up the property of an object using a string use square brackets, the obj.a will only work if the object has a property named a, for example obj = {a: "Test"}.

Categories