var name = "Window Object";
var a = {
name: 'manish',
getName: function() {
return this.name;
}
}
b = (a.getName = a.getName)();
console.log(b, window);
Above is the code that I had written on JSFiddle.
Here is the link: https://jsfiddle.net/shettyrahul8june/o49jn5fm/
Variable b returns result instead of Window Object. I saw that in the Window object there is a property called name which has result stored as string. But I am not sure why my global variable a didn't override that variable. Thanks in anticipation.
Edit: Guys I think I wasn't clear with my question. I know it's referencing the window object's name from JSFiddle. But I have also written var name = "Window Object".
Why my variable name didn't over ride Window objects name because I think even var name that I have declared should have got attached to window object. Is it because, the fiddle has a wrapper object where name gets assigned like
JSFiddleWrapper = {
name: "Window Object"
}
and hence it's referencing window.name?
There is something interesting whe you are doing a.getName = a.getName. The a.getName function is reassigned to the same . The parenthesis just returns that function with the Window as its context. So when inside the function you do this, it refers to the Window object.
var name = "Window Object";
var a = {
name: 'manish',
getName: function() {
return this.name;
}
}
b = (a.getName = a.getName)();
console.log(b);
You can use bind to change the context. Check the following snippet:
var name = "Window Object";
var a = {
name: 'manish',
getName: function() {
return this.name;
}
}
b = (a.getName = a.getName).bind(a)();
console.log(b);
In JavaScript, this behaves very different from most other languages. Its precise behavior depends entirely on how the function is called, notice:
console.log(a.getName(), window); // manish Window
This correctly gets name from a, because this is inferred to refer to the object on the left of the period. But here:
f = a.getName;
console.log(f(), window); // result Window
The function, f, is in a sense 'unbound' from the object at the time it's called, and so this is inferred to refer to the Window itself (in JSFiddle the name of the window in the result panel is 'result').
One fairly easy way to solve this is to use the bind method:
b = (a.getName = a.getName.bind(a))();
console.log(b, window); // manish Window
Related
In the console tab of chrome developer tools, I typed this, and it has shown Window object. How this becomes window object here?
console.log(this);
Consider below snippet
var firstname = "Javascript";
var lastname = "Lover - SKT";
function getName() {
this.firstname = "Sivakumar";
this.lastname = "Tadisetti";
}
console.log(firstname);
getName();
console.log(this.lastname); // How this.lastname is working here?
I've read the following StackOverflow answers
what does this mean
this in javascript
But didn't understand how the above snippet is working (The line I commented)
Update:
I have tried above code snippet in jsfiddle where it outputs this.firstname is undefined. So that's the reason I am asking this question. But in the stackoverflow code snippet it is working fine
In your function, this is the same as window (or whatever the global context is in your runtime). If it was a Class method, this would be the Class instance.
You can change this by using bind, or specifying it using apply and call.
Global Function Example
var that = {}
function getTest() {
console.log(this === window ? "this is window" : "this is not window")
}
getTest()
getTest.call(that)
getTest.apply(that)
getTest.bind(that)()
Lambda Example
If you use lambda syntax, this is bound to this at time of calling and cannot be changed.
let that = {}
let fn = () => {
console.log(this === window ? "this is window" : "this is not window")
}
// this is always window. You CANNOT this on a lambda.
fn()
fn.call(that)
fn.apply(that)
fn.bind(that)()
Class Example
class Foo {
fn() {
console.log(this === window ? "this is window" : "this is not window")
}
// Static methods do not have a `this`, but it can be defined by call and apply, but not bind.
static fnStatic() {
console.log(this === window ? "this is window" : "this is not window")
}
}
// this is Class instance, NOT window
new Foo().fn()
// Change this from class instance to window
new Foo().fn.call(window)
new Foo().fn.apply(window)
new Foo().fn.bind(window)()
// this is undefined in a static method, unless you apply or call. YOU CANNOT BIND a static method
Foo.fnStatic()
Foo.fnStatic.call(window)
Foo.fnStatic.apply(window)
// YOU CANNOT BIND
Foo.fnStatic.bind()(window)
In global scope, this is actually points to window object. By invoking getName you are doing the same as if:
window.firstname = "Sivakumar";
window.lastname = "Tadisetti";
In the global execution context (outside of any function), this refers to the global object whether in strict mode or not.
and console.log(this.lastname); is in global scope so here this refers to window object.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
According to MDN
In most cases, the value of this is determined by how a function is
called. It can't be set by assignment during execution, and it may be
different each time the function is called.
In your case, commented this is called by the JavaScript's execution context, the context that called your program to be executed. Inside that context variable lastname lives and this means that it is a part of this object. You are calling it after your getTest function that changed the value of lastname variable and that is why you see in in console.log() with it's changed value.
If you're in a global context then this refers to the window object.
console.log(this);
this can refer to the window object in a function if the context stays the same
const funcArrow = () => {console.log(this)}
const func = function(){console.log(this)};
//this has no difference
const func2 = function(){console.log(this)}.bind(this);
funcArrow(); func();
The context changes if you create an instance.
var Car = function(){
this.name = "bmw";
console.log(this);
};
class Person {
constructor(){
this.name = "john";
console.log(this);
}
}
new Car(); new Person();
To keep the window context in an instance bind it.
class Person {
constructor(){
this.name = "john";
}
logWindow(){
const someFunc = function(){console.log(this)}.bind(window);
someFunc();
};
}
(new Person()).logWindow();
I am learning javascript and i came across a doubt. Why is the value of "this" undefined in the first example , but prints out correctly in the second.
example 1:
var myNamespace = {
myObject: {
sayHello: function() {
console.log( "name is " + this.myName );
},
myName: "john"
}
};
var hello = myNamespace.myObject.sayHello;
hello(); // "name is undefined"
example 2:
var myNamespace = {
myObject: {
sayHello: function() {
console.log( "Hi! My name is " + this.myName );
},
myName: "Rebecca"
}
};
var obj = myNamespace.myObject;
obj.sayHello();//"Hi! My name is Rebecca"
Why does the value of "this" changes within the function. What concept am i missing?
First case you are just getting the reference of the function to the vairable hello, and invoking it from global context (window in browsers, global in node), So this becomes what invoked the function except for (bound functions). You can always set the context explicitly using function.call or set the context explicitly to the function using Ecma5 function.bind
hello.call(myNamespace.myObject); //now you are setting the context explicitly during the function call.
or just bind it while getting the function reference.
var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject); //Now no matter where you call it from `this` will point to the context of myObject
Second case you are invoking it from the object itself so this points to the object.
In the first case, the implicit this object is the global scope. Because there is no myName in the global scope, you get undefined.
If you want a free function with the proper this, use bind:
var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject);
I found something strange..
function Man(){
this.Man = "Peter";
}
after I call it. (not use it as a constructor)
Man()
I think a result will be
alert(Man.Man)//-->Peter
but.. I'm wrong , actually the result is :
alert(Man.Man)//-->undefined
alert(Man)//-->Peter
That was really confusing ,how it happened??
I'll explain you what is happening there.
1
function Man(){
this.Man = "Peter";
}
The this in Man() function is window.
2
Man();
You are calling the function. Which sets the global variable Man's value to "Peter".
Note that this.Man = "Peter" is equal to window.Man = "Peter" as this is referring to the window.
3
alert(Man.Man)
The function call Man(); in step 2 has made the Man from a function to a string variable. Now Man is a variable whose value is a string and it doesn't contain the property Man, so it is undefined.
4
alert(Man)
Now, you are actually alerting the global variable which was created in Man() call and it was set the value of "Peter"
I used the chrome console and had some other findings
function Man(){
this.Man = "Peter";
console.log("this", this);
}
Above this refers to Window. If you call the function Man() nothing is returned since the function does not return anything but sets the property Man on the window-object to be Peter. Your line Man.Man should return undefined in chrome. If you use Man().Man you will get undefined as well since this refers to the window object and the function Man() has no property Man. You could write
function Man(){
this.Man = "Peter";
return this.Man;
}
This returns the value Peter. If you want to have a property Man you could use a constructor function write
// set this.Man == window.Man to Peter
function Man() { this.Man = "Peter"; }
// create an constructor for each object Man
Man.prototype = { constructor: this.Man }
// create an object
var man = new Man();
// call his property which was set in the constructor of the prototype
man.Man;
Please ask for more help if anything is unclear.
Update as response to the comment
You can use a constructor without using prototype (see examples at mdn or this question if you use this syntax:
function Box(color) // Constructor
{
this.color = color;
}
var redBox = new Box("red");
var blueBox = new Box("blue");
redBox.color; // returns red
blueBox.color; // returns blue
To understand where this refers to you can take a look at understanding javascript this. In the box-example this refers to the new instance (object) of the "underlying class function". In function Man(){this.Man = "Peter"} the this refers to this.window. You can read more about protype in this book.
I get confused on a JavaScript this reference situation.
I am working on a code that I declare function inside an object method. (The reason is to tidy up code inside an object method, while keeping the functions private to the method.)
The following is an experiment to re-produce my problem.
I found that the this inside greeting function refers to the window scope instead of person scope.
var person = {
nickname: "Makzan",
sayHi: function() {
console.log(this);
var greeting = function() {
console.log(this);
return "Aloha " + this.nickname;
}
console.log(greeting());
}
}
person.sayHi();
(same code in jsfiddle: http://jsfiddle.net/makzan/z5Zmm/)
And this is the log result in browser:
> Object
> Window
Aloha undefined
In JS, I know that this reference is tricky. And I can change the scope by using .call method to make this code works.
var greeting = (function() {
console.log(this);
return "Aloha " + this.nickname;
}).call(this);
However, I am curious to know why by default the this refer to window scope inside the greeting method?
Thanks in advance for all your help.
this has nothing to do with scope. It is determined by context.
greeting() calls the function with no context, so this is the default object (window in a browser).
The this, references is not related to scope, it depends on the calling context.
As per the MDN doc,
In general, the object bound to this in the current scope is
determined by how the current function was called
Try person.nickname, this refers to the var greeting in your case
If we modify your code a little, we can see that this works:
var person = {
nickname: "Makzan",
greeting: function () {return "Aloha " + this.nickname;},
sayHi: function () {return console.log(this.greeting());}
}
person.sayHi();
So we may conclude the reason that this doesn't:
var person = {
nickname: "Makzan",
sayHi: function () {var greeting = function () {return "Aloha " + this.nickname}; console.log(greeting()); }
};
person.sayHi();
is because for greeting() to have the this context of the person object, it must be explicitly declared as a direct property of the person object.
What is the difference between declaring a variable with this or var ?
var foo = 'bar'
or
this.foo = 'bar'
When do you use this and when var?
edit: is there a simple question i can ask my self when deciding if i want to use var or this
If it is global code (the code is not part of any function), then you are creating a property on the global object with the two snippets, since this in global code points to the global object.
The difference in this case is that when the var statement is used, that property cannot be deleted, for example:
var foo = 'bar';
delete foo; // false
typeof foo; // "string"
this.bar = 'baz';
delete bar; // true
typeof bar; "undefined"
(Note: The above snippet will behave differently in the Firebug console, since it runs code with eval, and the code executed in the Eval Code execution context permits the deletion of identifiers created with var, try it here)
If the code is part of a function you should know that the this keyword has nothing to do with the function scope, is a reserved word that is set implicitly, depending how a function is called, for example:
1 - When a function is called as a method (the function is invoked as member of an object):
obj.method(); // 'this' inside method will refer to obj
2 - A normal function call:
myFunction(); // 'this' inside the function will refer to the Global object
// or
(function () {})();
3 - When the new operator is used:
var obj = new Constructor(); // 'this' will refer to a newly created object.
And you can even set the this value explicitly, using the call and apply methods, for example:
function test () {
alert(this);
}
test.call("hello!"); //alerts hello!
You should know also that JavaScript has function scope only, and variables declared with the var statement will be reachable only within the same function or any inner functions defined below.
Edit: Looking the code you posted to the #David's answer, let me comment:
var test1 = 'test'; // two globals, with the difference I talk
this.test2 = 'test'; // about in the beginning of this answer
//...
function test4(){
var test5 = 'test in function with var'; // <-- test5 is locally scoped!!!
this.test6 = 'test in function with this'; // global property, see below
}
test4(); // <--- test4 will be called with `this` pointing to the global object
// see #2 above, a call to an identifier that is not an property of an
// object causes it
alert(typeof test5); // "undefined" since it's a local variable of `test4`
alert(test6); // "test in function with this"
You can't access the test5 variable outside the function because is locally scoped, and it exists only withing the scope of that function.
Edit: In response to your comment
For declaring variables I encourage you to always use var, it's what is made for.
The concept of the this value, will get useful when you start working with constructor functions, objects and methods.
If you use var, the variable is scoped to the current function.
If you use this, then you are assigning a value to a property on whatever this is (which is either the object the method is being called on or (if the new keyword has been used) the object being created.
You use var when you want to define a simple local variable as you would in a typical function:-
function doAdd(a, b)
{
var c = a + b;
return c;
}
var result = doAdd(a, b);
alert(result);
However this has special meaning when call is used on a function.
function doAdd(a, b)
{
this.c = a + b;
}
var o = new Object();
doAdd.call(o, a, b);
alert(o.c);
You note the first parameter when using call on doAdd is the object created before. Inside that execution of doAdd this will refer to that object. Hence it creates a c property on the object.
Typically though a function is assigned to a property of an object like this:-
function doAdd(a, b)
{
this.c = a + b;
}
var o = new Object();
o.doAdd = doAdd;
Now the function can be execute using the . notation:-
o.doAdd(a, b);
alert(o.c);
Effectively o.doAdd(a, b) is o.doAdd.call(o, a, b)
var foo = 'bar'
This will scope the foo variable to the function wrapping it, or the global scope.
this.foo = 'bar'
This will scope the foo variable to the this object, it exactly like doing this:
window.foo = 'bar';
or
someObj.foo = 'bar';
The second part of your question seems to be what is the this object, and that is something that is determined by what context the function is running in. You can change what this is by using the apply method that all functions have. You can also make the default of the this variable an object other than the global object, by:
someObj.foo = function(){
// 'this' is 'someObj'
};
or
function someObj(x){
this.x=x;
}
someObj.prototype.getX = function(){
return this.x;
}
var myX = (new someObj(1)).getX(); // myX == 1
In a constructor, you can use var to simulate private members and this to simulate public members:
function Obj() {
this.pub = 'public';
var priv = 'private';
}
var o = new Obj();
o.pub; // 'public'
o.priv; // error
Example for this and var explained below:
function Car() {
this.speed = 0;
var speedUp = function() {
var speed = 10; // default
this.speed = this.speed + speed; // see how this and var are used
};
speedUp();
}
var foo = 'bar'; // 'var can be only used inside a function
and
this.foo = 'bar' // 'this' can be used globally inside an object