access variable in object from another function - javascript

I am trying to access the variable myVar inside myObject from MyFunction, but get this error
Uncaught TypeError: Cannot read propperty 'myVar' of undefined
when running the code below.
var myObject;
function MyObject(){
this.myVar = 500;
MyFunction();
}
function MyFunction(){
alert(myObject.myVar);
}
myObject = new MyObject();
I have read this but still can't figure out how to access it.

When calling a function it's executed, and then the result is returned to the variable.
So, the function executes first, then the result is passed back to the variable
var myObject; // 1. new variable, undefined
function MyObject(){ // 3. execute function
this.myVar = 500; // 4. set a property
MyFunction(); // 5. call next function
}
function MyFunction(){
alert(myObject.myVar); // 6. myObject is still undefined,
} // result hasn't returned yet
myObject = new MyObject(); // 2. call function - 7. When everything is done
// executing, the result
// is returned
In other words, you can't do that.
One way to solve this would be to prototype the MyFunction and keep the value of this constant
function MyObject() {
this.myVar = 500;
this.MyFunction();
}
MyObject.prototype.MyFunction = function() {
alert(this.myVar);
}
var myObject = new MyObject();
FIDDLE

The problem is that myObject is assigned AFTER calling MyObject, so if inside it, myObject is still undefined.
Some alternatives:
function MyObject(){
this.myVar = 500;
myFunction.call(this); // Pass object as `this`
}
function myFunction(){
alert(this.myVar);
}
var myObject = new MyObject();
or
function MyObject(){
this.myVar = 500;
myFunction(this); // Pass object as argument
}
function myFunction(obj){
alert(obj.myVar);
}
var myObject = new MyObject();
or
var myObject;
function MyObject(){
this.myVar = 500;
}
function myFunction(obj){
alert(myObject.myVar);
}
var myObject = new MyObject(); // Now myObject is set
myFunction(); // Call `myFunction` after `MyObject`, not inside it.
or
var myObject;
function MyObject(){
this.myVar = 500;
this.myFunction(); // Prototype method
}
MyObject.prototype.myFunction = function(){
alert(this.myVar);
}
var myObject = new MyObject();
or
var myObject;
function MyObject(){
var that = this;
function myFunction(){ /* Place myFunction inside MyObject. Note that this
way each instance will have a copy of myFunction */
alert(that.myVar);
}
this.myVar = 500;
myFunction();
}
var myObject = new MyObject();

a good article you can find HERE
here is an example of defining a function like you wanted: FIDDLE
function MyObject() {
this.myVar = 500;
this.MyFunction();
}
MyObject.prototype.MyFunction = function() {
alert(this.myVar);
};
myObject = new MyObject();

