If i need to write a java script function that takes an argument and returns a function that returns that argument, i can think of following two implementations. Are both of these same ? or there is anything different technically ? Both works and returns the same result.
/*Implemenation 1*/
function myWieredFunc(arg){
var retf=function inner(){
return arg;
};
return retf;
}
/* Implemenation 2 */
function myWieredFunc(arg){
return function(){
return arg;
};
}
To use these:
var f = myWieredFunc(84);
alert(f());
This would be the way to write it
function wrap(arg) {
return function() {
return arg;
};
};
If you wanted to make it more flexible you could allow multiple arguments:
function wrap() {
var args = arguments;
return function() {
return args;
};
};
var later = wrap('hello', 'world');
var result = later();
console.log(result); // ["hello", "world"]
There is no reason for the variable in the code shown - functions are objects are values. As you've shown this means that function-objects can be assigned to a variable which is later evaluated and returned, or returned directly from the Function Expression.
As such, both forms are generally held equivalent and the closure over arg is unaffected.
However, in the first form..
Function.toString and stack-traces will normally include the function name, this makes "named functions", as in the first example sometimes more useful in debugging. Additionally, Firefox will expose function names - e.g. "inner" - through the non-standard Function.name property. (The function name can be specified without the use of the retf variable.)
Two additional bindings are introduced - retf in the outer function and inner in the inner function. These variables could be observed in the the applicable scope when stopping via a break-point - but are not otherwise accessible in the code shown.
They are the same thing, the second is using an "Anonymous" function which just means its a function that is not given a name or assigned to a variable.
Related
I'm currently working on a JavaScript exercise in FreeCodeCamp, and one of the test-cases my code should work with is a function call that looks like this:
addTogether(2)(3);
here is the bare-bones function I'm given:
function addTogether() {
return;
}
When I run the code below:
function addTogether() {
return arguments;
}
In the console, that the editor provides, I get:
TypeError: addTogether(...) is not a function
The instructions hint at using the arguments object, and it works well with test-case function calls that only have one argument object (i.e. addTogether(2, 3);), but not with the one I've shown above.
Is there a way to access/utilize the separate argument objects when they're in the format I showed above?
Note: I don't want any sort of answer to solve the problem, just info on any techniques on accessing the arguments of these type of function calls.
Help, is greatly appreciated.
Don't think of it as two separate sets of arguments. Think of it as you're calling another function (which you are). Functions are first-class values in JavaScript so you can use them just like any other value. This includes returning them from functions.
var f = function(y) {
console.log('f:', y);
};
var getF = function(x) {
console.log('getF:', x);
return f;
};
getF(1)(2);
Functions can also use values that exist in any parent scope. Loosely speaking, functions which do this are called closures.
function createGetX(x) {
return function() {
// Since x is in the parent scope, we can use it here
return x;
}
}
var one = createGetX(1);
console.log(one()); // Always
console.log(one()); // returns
console.log(one()); // one
Sometimes it helps me to think in a certain order. You can read the code "addTogether(2)" and stop before reading the "(3)".
From there you can see the exercise wants you to have that first part "addTogether(2)" return a function...since anytime there are "()" that means a function is getting called.
So "addTogether(2)" needs to return a function that takes one argument. Later that 3 will be one example of an input.
I think the name "addTogether" is a bit confusing..since that function's job is to make up and return the actual function that adds.
Sort of hard to explain this one without helping too much, but the bulk of your job here is to return a custom function, which includes the first variable (from it's scope) and expects another variable when it's called.
You could do this with closures.
function addTogether(x) {
return function(y) {
return x+y;
}
}
(Question 1)
In Flanagan's JS Definitive Guide, he defines the Function method bind() in case it's not available (wasn't available n ECMAScript 3).
It looks like this:
function bind(f, o) {
if (f.bind) return f.bind(o); // Use the bind method, if there is one
else return function() { // Otherwise, bind it like this
return f.apply(o, arguments);
};
}
He illustrates the use of it with an example (which I have modified to change the 3rd line from f.bind(o)):
function f(y) { return this.x + y; } // This function needs to be bound
var o = { x : 1 }; // An object we'll bind to
var g = bind(f, o); // Calling g(x) invokes o.f(x)
g(2) // => 3
When I first saw this, I thought "Wouldn't arguments refer to the arguments variable within the bind function we're defining? But we want the arguments property of the function we eventually apply it to, like g in the example above..."
I verified that his example did indeed work and surmised that the line return f.apply(o, arguments) isn't evaluated until var g = bind(f, o) up above. That is, I thought, when you return a function, are you just returning the source code for that function, no? Until its evaluated? So I tested this theory by trying out a slightly different version of bind:
function mybind2(f, o) {
var arguments = 6;
return function() { // Otherwise, bind it like this
return f.apply(o, arguments);
};
}
If it's simply returning tbe unevaluated function source, there's no way that it stores arguments = 6 when later evaluated, right? And after checking, I still got g(2) => 3. But then I realized -- if it's just returning unevaluated code, how is the o in return f.apply(o, arguments) getting passed?
So I decided that what must be happening is this:
The o and the arguments variables (even when arguments equals 6) are getting passed on to the function. It's just that when the function g is eventually called, the arguments variable is redefined by the interpreter to be the arguments of g (in g(2)) and hence the original value of arguments that I tried to pass on was replaced. But this implies that it was sort of storing the function as text up until then, because otherwise o and arguments would have simply been data in the program, rather than variables that could be overwritten. Is this explanation correct?
(Question 2) Earlier on the same page, he defines the following function which makes use the apply method to trace a function for debugging:
function trace(o, m) {
var original = o[m]; // Remember original method in the closure.
o[m] = function() { // Now define the new method.
console.log(new Date(), "Entering:", m); // Log message.
var result = original.apply(this, arguments); // Invoke original.
console.log(new Date(), "Exiting:", m); // Log message.
return result; // Return result.
};
}
Wouldn't the this here refer to the function that we're defining, rather than the object o? Or are those two things one and the same?
Question 1
For your first question, let's simplify the example so it's clear what being done:
function bind(func, thisArg) {
return function () {
return func.apply(thisArg, arguments);
};
}
What happens here is that a closure is created that allows the access of the original function and the value of this that is passed. The anonymous function returned will keep the original function in its scope, which ends up being like the following:
var func = function () {};
var thisArg = {};
func.apply(thisArg, [/*arguments*/]);
About your issue with arguments, that variable is implicitly defined in the scope of all functions created, so therefore the inner arguments will shadow the outer arguments, making it work as expected.
Question 2
Your problem is to your misunderstanding of the late binding of this -- this is one of the more confusing things about JavaScript to people used to more object-oriented languages that also have their own this keyword. The value of this is only set when it is called, and where it is called defines the value of this when it is called. It is simply the value of the parent object from where it is at the time the function is called, with the exception of cases where the this value is overridden.
For example, see this:
function a() {return this;};
a(); // global object;
var b = {};
b.a = a;
b.a(); // object b
If this was set when the function was defined, calling b.a would result in the global object, not the b object. Let's also simplify what happens with the second function given:
function trace(obj, property) {
var method = obj[property]; // Remember original method in the closure.
obj[property] = function () { // Now define the new method.
console.log(1); // Log message.
// Invoke original method and return its result
return original.apply(this, arguments);
};
}
What happens in this case is that the original method is stored in a closure. Assigning to the object that the method was originally in does not overwrite the method object. Just like a normal method assignment, the principles of the this value still work the same -- it will return the parent object, not the function that you've defined. If you do a simple assignment:
var obj = {};
obj.foo = function () { return this; };
obj.foo(); // obj
It does what was expected, returns the parent object at the time of calling. Placing your code in a nested function makes no difference in this regard.
Some good resources
If you'd like to learn more about writing code in JavaScript, I'd highly recommend taking a look at Fully Understanding the this Keyword by Cody Lindley -- it goes into much more detail about how the this keyword behaves in different contexts and the things you can do with it.
But this implies that it was sort of storing the function as text up until then, because otherwise o and arguments would have simply been data in the program, rather than variables that could be overwritten. Is this explanation correct?
No. this and arguments are just special variables which are implicitly set when a function is executed. They don't adhere to normal "closure rules". The function definition itself is still evaluated immediately and bind returns a function object.
You can easily verify this with:
var g = bind(f, o);
console.log(typeof g);
Here is a simpler example which doesn't involve higher order functions:
var arguments = 42;
function foo() {
console.log(arguments);
}
foo(1, 2);
I think you see that the definition of foo is evaluated like you'd expect. Yet, console.log(arguments) logs [1, 2] and not 42.
Wouldn't the this here refer to the function that we're defining, rather than the object o? Or are those two things one and the same?
this never refers to the function itself (unless you explicitly set it so). The value of this is completely determined by how the function is called. That's why this is often called "the context". The MDN documentation provides extensive information about this.
Reading material:
MDN - this
MDN - arguments
In the following example, why does the declaration of 'z' cause a syntax error?
(function(){
function x(){return 'this is x'};
y = function(){return 'this is y'};
//z : function(){return 'this is z'};
alert(x());
alert(y());
//alert(z());
})();
http://jsfiddle.net/VXPsd/2/
...why does the declaration of 'z' cause a syntax error?
Because you're using property initializer syntax outside of an object initializer.
This is an object initializer (the bit starting with { and ending with }) containing property initializer (the middle line):
var obj = {
propertyName: "property value"
};
So if you were declaring an object, you could use your z line (without the ;):
var obj = {
z: function() { return 'this is z'}
};
But where you have that in your code, you're not in an object initializer, you're in the body of a function. So you can't use that syntax.
It's worth noting that your x and y are quite different constructs from each other.
This:
function x(){return 'this is x'};
is a function declaration. Function declarations are processed before any step-by-step code in the containing function is run, and the function name is in scope from the top of the containing function. (Sometimes people call this "hoisting".)
This:
y = function(){return 'this is y'};
is a function expression. It's processed, like all expressions, where it's encountered in the step-by-step execution of the code in the containing function.
(The code as quoted falls prey to The Horror of Implicit Globals, btw: Since there's no var on y, and since you're not using strict mode, that line creates a global variable called y.)
What's the correct way to declare functions in a self executing function?
Neither form (the x or y form) is more correct than the other (leaving aside the implicit global thing). They each have uses, it depends on what you're doing. The y form has the issue that the function y refers to has no name (it's an anonymous function — the variable it's assigned to has a name, but the function doesn't). That can make debugging more difficult (looking at lists of breakpoints or the call stack), although modern debuggers are pretty good at showing you the variable name if the function doesn't have one, when they can.
Note that because they're not part of the step-by-step code, you cannot use a function declaration within a control structure:
function foo() {
if (condition) {
function bar() { /* ...do something... */ } // <==== WRONG
}
else {
function bar() { /* ...do something else... */ } // <==== WRONG
}
}
That's one of the reasons we have function expressions:
function foo() {
var bar;
if (condition) {
bar = function() { /* ...do something... */ }; // <==== Right
}
else {
bar = function() { /* ...do something else... */ }; // <==== Right
}
}
Note that some JavaScript engines tolerate the wrong syntax above, but the way that they tolerate it varies from engine to engine. Some engines convert the declarations into expressions for you. Others just always use the second declaration. Just don't do it. :-)
And finally: There's also something called a named function expression:
var x = function foo() { /* ... */ };
The function has a name (foo), and the variable referring to it has a name (x). It's an expression because it's used as a right-hand value (the right-hand side of an =, the : in an initializer, if you were passing it into a function as an argument, etc.) Sadly, various JavaScript engines have been known to get NFEs (as they're called) wrong in various different ways, although I think in today's world, it's really just IE8 and earlier, which create two different functions at different times.
The variableName : value syntax can only be used in the context of an object. For example:
var obj = {
z: function(){return 'this is z'};
};
In which case running obj.z() will return This is an object.
In your case you are just in the context of a function, not declaring an object. Which means you have to use the syntax you used with x or y.
The colon notation only works inside of object syntax.
For example
var theObj = {one : 'one', two : 'two'};
In order to add to the object you should use dot notation:
theObj.three = 'three';
As an executed Anonymous Function (with hiding);
var objOuter = (function(){ // Anonymous Function
var funcPrivate = function() {
// private function contents
};
var funcPublic = function() {
// private function contents
};
return { // JavaScript Object
funcName : funcPublic // provides public access to funcPublic
};
})();
//objOuter.funcPrivate(); // Failure, private.
//objOuter.funcPublic(); // Failure, internal name for public function.
objOuter.funcName(); // Executes funcPublic in objOuter's scope.
As part of a JavaScript object definition (everything is public):
var objOuter = { // JavaScript Object
funcName : function() {
// function contents
}
};
objOuter.funcName(); // Executes funcName
The Anonymous Function is executed JavaScript code, but the inside of the {} for the JavaScript object definition is a different kind of syntax that pairs keys and values.
Inside the JavaScript object you assign the value function() to key funcName. When you reference that key and execute it by passing it an argument list (), the function executes.
In the Anonymous Function (also called the Revealing Module Pattern), you are defining private functions inside the scope of the module and then passing references to those functions to the calling code as part of the returned JavaScript object.
What is the difference, pros/cons (if any) between these constructs?
new function(obj) {
console.log(obj);
}(extObj);
vs
(function(obj) {
console.log(obj);
})(extObj);
The first one returns a reference to the newly constructed instance of your anonymous constructor function (= this).
The second one returns the return value of the anonymous function. Since your function does not have a return statement, it will implicitly return undefined.
Try the following:
var t1 = new function(obj) { console.log(obj); }(extObj);
var t2 = (function(obj) { console.log(obj); })(extObj);
typeof t1 => "object"
typeof t2 => "undefined"
(Btw, t1.constructor will return the original function you created t1 with.)
The difference becomes much clearer, if you add a return statement:
var t1 = new function(obj){ return(obj); }("foo");
var t2 = (function(obj){ return(obj); })("bar");
console.log(t1) => "object"
console.log(t2) => "bar"
IMO, this makes the (function)() much more useful for the everyday usecase - you assign the returnvalue of the execution of this function to the variable which normally would be what you want if you are working with immediately invoked functions. Especially when having more complex things like (pseudocode):
var myNameSpace = (function(){
/* do some private stuff here*/
...
/* expose parts of your anonymous function by returning them */
return{
functionX,
variable1,
variable2
}
}();
Basically you can use an arbitrary unary operator to turn the function declaration into an expression, that is immediately invoked. So you could also write:
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
depending on the return statement of your function, these will give different return results. ! - negate the returnvalue +|- evaluate as Number (apply negative sign) ~ apply bitwise not to the return value.
If you're looking at dealing expressly with an immediately-invoked function, then there isn't any real difference between the two, except that the first one will return this inside the function, to the outside world, automatically (that is what new does), and by default if a different return value is not specified (regular functions return undefined).
The rest of the major differences are not really going to matter -- access to the prototype chain is going to be pointless, having the returned this.constructor point to the anonymous function would give you access to caching the anonymous function for use at a later time (like removing it from an event listener, if you somehow managed to stick the enclosed function in... ...that would be a trick in and of itself).
Allowing people to cache your immediately-invoked function as a constructor property of the returned this object might be a security-risk... ...or it might be really useful... ...in very specific scenarios.
Every-day purposes of firing code in-line -- no real difference.
Another difference is that the first invocation creates an extra object. Here I've put the names f and o to denote an objects:
var o = new function f(obj) {
console.log(obj);
}(extObj);
In second case we still create a function object f but we don't create an o:
(function f(obj) {
console.log(obj);
})(extObj);
A closure is still created but that's cheaper than the actual JavaScript object since it doesn't carry the whole prototype chain or other attributes (like hidden class reference) with it,
As far as I know, function foo() { aaa(); } is just var foo = function(){ aaa() } in JavaScript. So adding function foo() { bbb(); } should either overwrite the foo variable, or ignore the second definition - that's not the point. The point is that there should be one variable foo.
So, in this example the me variable should not be correctly resolved from inside the methods and it is not in Explorer 8 :-). I came to this example by trying to wrap them into another closure where (var) me would be, but I was surprised that it's not necessary:
var foo = {
bar1 : function me() {
var index = 1;
alert(me);
},
bar2 : function me() {
var index = 2;
alert(me);
}
};
foo.bar1(); // Shows the first one
foo.bar2(); // Shows the second one
Demo: http://jsfiddle.net/W5dqy/5/
AFAIK function foo() { aaa(); } is just var foo = function(){ aaa() } in JavaScript.
Not quite; they're similar, but also quite different. JavaScript has two different but related things: Function declarations (your first example there), and function expressions (your second, which you then assign to a variable). They happen at different times in the parsing cycle and have different effects.
This is a function declaration:
function foo() {
// ...
}
Function declarations are processed upon entry into the enclosing scope, before any step-by-step code is executed.
This is a function expression (specifically, an anonymous one):
var foo = function() {
// ...
};
Function expressions are processed as part of the step-by-step code, at the point where they appear (just like any other expression).
Your quoted code is using a named function expression, which look like this:
var x = function foo() {
// ...
};
(In your case it's within an object literal, so it's on the right-hand side of an : instead of an =, but it's still a named function expression.)
That's perfectly valid, ignoring implementation bugs (more in a moment). It creates a function with the name foo, doesn't put foo in the enclosing scope, and then assigns that function to the x variable (all of this happening when the expression is encountered in the step-by-step code). When I say it doesn't put foo in the enclosing scope, I mean exactly that:
var x = function foo() {
alert(typeof foo); // alerts "function" (in compliant implementations)
};
alert(typeof foo); // alerts "undefined" (in compliant implementations)
Note how that's different from the way function declarations work (where the function's name is added to the enclosing scope).
Named function expressions work on compliant implementations. Historically, there were bugs in implementations (early Safari, IE8 and earlier). Modern implementations get them right, including IE9 and up. (More here: Double take and here: Named function expressions demystified.)
So, in this example the me variable shoudl not be corectly resolved from inside the methods
Actually, it should be. A function's true name (the symbol between function and the opening parenthesis) is always in-scope within the function (whether the function is from a declaration or a named function expression).
NOTE: The below was written in 2011. With the advances in JavaScript since, I no longer feel the need to do things like the below unless I know I'm going to be dealing with IE8 (which is very rare these days).
Because of implementation bugs, I used to avoid named function expressions. You can do that in your example by just removing the me names, but I prefer named functions, and so for what it's worth, here's how I used to write your object:
var foo = (function(){
var publicSymbols = {};
publicSymbols.bar1 = bar1_me;
function bar1_me() {
var index = 1;
alert(bar1_me);
}
publicSymbols.bar2 = bar2_me;
function bar2_me() {
var index = 2;
alert(bar2_me);
}
return publicSymbols;
})();
(Except I'd probably use a shorter name than publicSymbols.)
Here's how that gets processed:
An anonymous enclosing function is created when the var foo = ... line is encountered in the step-by-step code, and then it is called (because I have the () at the very end).
Upon entry into the execution context created by that anonymous function, the bar1_me and bar2_me function declarations are processed and those symbols are added to the scope inside that anonymous function (technically, to the variable object for the execution context).
The publicSymbols symbol is added to the scope inside the anonymous function. (More: Poor misunderstood var)
Step-by-step code begins by assigning {} to publicSymbols.
Step-by-step code continues with publicSymbols.bar1 = bar1_me; and publicSymbols.bar2 = bar2_me;, and finally return publicSymbols;
The anonymous function's result is assigned to foo.
These days, though, unless I'm writing code I know needs to support IE8 (sadly, as I write this in November 2015 it still has significant global market share, but happily that share is plummetting), I don't worry about it. All modern JavaScript engines understand them just fine.
You can also write that like this:
var foo = (function(){
return {
bar1: bar1_me,
bar2: bar2_me
};
function bar1_me() {
var index = 1;
alert(bar1_me);
}
function bar2_me() {
var index = 2;
alert(bar2_me);
}
})();
...since those are function declarations, and thus are hoisted. I don't usually do it like that, as I find it easier to do maintenance on large structures if I do the declaration and the assignment to the property next to each other (or, if not writing for IE8, on the same line).
Both me lookups, are only visible/available inside the function expression.
Infact those two are named function expressions, and the ECMAscript specification tells us, that the name of an expression is not exposed to the such called Variable object.
Well I tried to put that only in a few words, but while trying to find the right words, this ends up in pretty deep chain of ECMAscript behavior. So, function expression are not stored in a Variable / Activation Object. (Would lead to the question, who those guys are...).
Short: Every time a function is called, a new Context is created. There is some "blackmagic" kind of guy that is called, Activation object which stores some stuff. For instance, the
arguments of the function
the [[Scope]]
any variables created by var
For instance:
function foo(test, bar) {
var hello = "world";
function visible() {
}
(function ghost() {
}());
}
The Activation Object for foo would look like:
arguments: test, bar
variables: hello (string), visible (function)
[[Scope]]: (possible parent function-context), Global Object
ghost is not stored in the AO! it would just be accesssible under that name within the function itself. While visible() is a function declaration (or function statement) it is stored in the AO. This is because, a function declaration is evaluated when parsing and function expression is evaluated at runtime.
What happens here is that function() has many different meanings and uses.
When I say
bar1 : function me() {
}
then that's 100% equivalent to
bar1 : function() {
}
i.e. the name doesn't matter when you use function to assign the variable bar1. Inside, me is assigned but as soon as the function definition is left (when you assign bar2), me is created again as a local variable for the function definition that is stored in bar2.