What does 'this' represent in the javascript below? - javascript

(Sorry, another this question in javascript.)
I have the code below, and I'm wondering what 'this' represents in the call at the end-- the Window or the Bird?
var Bird = (function () {
Bird.name = 'Bird';
function Bird(name) {
this.name = name;
}
Bird.prototype.move = function (feet) {
return alert(this.name + (" flew" + feet + "ft."));
};
return Bird;
}).call(this);

Well, assuming there is no parent scope, it is window
EDIT: See example: http://jsfiddle.net/Umseu/1

Probably window, because it's not in any particular context that would give this any special meaning.

The window. .call(this) is not written inside the bird. It simply calls an anonymous function that happen to return "Bird" "constructor".

Call console.log(this) at first line in the anonymous function. That return the scope, window.

Related

What is this code's constructor doing?

I'm not getting what's happening in the below code. Why constructor function is enclosed inside another function and why both constructor and the function in which it is enclosed have given the same name? Also why enclosing function has made to be self invoked?
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
}());
var greeter;
greeter = new Greeter("world");
console.log(greeter.greet());
In this particular case there's no point in wrapping Greeter in an immediately invoked function (IIFE); Ravindra Thorat is right that rewriting results in (mostly) equivalent behavior.
This construct starts to make sense when you put more stuff inside the anonymous-immediately-executed-function, like the strict mode marker or a private variable (GREETING in example below):
var Greeter = (function () {
"use strict";
const GREETING = "Hello, ";
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return GREETING + this.greeting;
};
return Greeter;
}());
var greeter;
greeter = new Greeter("world");
console.log(greeter.greet());
// console.log(GREETING) // not defined here -- only available inside the anonymous function
Updated to answer a comment:
Note that the value of the outermost variable Greeter is not the outer anonymous (nameless) function itself, but the result of its invocation. Compare:
var Greeter = (function() {...})() // the returned value is assigned to Greeter
var Greeter = (function() {...}) // the anonymous function without parameters is assigned to Greeter
Since the outer anonymous function ends with return Greeter, the value of the outermost Greeter variable is the function Greeter(message) declared inside the IIFE.
Basically everything inside the IIFE is unavailable outside it, except the explicitly returned object (the Greeter(message) constructor in this example).
You can consider the self-invocation function as kind of higher order function, that returns some another function with some configuration.
Okay, what that self-invocation function is doing? It does contain one constructor functions which hold one public property with name "greeting". Input parameter received from constructor function, get assigned to the greeting. After this signature, it's adding some helper function to this constructor function, with the help of prototype, which prints greeting message.
what does it mean by prototype? it's the one of the major pillar of javascript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
Well! do we really need a self-invocation function for this? the answer is, nope! we can have this written in a simple way too, just like below,
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
var greeter;
greeter = new Greeter("world");
console.log(greeter.greet());
That's it! And it will give the exact result as above.
Then why that guy used the self-invocation function for it? I believe, cool design pattern always shines. That guy has a plan to write some factory function kind of thing which would give me a fully configured constructor function. In this case, the self-invocation expression is nothing but the so called factory.
Note: in the original post by you, the outer most Greeter is not a real function, that is a simple variable which holds some function, returned by that self invocation block. You can use any name for that variable.

Javascript anonymous closure - return vs window

