Function()() mutiple calling to access child functions in javascript - javascript

var obj = {
bar: function() {
var x = (() => this);
return x;
}
};
// Call bar as a method of obj, setting its this to obj
// Assign a reference to the returned function to fn
var fn = obj.bar();
// Call fn without setting this, would normally default
// to the global object or undefined in strict mode
console.log(fn() === obj); // true
// But caution if you reference the method of obj without calling it
var fn2 = obj.bar;
// Calling the arrow function's this from inside the bar method()
// will now return window, because it follows the this from fn2.
console.log(fn2()() == window); // true
My question is that at last line fn2()() is called but with two sets of closing bracket` which executes the child function. But I searched along web and did not got this double or triple, etc. type of function call anywhere.
So I want ask which part of JavaScript have this topic and how actually it works behind the scene?

Related

Javascript Closure is Preserving Value of This Keyword Even Though Call Site is Different

While I was creating a module I came up with a small technique to remove event listeners and the way I coded it, I actually thought it might not work and it did. Now, I am not clueless with what the this keyword is and how it works, I know what execution context is, and I understand that this is determined at invocation time.
With that out of the way I have a simplified piece of code that illustrates the point I am confused about. The reason I am confused is that the closure seems to be binding the value of this
const obj = {
foo() {
console.log(this)
},
bar() {
const context = { ctx: this, baz: this.foo }
const modal = Modal(context)
modal.open()
}
}
function Modal(ctx) {
// this closes over ctx
function open() {
// here is where I am a bit confused, the call site is function open()
// yet `this` is preserved as the above owner object
ctx.baz() // logs the above owner object
// but why is this not lost like the second example below.
}
return { open }
}
obj.bar()
Essentially I am passing this for the object into the Modal() function. In the above example it is possible to do a little bit more but here is a simplified example for what is going on above
const obj = {
foo() {
console.log(this)
},
bar() {
const modal = Modal(this)
modal.open()
}
}
function Modal(ctx) {
function open() {
ctx.foo()
}
return { open }
}
obj.bar()
To make this even more confusing lets modify the above example slightly with destructuring.
const obj = {
foo() {
console.log(this)
},
bar() {
const context = { ctx: this, baz: this.foo }
const modal = module(context)
modal.open()
}
}
function module({ ctx, baz }) {
function open() {
baz() // now the binding is gone and logs window
}
return { open }
}
obj.bar() // logs window
If we did this the context would be lost since obj.foo is a reference to a function being called from the window
const obj = {
foo() {
console.log(this)
}
}
const bar = obj.foo // bind would need to be used
bar() // window
I did my best to try to explain this as clear as possible. Although the code works how I want, I was expecting the context to be lost in function open() in the first example as it is lost in the second example. Would this example I came up with above be more bulletproof using call, or bind?
What determines the value of this is not who the caller is, but how the call looks at the call site.
'use strict'
const obj = {
hello: 'I am obj',
printThis () {
console.log(this)
}
}
// logs obj
obj.printThis()
// logs undefined (window in non-strict mode)
const fn = obj.printThis
fn()
// logs obj
const fn2 = obj.printThis.bind(obj)
fn2()
// logs obj2
const obj2 = {
hello: 'I am obj2',
printThis: obj.printThis
}
obj2.printThis()
// logs obj3
const obj3 = {
hello: 'I am obj3'
}
obj.printThis.call(obj3)
This is because unless you use .call/.apply/.bind to manually set what this should be, it is determined by looking at whether the call itself looks like x.y().
If it does, then y is called with x as its this. Otherwise, it is called with undefined (or window in non-strict mode) as this.
obj.printThis()
// ^^^-------------- this is obj
fn()
// ^----------------- no this given
fn2()
// ^----------------- no this given, but fn2 was already bound to obj
obj2.printThis()
// ^^^^------------- this is obj2
obj.printThis.call(obj3)
// ^^^^-- this is obj3 (explicitly)
// ^^^^^^^^^^^^^-- well, in fact this is a call to the function
// Function.prototype.call, with obj.printThis as
// this and obj3 as argument ;-)
This is different with arrow functions, though. They don't have their own this at all, instead this behaves like any other variable closed over from the surrounding scope of their definition (also not call site).
Let's go over your example again then:
You call obj.bar() (resulting in its this being obj).
bar creates an object context as follows:
context = {
ctx: obj // because this === obj
baz: function () { console.log(this) } // the same as obj.foo
}
You call Modal(context). This returns an object with an open function in it. You store it in modal.
You call modal.open() (resulting in its this being modal).
open calls ctx.baz(). open's this being modal has no relevance here, you are not referencing the keyword this, instead you have a call ctx.baz() which means calling the function function () { console.log(this) } with a this of ctx (which is the same as the context previously created in bar).
So, to recap: At point 5 we have ctx.baz === obj.foo, but if you write obj.foo() then you call the function with obj as this (because you wrote obj. in front), but if you write ctx.baz() then you call the same function with ctx as this (because you wrote ctx. in front).

Why in JSX sometimes we use brackets and sometimes not? [duplicate]

I was handling a JavaScript file upload event. And I have the following initializer and the following function:
Initializer
$('#s3-uploader').S3Uploader({
allow_multiple_files: false,
before_add: progressBar.show,
progress_bar_target: $('.upload-progress-bar'),
remove_completed_progress_bar: false
}).bind("s3_upload_complete", function(e, content) {
console.log(content);
});
Function
var progressBar = {
show: function() {
$('.upload-progress-bar').show();
return true;
}
}
In the initializer, I noticed there is a difference if I do
before_add: progressBar.show v.s. before_add: progressBar.show(). With the parentheses, it will be called once even if it is bound to the before_add option, and without the parentheses it will not.
Is there an explanation for the behaviour I observed?
With parentheses the method is invoked because of the parentheses, and the result of that invocation will be stored in before_add.
Without the parentheses you store a reference (or "pointer" if you will) to the function in the variable. That way it will be invoked whenever someone invokes before_add().
If that didn't clear things up, maybe this will help:
function Foo() {
return 'Cool!';
}
function Bar(arg) {
console.log(arg);
}
// Store the >>result of the invocation of the Foo function<< into X
var x = Foo();
console.log(x);
// Store >>a reference to the Bar function<< in y
var y = Bar;
// Invoke the referenced method
y('Woah!');
// Also, show what y is:
console.log(y);
// Now, try Bar **with** parentheses:
var z = Bar('Whut?');
// By now, 'Whut?' as already been output to the console; the below line will
// return undefined because the invocation of Bar() didn't return anything.
console.log(z);
If you then take a look at your browsers' console window you should see:
Cool!
Woah!
function Bar(arg)
Whut?
undefined
Line 1 is the result of invoking Foo(),
Line 2 is the result of invoking Bar() "via" y,
Line 3 is the "contents" of y,
Line 4 is the result of the var z = Bar('Whut?'); line; the Bar function is invoked,
Line 5 shows that invoking Bar() and assigning the result to z didn't return anything (thus: undefined).
Functions are first-class in JavaScript. This means they can be passed around, just like any other parameter or value. What you're seeing is the difference between passing a function and passing the value said function returns.
In your example:
before_add: progressBar.show
You want to pass progressBar.show instead of progressBar.show() because the former represents a function (function () {$('.upload-progress-bar').show(); return true;}) whereas the latter represents a returned result (true).
Here's another example:
// All this function does is call whatever function is passed to it
var callAnotherFunction = function (func) {
return func()
}
// Returns 3 — that's all
var return3 = function () { return 3 }
// `callAnotherFunction` is passed `return3`
// so `callAnotherFunction` will `return return3()` === `return 3`
// so `3` is printed
document.write(callAnotherFunction(return3))
// `callAnotherFunction(return3())` is the same as `callAnotherFunction(3)`.
// This will print nothing because, in `callAnotherFunction`
// `func` is 3, not a function
// so it cannot be invoked, so nothing is returned
// and `document.write` doesn't print anything.
document.write(callAnotherFunction(return3()))

Difference of calling a function with and without parentheses in JavaScript

I was handling a JavaScript file upload event. And I have the following initializer and the following function:
Initializer
$('#s3-uploader').S3Uploader({
allow_multiple_files: false,
before_add: progressBar.show,
progress_bar_target: $('.upload-progress-bar'),
remove_completed_progress_bar: false
}).bind("s3_upload_complete", function(e, content) {
console.log(content);
});
Function
var progressBar = {
show: function() {
$('.upload-progress-bar').show();
return true;
}
}
In the initializer, I noticed there is a difference if I do
before_add: progressBar.show v.s. before_add: progressBar.show(). With the parentheses, it will be called once even if it is bound to the before_add option, and without the parentheses it will not.
Is there an explanation for the behaviour I observed?
With parentheses the method is invoked because of the parentheses, and the result of that invocation will be stored in before_add.
Without the parentheses you store a reference (or "pointer" if you will) to the function in the variable. That way it will be invoked whenever someone invokes before_add().
If that didn't clear things up, maybe this will help:
function Foo() {
return 'Cool!';
}
function Bar(arg) {
console.log(arg);
}
// Store the >>result of the invocation of the Foo function<< into X
var x = Foo();
console.log(x);
// Store >>a reference to the Bar function<< in y
var y = Bar;
// Invoke the referenced method
y('Woah!');
// Also, show what y is:
console.log(y);
// Now, try Bar **with** parentheses:
var z = Bar('Whut?');
// By now, 'Whut?' as already been output to the console; the below line will
// return undefined because the invocation of Bar() didn't return anything.
console.log(z);
If you then take a look at your browsers' console window you should see:
Cool!
Woah!
function Bar(arg)
Whut?
undefined
Line 1 is the result of invoking Foo(),
Line 2 is the result of invoking Bar() "via" y,
Line 3 is the "contents" of y,
Line 4 is the result of the var z = Bar('Whut?'); line; the Bar function is invoked,
Line 5 shows that invoking Bar() and assigning the result to z didn't return anything (thus: undefined).
Functions are first-class in JavaScript. This means they can be passed around, just like any other parameter or value. What you're seeing is the difference between passing a function and passing the value said function returns.
In your example:
before_add: progressBar.show
You want to pass progressBar.show instead of progressBar.show() because the former represents a function (function () {$('.upload-progress-bar').show(); return true;}) whereas the latter represents a returned result (true).
Here's another example:
// All this function does is call whatever function is passed to it
var callAnotherFunction = function (func) {
return func()
}
// Returns 3 — that's all
var return3 = function () { return 3 }
// `callAnotherFunction` is passed `return3`
// so `callAnotherFunction` will `return return3()` === `return 3`
// so `3` is printed
document.write(callAnotherFunction(return3))
// `callAnotherFunction(return3())` is the same as `callAnotherFunction(3)`.
// This will print nothing because, in `callAnotherFunction`
// `func` is 3, not a function
// so it cannot be invoked, so nothing is returned
// and `document.write` doesn't print anything.
document.write(callAnotherFunction(return3()))

What does 'this' in javascript reference to?

I'm not sure where this points in JavaScript. And I give 2 examples.
Can you help me analyze them? Thank you very much.
//exmp1
function f1()
{
alert(this);
function f2()
{
alert(this);
}
f2();
}
f1();
//exmp2
var jsn =
{
name : "b",
func : function() // closure
{
alert(this);
return function()
{
return this;
}
}
}
alert(jsn.func()());
this is different in JavaScript than it is in some other languages like C++ or Java. The value of this in your first example will always be the global object (window, on browsers). this in your second example is the jsn object for the first alert, and window for the second. This is because this is determined entirely by how a function is called, not where it's defined.
If you don't do anything special when calling the function, this is the global object. When you call a function via an object property (jsn.func()), this is set to the object the property came from. (But don't get the wrong impression, func is in no way specially tied to jsn; JavaScript doesn't have methods, just functions; details.) f1 then returns a function, which is called within the final alert; since that call is not via an object property, this is set to the global object.
Some examples:
// Simple function
function foo() {
alert(this === window);
}
foo(); // true, within the call, `this` === `window`
// Object example, and twist at the end
var obj = {
func: function() {
alert(this === obj);
},
};
obj.func(); // true, within the call, `this` === `obj`
obj["func"](); // true, within the call, `this` === `obj`
var f = obj.func; // Not calling it, just getting a reference to the function
f(); // false, within the call `this` !== `obj` (`this` === `window`)
// Creating functions on the fly, returning them, and how that has
// nothing whatsoever to do with how `this` gets set:
var obj = {
func: function() {
return function() {
alert("I'm a generated function");
alert(this === obj);
};
}
};
obj.func()(); // alerts the "I'm a generated function", then false; `this` !== `obj`
obj.bar = obj.func();
obj.bar(); // alerts the "I'm a generated function", then true; `this` === `obj`
There's a second way to control what this is within a function: Use the .call or .apply features of JavaScript functions:
var obj = {
func: function() {
alert(this === obj);
}
};
function foo(a, b) {
alert(this === obj); // Yes, really obj; see below
alert(a);
alert(b);
}
foo(1, 2); // alerts false (`this` !== `obj`), then 1, then 2
obj.func(); // alerts true, `this` === `obj`
foo.call(obj, 3, 4); // alerts true (`this` === `obj`), then 3, then 4
foo.apply(obj, [5, 6]); // alerts true (`this` === `obj`), then 5, then 6
As you can see, the first argument to call or apply is the object to make this within the function call. The only difference between call and apply is how you specify arguments to pass into the target function: With call, you just supply them after the first argument; with apply, you supply them as an array.
And finally, there's a third way: The new keyword. JavaScript has the concept of constructor functions. The purpose of a constructor function is to create instances of objects initialized in a particular way. Here's an example:
function Foo(b) {
this.bar = b;
}
var f = new Foo();
Technically, any function can be used as a constructor function. The convention is to give functions meant to be used with new names starting with a capital letter, just to reinforce that we call them in a special way.
Calling a function via new creates a new object instance and makes that object the this value within the function call. So
function Foo(b) {
alert(this === window);
}
var f = new Foo(); // alerts false, `this` !== `window` (it points to the new object created for the call)
var f = Foo(); // alerts true, `this` === `window` because we didn't use `new`
As you can see, it's important to call a function in the correct way. If it's designed to be used with new, call it via new; if it's not, don't.
(new does more than just create a blank object; the object created has some other aspects set up in a certain way. I won't go into the details here, but I didn't want to leave you with the impression that all it did was create a new object instance.)
In your last example (the function inside json object), this refers to the json object that is holding the function.
In your first example, the first this is referring to the object that is holding f1, it happens to be the global window object. The second this in f2 is also referring to the global object and not to f1, and this is a known bug in javascript, when you have one function defined in another.
A common workaround is this (no pun intended):
function f1() {
alert (this);
var that = this;
function f2() {
alert (that);
}
f2();
}
Notice that if you define a function in a json object, it can still be "moved around" and the context of this will change. For example:
var car1 = {
color: "red",
f: function () { alert (this.color); }
}
car1.f(); // prints "red"
var car2 = {
color: "blue",
}
car2.f = car1.f;
car2.f(); // prints "blue"
In JavaScript "this" always refers to the object which "owns" the function, or rather, the object to which a function was bound via a property at the time it was called. Consider this example:
var f = function() { alert(this); }
f(); // Alerts the "DOM window" (global) object, which
// is implied if there is no explicit owner.
var o = {toString:function(){return "Foo!";}}
o.func = f;
o.func(); // Alerts the "Foo!" object (o) since the
// function then belongs to it as a member.
Now regarding your specific examples, here's what happens:
//exmp1
function f1() {
alert(this);
function f2() {
alert(this);
}
f2(); // Alerts "the global object", since f2
// is not bound to any object's property.
}
f1(); // Alerts "the global object" (probably DOM window)
// for same reason as above.
//exmp2
var jsn = {
name : "b",
func : function() {
alert(this); // Will alert the "jsn" object, since it
// owns the function in its "func" member.
return function() {
return this; // Returns whoever is calling it!
};
}
}
alert(jsn.func()()); // "jsn.func()" returns a function which gets
// called by the global "DOM window" object.
when you use a function as a constructor, this points to the object you are constructing.
function Test() {
this.test = true;
}
t = new Test();
alert(t.test);

Declaring variables with this or var?

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

Categories

Resources