I want to reference a property in Constructor1 (property1) from Constructor2
and I thought, it was ok by doing this... or should I nest the constructor2 inside the constructor1?
var Constructor2 = function() {
this.method2 = function() {
// how to reference Constructor1.property ???
};
};
var Constructor1 = function() {
this.property1 = true;
this.property2 = false;
this.method1 = new Constructor2();
};
var inst = new Constructor1();
inst.method1.method2();
This seems an example of the delegation pattern.
Your "class" Constructor1 is delegating part of its logic to the "class" Constructor2.
Constructor2 needs to access the properties of the delegator and this can be done passing an instance of the delegator to the delegate:
var Constructor2 = function(delegator) {
this.delegator = delegator;
this.method2 = function() {
console.log(delegator.property1);
};
};
var Constructor1 = function() {
this.property1 = true;
this.property2 = false;
this.method1 = new Constructor2(this);
};
var inst = new Constructor1();
inst.method1.method2();
I think that it would be better to consider Constructor1 and Constructor2 not as constructors but as classes. I understand that they are functions and that they are used to create objects, but usually they get the name of the class they will instantiate.
I'm always getting Cannot set property 'saySomething' of undefined but why?
Am I making a mistake somewhere?
var Person = new Object();
Person.prototype.saySomething = function ()
{
console.log("hello");
};
Person.saySomething();
Debugging tip: You get this ..of undefined errors when you try to access some property of undefined.
When you do new Object(), it creates a new empty object which doesn't have a prototype property.
I am not sure what exactly are we trying to achieve here but you can access prototype of function and use it.
var Person = function() {};
Person.prototype.saySomething = function() {
console.log("hello");
};
var aperson = new Person();
aperson.saySomething();
The prototype property exists on functions, not on instantiated objects.
var Person = new Object();
console.log(Person.prototype); // undefined
var Person2 = function () {}
console.log(Person2.prototype); // {}
This is useful because things put on the prototype of a function will be shared by all object instances created with that function (by using new).
var Person = function() {};
Person.prototype.saySomething = function() {
console.log("hello");
};
console.log(
new Person().saySomething === Person.prototype.saySomething // true. they are the same function
);
If all you want is to add a method to the person object, there's no need for a prototype:
var Person = {};
Person.saySomething = function() {
console.log("hello");
};
Person.saySomething();
You can even use object literal syntax:
var Person = {
saySomething: function() {
console.log("hello");
}
};
Person.saySomething();
i was trying out some code thought of posting it, might help others.
<script>
var MODULE = {};
MODULE = (function (my) {
my.anotherMethod = function () {
console.log("hello ");
};
my.newMethod = function(){
console.log("hi new method ");
}
return my;
}(MODULE));
MODULE.anotherMethod();
MODULE.newMethod();
</script>
And please not var MODULE ={}, if this is not initialized with {} then it give cannot set property.
I know i am late to the party but as you see there is no satisfying answer available to the question so i am providing my own.
In your case when you write
var Person = new Object();
you are creating an instance of Object type.
You can add a property using prototype property to the Object, not to the instance of Object.which you can use by the instance laterly.
so you can define like
Object.prototype.saySomething = function ()
{
console.log("hello");
};
now you can call it like this.
Person.saySomething();
You can check here.
var Person = function(name) {
this.canTalk = true;
this.name = name;
};
Person.prototype.greet = function() {
if (this.canTalk) {
console.log('Hi, I am ' + this.name);
}
};
bob = new Person('bob');
bob.greet();
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Javascript outer scope variable access
I have a javascript module that looks something like below. The main issue I'm having is how to access variables in the "this" scope from the private someOtherFunc. Is there a way to access this.myvar in the private someOtherFunc
var mymodule = (function(){
return {
MyObj : function() {
this.myvar = 123;
this.publicfunc = function() {
someOtherFunc();
};
var someOtherFunc = function() {
//this doesn't seem to work
this.myvar = 456;
};
}
}
}
The idea is that I want to be able to do something like
new mymodule.MyObj().publicfunc, but make the someOtherFunc private
Forget my previous answer. You can do this just by adding a private version of this.
var mymodule = (function() {
return {
MyObj : function() {
this.myvar = 123;
var that = this;
this.publicfunc = function() {
someOtherFunc();
};
var someOtherFunc = function() {
that.myvar = 456;
};
return this;
}
};
});
Bear in mind that, with your code, every time you call MyObj you get a new object.
So this would do what you want:
>var o = new mymodule().MyObj()
>o.myvar
123
>o.publicfunc()
>o.myvar
456
but not this
>var m = new mymodule()
>m.MyObj().myvar
123
>m.MyObj().publicfunc()
>m.MyObj().myvar
123
If that's not what you want, consider doing something like this
var mymodule = (function() {
var myObj = null;
this.MyObj = function() {
if(myObj != null)
return myObj;
myObj = {};
myObj.myvar = 123;
myObj.publicfunc = function() {
someOtherFunc();
};
var someOtherFunc = function() {
myObj.myvar = 456;
};
return myObj;
};
});
Declare myvar using the var keyword, making it private, then access it without the this.:
function MyObj(){
var myvar = 123;
this.publicfunc = function() {
someOtherFunc();
};
var someOtherFunc = function(){
alert(myvar);
};
}
var o = new MyObj();
o.publicfunc();
If you need public access to myvar then create a public getter/setter.
jsFiddle Demo
I think what you're looking for is a way to encapsulate myvar for changes. When some of the other answers run, myvar usually will stay as 123 because the initially returned object from mymodule holds on to that initial value.
Return a function that gets the value of myvar even after it's been modified, and I think that helps your problem.
Here's the code that works for me:
var mymodule = (function(){
var myvar = 123,
publicfunc = function() { myvar = 456 },
getMyVar = function() { return myvar; };
return {
someOtherFunc : publicfunc,
myPublicVar : getMyVar
};
}());
mymodule.someOtherFunc();
alert(mymodule.myPublicVar()); //gives you 456
JSFiddle here.
I hope this helps.
Why not build it a little more deliberately?
// this one returns an object used like:
// myModule.myInt; /* 456 */
// myModule.myFunc(); /* 124 */
var myModule = (function () {
var secretData = 123,
publicData = 456,
publicFunc = function () { return privateFunc(secretData); },
privateFunc = function (num) { return num + 1; },
public_interface = {
myInt : publicData,
myFunc : publicFunc
};
return public_interface;
}());
I went through the trouble of explicitly naming the returned, public object, but it's now very clear what is and isn't public, and yet, each one of those things will have access to the variable versions of one another, with the one exception being that if you change myModule.myInt or publicData, they will no longer be equal.
To demonstrate what I mean in the comments below, creating multiple instances with their own private data/methods, I just add in one more layer of function-scope:
var myModule = (function () {
var static_int = 789,
makeInstance = function (/* any constructor values */) {
var secretData = 123,
publicData = 456,
publicFunc = function () { return privateFunc(secretData); },
privateFunc = function (num) {
console.log(static_int);
return num + 1;
},
public_interface = {
myInt : publicData,
myFunc : publicFunc
};
return public_interface;
};
return makeInstance;
}());
You now use it like:
var newModule = myModule(/* instance parameters */);
newModule.myFunc();
...or
var num = myModule(/* instance parameters */).myFunc();
If you wanted to save memory, you could have static helper functions inside of the static-layer:
var myModule = (function () {
var static_int = 789,
static_addOne = function (num) { return num + 1; },
static_divideBy = function (dividend, divisor) { return dividend/divisor; },
makeInstance = function (/* any constructor values */) {
var secretData = 123,
publicData = 456,
publicFunc = function () { return privateFunc(secretData); },
privateFunc = function (num) {
console.log(static_int);
return num + 1;
},
public_interface = {
myInt : publicData,
myFunc : publicFunc
};
return public_interface;
};
return makeInstance;
}());
And now you have "private" functions which are only written one time (ie: you save memory), but any instance can use those functions.
Here's the catch:
Because of how scope and closure work, the static functions have NO access to values inside of the instance (functions inside have access to the static functions, not the other way around).
So, any static helper functions MUST have the values passed to them as arguments, and if you're modifying a number or a string, you MUST return the value out of that function.
// inside of a private method, in any instance
var privateString = "Bob",
privateFunc = function () {
var string = static_helper(privateString);
privateString = string;
//...
};
You don't return anything from MyObj.
return this;
should fix it.
Use the bind method:
var someOtherFunc = function() {
this.myvar = 456;
}.bind(this);
The standard prototypal inheritance in JavaScript is as follows:
function Animal() {
this.legs = 0;
}
Animal.prototype.move = function () {
alert("I'm moving!");
}
Bird.prototype = new Animal();
Bird.prototype.constructor = Bird;
function Bird() {
this.legs = 2;
this.wings = 2;
}
Bird.prototype.move = function () {
alert("I'm flying!");
}
Does the function definition for Bird have to come after the assignment of Bird's prototype and constructor. I ask this because I'm trying to do this from within a namespace, and variable hoisting is causing my code to fail. As an example:
var namespace = {};
namespace.Animal = function () {
this.legs = 0;
};
namespace.Animal.prototype.move = function () {
alert("I'm moving!");
};
namespace.Bird.prototype = new namespace.Animal();
namespace.Bird.prototype.constructor = namespace.Bird;
namespace.Bird = function () {
this.legs = 2;
this.wings = 2;
};
namespace.Bird.prototype.move = function () {
alert("I'm flying!");
};
Thanks to hoisting the namespace.Bird.prototype assignment statement and the namespace.Bird.prototype.constructor assignment statement fail. If I move the namespace.Bird function assignment above those two lines as shown in the following code block, however, the code seems to work.
namespace.Bird = function () {
this.legs = 2;
this.wings = 2;
};
namespace.Bird.prototype = new namespace.Animal();
namespace.Bird.prototype.constructor = namespace.Bird;
However, I don't know if there's a specific reason why most resources show the original order rather than having the function assignment come first.
Can someone please clarify?
Thanks!
The reason has to do with parse-time availability of functions and runtime availability of functions.
For example:
var afunc = asdf;
function asdf(){}
is the same as
function asdf(){}
var afunc = asdf;
But,
var afunc = asdf;
var asdf = function(){};
is not the same as
var asdf = function(){};
var afunc = asdf;
Does that make sense why?
Also, the answers to this question would probably help you
var functionName = function() {} vs function functionName() {}
let's say I have code like this:
var object1 = {};
object1.class1 = function() {
this.property1 = null;
this.property2 = 'ab';
}
in this case, what does 'this' stand for? object1 or class1? And whenever I want to define a class constructor inside an object, what is the best way to do it?
For class1, because you can't make an object of type object1.
However, if the code would be:
function object1() {
this.class1 = function() {
this.property1 = null;
this.property2 = 'ab';
}
}
You could have:
var obj = new object1();
obj.class1();
obj.property2; // => 'ab';
var cls = new obj.class1();
cls.property2; // => 'ab';
So it could depend on context.
If you call it like so:
object1.class1();
Then this will refer to object1.