-1
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.

Matt
  • 3,508
  • 6
  • 38
  • 66
user2485435
  • 125
  • 9
  • 4
    Because that's how JavaScript works. This question is too broad. What problem in particular do you have? – elclanrs Apr 11 '15 at 20:05
  • A property needs to have a name. `n` is the name of the property, 70 is its value. – arkascha Apr 11 '15 at 20:06
  • I don't have a problem but as a newbie who is habitual in C#. This is weird – user2485435 Apr 11 '15 at 20:07
  • 2
    JavaScript does not have an "implicit self" - it is similar to Python in this aspect, and unlike C# or Java. *It is simply how the language is.* The "solution" to this "problem" is to learn the language and understand/accept it. – user2864740 Apr 11 '15 at 20:07
  • PLease go through what 'this' mean in javascript. w3schools give a very good explanation for it. – Gaurav Kumar Apr 11 '15 at 20:25
  • You do not need to. [You can use `simpleObject.n` just as well](http://stackoverflow.com/q/10711064/1048572) – Bergi Apr 11 '15 at 20:44
  • You'll want to have a look at [Javascript: Do I need to put this.var for every variable in an object?](http://stackoverflow.com/a/13418980/1048572) (it's about constructors not methods, but that doesn't matter) – Bergi Apr 11 '15 at 20:46
  • Gaurav Sir i don't know too much but i know that "this" refers to the current object.It is a keyword;which if used inside the context of function refers to the object on which the function is executed. Bergi Sir nothing against but why would i write simpleObject.n when that can be achieved only by writing n. – user2485435 Apr 11 '15 at 20:56

3 Answers3

0

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'.

Chris Mendes
  • 111
  • 4
  • Sir i understood the concept i asked because the same concepts works differently in C#,JavaScript. I know javascript will try to resolve n first inside the function by looking at parameters and local declaration and then it will go for global object properties. If not found Reference error is coming. I just wanted to know why JavaScript is not trying to resolve in the object itself before looking for global object and then ending up in Reference error. Why its Scope Chain doesn't have method own object before global object. – user2485435 Apr 11 '15 at 20:16
  • 1
    @user2485435 Because that is how JavaScript works.. it is [clearly defined in the specification](https://es5.github.io/). As to *why* it was originally designed as such, that can only be speculated at. This is actually a *good* thing for JavaScript as it requires less dynamic traversals and allows a wider range of optimizations; these reasons also correlate with why `with` is forbidding in strict-mode - but are these "the reasons" of the *language design decision*? *:shrug:* – user2864740 Apr 11 '15 at 20:30
  • Cool....Thanks all for being so supportive in helping me reaching at some consensus.Respect – user2485435 Apr 11 '15 at 20:37
  • Apologies for not providing the answer you were looking for. But your question was very short and simple. If you already have a sound understanding on the subject and actually mean to ask the question from a specific point of view as you've explained (i.e. in comparison with other languages), then next time I'd suggest being more clear so we can be more helpful. – Chris Mendes Apr 14 '15 at 14:19
0

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.

c-smile
  • 26,734
  • 7
  • 59
  • 86
  • yes Had you declared n as an property to simpleObject2 you wouldn't have got undefined. My problem is why JavaScript is not going for object simpleObject for resolution of n if i don't use this this keyword. – user2485435 Apr 11 '15 at 20:27
  • How that function would know what `n` do you mean? It could be global `var n` or `this.n`. In static languages like C# that name resolution is done by compiler at compile time. Consider `this.` construct as a namespace declaration meaning "member variable". Each dynamic language has its own namespace conventions. Like in PHP `this.n` can be written as `$n`, etc. – c-smile Apr 11 '15 at 20:35
0

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]]:

10.4.3 Entering Function Code

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:

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:

  1. Let Scope be the result of NewObjectEnvironment(document, the global environment).
  2. If form owner is not null, let Scope be the result of NewObjectEnvironment(form owner, Scope).
  3. 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
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • Here also you have specifically informed JavaScript running in non strict mode to refer simpleObject for resolution why not automatically. – user2485435 Apr 11 '15 at 20:30
  • Please correct me if i'm wrong there is a scope chain which JavaScript has for variable value resolution. for my code Javascript first looks inside testMethod i.e. parameters and local declarations and then it moves to global object. My problem is why it skips simpleObject itself. He should have targeted simpleObject property also. – user2485435 Apr 11 '15 at 20:33
  • @user2485435 That could happen, if the spec said so. But it doesn't. – Oriol Apr 11 '15 at 20:42
  • 1
    I don't think this answer is helpful for a newbie who doesn't understand the difference between variables and properties. Introducing `with` and the weird scoping in event handler attributes is just confusing, not explaining anything. – Bergi Apr 11 '15 at 20:49
  • @Bergi I wasn't trying to explain how it works. I was trying to demonstrate that the question is flawed because it assumes that `this` is necessary, but that is not entirely correct. – Oriol Apr 11 '15 at 21:57
  • Yeah, but `simplemodule.n` would work as well and doesn't use `this`. No need to get to the advanced stuff :-) – Bergi Apr 11 '15 at 21:59