I'm learning about anonymous closures and the module pattern. I understand that using a return object will expose some functionality of the module. However there have been some mentions of attaching some functionality to the window/global object.
I was wondering if attaching to the window was a more hacky way of doing a proper return, or had a legitimate use?
var speakingDog = (function() {
var dog = 'spot';
var says = 'woof';
function speak() {
return (dog + ' goes ' + says);
}
return {
speak: speak
}
})();
vs
(function() {
var dog = 'spot';
var says = 'woof';
function speak() {
return (dog + ' goes ' + says);
}
window.speak = speak;
})();
Adding attributes to window is equivalent to creating global variables (since that's actually what it does).
Your first example where you return the object on the other hand encapsulates everything and exposes it via speakingDog in the scope where the code runs. That's much cleaner of course, since you don't create rather meaningless (speak()) globals.

JavaScript - What's the difference between an anonymous function and just regular code?

I am wondering what the difference is between this:
(function(msg) {
alert(msg);
}('Hi'));
and this:
alert('Hi');
Because when you use an anonymous function, you can't run it twice, right? You can't do this:
(function(msg) {
alert(msg);
}('Hi')('Goodbye'));
So what's the point of an anonymous function?
This:
(function(msg) {
alert(msg);
}('Hi'));
gets the same output as this:
alert('Hi');
Could someone tell me what the difference is?
The main difference is that it has its own scope. Example:
(function(msg) {
var x = msg; // local variable in the scope
alert(x);
}('Hi'));
// the variable x doesn't exist out here
That is useful when you for example create a function in the scope, and expose it outside. The function still has access to the scope even when executed outside it. That way the function can keep a state, without exposing the state globally:
var f = (function(msg) {
var cnt = 1;
return function(){
alert(msg + ' ' + cnt);
cnt++;
};
}('Hi'));
f(); // shows "Hi 1"
f(); // shows "Hi 2"
Your example shows an Anonymous Function that is self-executing. The self-executing Function closes off scope, so you can do things like this:
var count = (function(){
var c = 0;
return function(){
return c++;
}
})();
console.log(count()); console.log(count());
In your first example nothing different will occur. An Anonymous function, just has no name, so this:
document.getElementById('whatever').addEventListener('click', function(){alert('wow')});
and
function wow(){
alert('wow');
}
document.getElementById('whatever').addEventListener('click', wow);
do the same thing.
the anonymous function is when you declare a function without name i.e
function(){
...
}
Your example is an inmediate function, here you can hide properties and functionality (using closures, this is complex I recommend you The secrets of JS Ninja, but is a intermediate lvl book.), so you can use this when use the module pattern:
(function(msg) {
alert(msg);
}('Hi'));
BTW this is a good resource about patterns in JS: http://addyosmani.com/resources/essentialjsdesignpatterns/book/

JavaScript this refers to window instead of object inside function

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.

"this" keyword in Object method points to Window

var name = 'The Window';
var object = {  
name: 'My Object',
getNameFunc: function(){    
return function() {     
return this.name;   
}; 
}
};
console.log( object.getNameFunc()() );
when i tested the code. the result is The Window. but i think this.name; should be My Object. what's wrong with my thinking.
when i add var before the name : "My Object", it show's an error.? why?
this inside a function is the "receiver" it was invoked upon.
That is,
for the construct x.f(), this inside the function (f) will evaluate to the value of x.
for all other cases, this will evaluate to window inside the invoked function. (The functions call, apply, and bind can also alter this... but that's another story.)
In the posted example the second function (the one with this.name) is not invoked using the x.f() form and so this is the window object.
The "simple fix" is to use a closure: (The first function is invoked in the x.f() form and thus this is the same as object, which is as expected. We capture the value of this in the current scope via a closure created with self and the returned function.)
getNameFunc : function () {
var self = this
return function () {
return self.name
}
}
However, I may consider another design, depending :)
Happy coding.
Additional clarification, for comment:
...that is because you are using circle.getArea() which is of the form x.f(). Thus this inside the getArea function evaluates to circle.
In the code posted you are invoking two different functions in a row. Imagine writing the code like this:
var nameFunc = object.getNameFunc()
nameFunc()
The first function call is in the form of x.f() and thus this inside getNameFunc is the evaluation of object. However, in the second line, the function (nameFunc) is not invoked in the form x.f(). Therefore, the this inside nameFunc (the function returned from getNameFunc) will evaluate to window, as discussed above.
var myObject = {
name:'My Object'
};
console.log(myObject.name);
console.log(myObject['name']);
There are various other ways to make objects in javascript.
this is a hidden argument that is automatically passed from the calling function to the callee. The traditional way is to do:
function MyObject() {
this.name = 'My Object';
}
myObject = new MyObject();
console.log(myObject.name);
Nowadays you might just use closures:
[**edit**: redacted because not a good method]
Nowadays you might just use closures, correctly:
function makeObject() {
var THIS = {};
THIS.name = 'My Object';
THIS.sayMyName = function () {
return THIS.name+" is my name";
}
return THIS;
}
There are many libraries that support "smarter" ways to make objects as well.
You need to use .bind() to set the right context for the method, so the this keyword will be what you want it to actually be.
The default is in such a scenario for the this keyword is to point to the window object, because...this is how the JS engine works.
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
}.bind(this); // <-- sets the context of "this" to "object"
}
};
console.log( object.getNameFunc()() );
As the others have written, you need to target this. I believe this piece of code will help you to understand how this in javascript works
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
that = this; // targeting this
return function() {
return that.name;
};
}
};
alert(object.getNameFunc()()); // it is My Object now
var object = {
  name : "My Object",
  getNameFunc : function(){
    return (function(){
      return this.name;
    }).bind(this);
 }
};
.bind, use the ES5-shim for browser support
The problem lies in the way you have declared your function.
The important point we need to remember while placing function inside a method is to use arrow function (if our function block is going to have a this keyword).
Instead of declaring a new variable and assigning this keyword to the variable, we can easily solve this problem using Arrow Functions.
Just convert the normal function into arrow function and boom it will work.
var name = 'The Window';
var object = {  
name: 'My Object',
getNameFunc: function(){    
return () => {     
return this.name;   
}; 
}
};
console.log( object.getNameFunc()() );
This works because arrow functions are always lexically binded and not dynamically binded like any other functions.

Categories

Resources