var simpleObject={n:70};
simpleObject.testMethod=function(){
console.log(n);
}
Why do i need to write this.n
inside console.log
to show the output 70
.
var simpleObject={n:70};
simpleObject.testMethod=function(){
console.log(n);
}
Why do i need to write this.n
inside console.log
to show the output 70
.
The 'this' keyword refers to the object itself, the property n is a member of the object, and thus it must be accessed via that namespace 'this.n'.
However if the variable was declared inside the same function (i.e. testMethod), via 'var n = 0', then within that same closure/scope you could access the variable with just 'n' (without 'this').
But the property n is outside the 'testMethod' function scope, and thus must be accessed via the proper namespace - hence 'this.n'.
JavaScript is a dynamic language. This essentially means that it uses dynamic name resolving and function objects. Thus you can take function from one object and assign it to another. Consider this:
var simpleObject={n:70};
simpleObject.testMethod=function(){console.log(this.n);}
var simpleObject2={foo:42};
simpleObject2.testMethod = simpleObject1.testMethod;
simpleObject.testMethod();
simpleObject2.testMethod();
Both objects here are using the same function, first call will print 70. But second will print undefined
.
this
is not necessary, it's just a way to do it. Another trivial way would be simpleObject.n
.
However, it seems that you want the identifier n
to be avaluated to a reference to simpleObject.n
.
Identifiers are resolved using property lookups to the binding object of the environment record of the LexicalEnvironment of the running execution context. Initially, it is [[Scope]]
:
The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:
- Let localEnv be the result of calling NewDeclarativeEnvironment passing the value of the [[Scope]] internal property of F as the argument.
- Set the LexicalEnvironment to localEnv.
To achieve what you want, you need to set the running execution context's LexicalEnvironment to NewObjectEnvironment(this, oldEnvironment).
You can achieve that using the width
statement:
The
with
statement adds an object environment record for a computed object to the lexical environment of the current execution context. It then executes a statement using this augmented lexical environment. Finally, it restores the original lexical environment.
var simpleObject = {n: 70};
simpleObject.testMethod = function(){
with(this) {
console.log(n);
}
};
simpleObject.testMethod(); // 70
However, note that the use of with
is discouraged, and won't work in strict mode.
Another way is taking advantage of the fact that the scope in event handler content attributes is the global one shadowed by the document, the form owner, and the element:
- Let Scope be the result of NewObjectEnvironment(document, the global environment).
- If form owner is not null, let Scope be the result of NewObjectEnvironment(form owner, Scope).
- If element is not null, let Scope be the result of NewObjectEnvironment(element, Scope).
Then, you can let your object be an HTML element, and let your method be an internal raw uncompiled handler:
var el = document.createElement('div');
el.n = 70;
el.setAttribute('onclick', 'console.log(n)');
el.click(); // 70