(I think you know myObject and MyObject are different things (even unrelated to the interpreter, just their names are similar), but maybe that caused your confusion, so I'll just state this.)
What the interpreter will do is first evaluate the left-hand side of the assignment (new MyObject()) and then stuff it into the variable myObject. This means, that when you call function MyObject() { ... } the variable myObject has not yet been initialised`. Obviously (now), it is undefined, hence the error.
There are different ways to solve this, Omri Aharon's is one possibility.

Related

why prototype has to be declared outside of the constructor?

havng such a code:
function A(){
var a=7;
this.fun = function(){
return a*2;
}
}
function B(){
var a =8;
}
it is obvous that in order to refernce B prototype to A we need to add a line:
B.prototype = new A();
I am wandering why it is not valid to make such a code:
function A(){
var a=7;
this.fun = function(){
return a*2;
}
}
function B(){
var a =8;
this.prototype = new A();
}
when we would need to put prototype inside declaration on B, we would need to make it via:
function B(){
var a =8;
this.__proto__ = new A();
}
and such code will not work:
function B(){
var a =8;
}
B.__proto__ = new A();
and now I am loosing it - why it is like that? Why we have to declare prototype outside of a function and we cannot declare it within, and why it is just opposite for proto ?
1) var A = function () {
this.x = function () {
//do something
};
};
2) var A = function () { };
A.prototype.x = function () {
//do something
};
In first case, variable A is assigned a value that is a reference to a function. When that function is called using A(), the function's this isn't set by the call so it defaults to the global object and the expression this.x is effectively window.x. The result is that a reference to the function expression on the right hand side is assigned to window.x.
In the second case, in the first line, variable A is assigned a reference to a function. In JavaScript, all functions objects have a prototype property by default so there is no separate code to create an A.prototype object.In the second line, A.prototype.x is assigned a reference to a function. This will create an x property if it doesn't exist, or assign a new value if it does. So the difference with the first example is which object's x property is involved in the expression.

How to access from 'private method' to 'public variable', in Javascript class

First, See my code plz.
function test(){
this.item = 'string';
this.exec = function(){
something();
}
function something(){
console.log(this.item);
console.log('string');
}
}
And I made class and call 'exec function', like this code
var t = new test();
t.exec();
But result is...
undefined
string
I wanna access from something function to test.item.
Have you any solution?
You need to call something with apply so that this is properly set inside of something:
function test(){
this.item = 'string';
this.exec = function(){
something.apply(this);
}
function something(){
console.log(this.item);
console.log('string');
}
}
As #aaronfay pointed out, this happens because this doesn't refer to the object that new test() created. You can read more about it here, but the general rule is:
If a function is invoked on an object, then this refers to that object. If a function is invoked on its own (as is the case in your code), then this refers to the global object, which in the browser is window.
You have many choices, but I recommend the last one.
var item = 'string'
or
this.exec = function(){
something.apply(this, []);
}
or
var that = this;
function something(){
console.log(that.item);
console.log('string');
}
this.item in something() isn't what you think it is.
The this value is different. In this case, it's the global object.
The best solution, in my opinion, is to declare a variable with a reference to this, that can be accessed inside the inner function.
function test() {
var that = this; // a reference to 'this'
function something() {
console.log(that.item); // using the outer 'this'
console.log('string');
}
this.item = 'string';
this.exec = function(){
something();
}
}
Why not just define something like this:
Fiddle
function test(){
this.item = 'string';
this.exec = function(){
this.something();
}
this.something = function(){
console.log(this.item);
console.log('string');
}
}
var t = new test();
t.exec();
// output:
// string
// string

Javascript Difference between normal function and function object

In Javascript, the way to create classes (or objects) is to use;
function MyObj()
{
this.someVar = "xyz";
this.someMethod = function(){}
}
My simple question is how different is this function from a normal JavaScript function...say a function which adds 2 numbers?
The function aren't different. What makes the difference is how you call them.
For example, those have the same effect :
function MyObj(){
this.someVar = "xyz";
this.someMethod = function(){
console.log(this.someVar);
}
}
var obj = new MyObj();
obj.someMethod();
and
function someMethod(){
console.log(this.someVar);
}
function MyObj(){
this.someVar = "xyz";
}
var obj = new MyObj();
someMethod.call(obj);
and
function someMethod(){
console.log(this.someVar);
}
function MyObj(){
this.someVar = "xyz";
}
var obj = new MyObj();
obj.f = someMethod;
obj.f();
As you tagged your question prototypal-inheritance, I'll complete by saying the best way to build your function would have been this one :
function MyObj(){
this.someVar = "xyz";
}
MyObj.prototype.someMethod = function(){
console.log(this.someVar);
}
var obj = new MyObj();
obj.someMethod();
This way, all instances of MyObj share the same function and thus are lighter.
The difference is not so much in the contents of the function, but in how you call it.
If you call var myObj = new MyObj() then a new object is created. By convention functions intended for use like this start with a capital letter.
If you were to call the function without the new keyword then exactly the same things happen inside the function, except that this will be the global object instead of the newly created object. This wouldn't matter in a simple "add 2 numbers" function, but can cause very odd bugs if you forget it.
One way to ensure that it doesn't matter if you forget the new call is to put this in the top of your function:
function MyObj() {
if (! (this instanceof MyObj)) {
return new MyObj();
}
...
}
None. What matters is the use of the new keyword.
See here:
function Fun(){
this.method = function(){
return "Bar";
}
return "Foo";
}
var value = Fun(); // assigns the return value of Fun() to value
alert(value); // "Foo"
// alert(value.method()); // won't work because "Foo".method doesn't exist
var instance = new Fun(); // assigns a new instance of Fun() to instance
alert(instance); // [object Object]
alert(instance.method()); // "Bar"

How to call a prototype function inside another prototype function without losing context

I have this CODE:
var MyObj = (function() {
//Constructor
var MyObj= function(){
this.myArray = [1,2,3];
}
MyObj.prototype = {
myFunc: function(){
alert(this.myArray.toString());
},
myFuncCaller: function(){
MyObj.prototype.myFunc();
}
};
return MyObj;
})();
var myObj = new MyObj();
myObj.myFunc();
//This line will throw an exception because this.myArray is undefined
myObj.myFuncCaller();
​
Why is this.myArray undefined?
I know I'm doing something wrong, how would be the correct way to do it?
Just use this:
this.myFunc();
When you call a function in Javascript, this is set to the expression you called it on.
In your code, for example, this in myFunc() is MyObj.prototype.

Is it possible for a function called from within an object to have access to that object's scope?

I can't think of a way to explain what I'm after more than I've done in the title, so I'll repeat it. Is it possible for an anonymous function called from within an object to have access to that object's scope? The following code block should explain what I'm trying to do better than I can:
function myObj(testFunc) {
this.testFunc = testFunc;
this.Foo = function Foo(test) {
this.test = test;
this.saySomething = function(text) {
alert(text);
};
};
var Foo = this.Foo;
this.testFunc.apply(this);
}
var test = new myObj(function() {
var test = new Foo();
test.saySomething("Hello world");
});
When I run this, I get an error: "Foo is not defined." How do I ensure that Foo will be defined when I call the anonymous function? Here's a jsFiddle for further experimentation.
Edit: I am aware of the fact that adding the line var Foo = this.Foo; to the anonymous function I pass in to my instance of myObj will make this work. However, I'd like to avoid having to expose the variable inside the anonymous function--do I have any other options?.
Should be this.Foo:
var test = new myObj(function() {
var test = new this.Foo();
test.saySomething("Hello world");
});
http://jsfiddle.net/grzUd/5/
Or alternatively using with:
var test = new myObj(function() {
with (this) {
var test = new Foo();
test.saySomething("Hello world");
}
});
http://jsfiddle.net/grzUd/6/
Change var test = new Foo(); to var test = new this.Foo();.
Edit: Or you could pass it as a parameter.
function myObj(testFunc) {
this.testFunc = testFunc;
var Foo = function (test) {
this.test = test;
this.saySomething = function(text) {
alert(text);
};
};
this.testFunc(Foo);
}
var test = new myObj(function(Foo) {
var test = new Foo();
test.saySomething("Hello world");
});
You seem to be confused about the difference between identifier resolution on the scope chain and property resolution.
Foo is a property of an instance of myObj (i.e. it's an object property). Calling new Foo will resolve Foo as a variable on the scope chain, which isn't the right place to look for it. That's why Petah's answer tries to use with, to put the object properties of the this object on the scope chain.

Categories

Resources