A function and an object at the same time? - javascript

Is it possible that after creating a function variable you can actually assign properties to it as if it's a regular object? This is what I did:
var example = function(a, b){
console.log(a, b);
}
example.someProperty = 'hi there';
Then I typed these lines in the browser console:
example('Hello', 'world') // Hello world
example.someProperty // hi there
So now basically the 'example' var acts as a function and as an object at the same time. This raised some questions for me, one of which is why, and another one - is there a way to do this by creating an object literal, because I can't think of such way.

So now basically the 'example' var acts as a function and as an object at the same time.
It doesn't act as a function and an object, it is a function and an object. Functions are objects in JavaScript.
This raised some questions for me, one of which is why
Fundamentally because that's what Eich decided to do in those 10 days in May 1995. Why he decided that is something only he can answer, but there have been many languages through the years that also see no reason to treat functions as something special and different. Presumably he was influenced by those. It's incredibly handy and flexible that functions are proper objects. For instance:
function foo() {
// ...
}
var f = foo;
I can use the variable f to refer to foo because foo is an object. In many languages, such as Java, it's a real pain to do that (though Java is a bit better now thanks to its recently-added lambdas).
Since functions are objects, they have a prototype, which means I can add features to all functions. For instance: I find it quite handy to be able to take a function and "bake in" (or "curry") arguments:
// A simple function
function foo(a, b) {
console.log("a is " + a);
console.log("b is " + b);
}
// Create a new one that, when called, will call the original passing in
// 1 as the first argument and then passing in any further arguments,
// preserving the `this` it was called with
var f = foo.curry(1);
// Call it
f(2); // "a is 1" / "b is 2"
Since JavaScript doesn't have a curry function (it has bind, which is similar, but interferes with this), I can add one:
var slice = Array.prototype.slice;
Object.defineProperty(Function.prototype, "curry", {
value: function() {
var f = this;
var args = slice.call(arguments);
return function() {
return f.apply(this, args.concat(slice.call(arguments)));
};
}
});
And voilà, now I can use curry on any function:
var slice = Array.prototype.slice;
Object.defineProperty(Function.prototype, "curry", {
value: function() {
var f = this;
var args = slice.call(arguments);
return function() {
return f.apply(this, args.concat(slice.call(arguments)));
};
}
});
// A simple function
function foo(a, b) {
snippet.log("a is " + a);
snippet.log("b is " + b);
}
// Create a new one that, when called, will call the original passing in
// 1 as the first argument and then passing in any further arguments,
// preserving the `this` it was called with
var f = foo.curry(1);
// Call it
f(2); // "a is 1" / "b is 2"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
is there a way to do this by creating an object literal
No, the only way to create a function is to start out with a function. You can't take a non-function object and turn it into a function.

Functions are indeed objects in JavaScript. As any other object, they also have a prototype, that's where methods such as .call(), .apply() & .bind() come from.

Related

About dynamic dispatch in the book-[Programming JavaScript Applications]

I meet a problem about dynamic dispatch. The following is the code snippet which from the book [Programming JavaScript Applications], and I put it on https://jsfiddle.net/abramhum/bbfxxwok/1/
function equals(a, b, c) {
console.log("a[=]" + a);
if (a == b) {
console.log(c);
}
}
function test(a, fn) {
console.log(a + " ---start function[=]");
fn.apply(this);
console.log(a + " ---Fnished");
}
var methods = {
init: function(args) {
return 'initializing...';
},
hello: function(args) {
return 'Hello, ' + args;
},
goodbye: function(args) {
return 'Goodbye, cruel ' + args;
}
},
greet = function greet(options) {
var args = [].slice.call(arguments, 0),
initialized = false,
action = 'init'; // init will run by default
if (typeof options === 'string' &&
typeof methods[options] === 'function') {
action = options;
args.shift();
}
return methods[action](args);
};
test('Dynamic dispatch', function() {
var test1 = greet(),
test2 = greet('hello', 'world!'),
test3 = greet('goodbye', 'world!');
equals(test2, 'Hello, world!',
'Dispatched to hello method.');
equals(test3, 'Goodbye, cruel world!',
'Dispatched to goodbye method.');
});
There exist two subjects in this problem, one is when greet("goodbye", "world") is executed, why it called greet(options), and the value about options is indeed the fist parameter, like "goodbye", and the "world" can be get via arguments; The second is var methods ={...}, it get the arguments like init, and return the value if matching the declare, like init:function(args){...}, but it indeed not code style of switch, and why we can use that in javascript.
This is much unlike C codes, I don't know why, is any one know the reason?
thanks.
one is when greet("goodbye", "world") is executed, why it called greet(options), and the value about options is indeed the fist parameter, like "goodbye", and the "world" can be get via arguments
Because in a JavaScript non-arrow function, arguments is a predefined identifier referring to a pseudo-array of all of the arguments passed to the function. It has nothing to do with dynamic dispatch. It's just a feature of JavaScript functions that was useful back before JavaScript got proper variable parameter lists:
function foo() {
console.log("foo called, total arguments: " + arguments.length);
for (var n = 0; n < arguments.length; ++n) {
console.log("Arg #" + n + ":", arguments[n]);
}
}
foo();
foo("bar");
foo("biz", 42);
the second problem is var methods ={...}, it get the arguments like init
Those aren't arguments, those are properties being defined for the object assigned to methods. Just like a, b, and c here:
var obj = {
a: 42,
b: "Whatever",
c: "just cuz"
};
...and return the value if matching the declare, like init:function(args){...}, but it indeed not code style of switch, and why we can use that in javascript.
Because functions are objects, and so like any other object, you can refer to them from variables, arguments, and object properties. methods's properties init, hello, and goodbye refer to functions. You can call them via the properties: method.init().
So say we have the variable name containing "init". We can look up the property with that name on methods: methods[name]. And since that gives us a reference to a function, we can call that function.
var methods = {
init: function() {
console.log("init called");
}
};
var name = "init";
methods[name](); // "init called"
More: Dynamically access object property using variable
This is much unlike C codes, I don't know why, is any one know the reason?
Because C and JavaScript are fundamentally different languages, created with different design constraints, at different times, by different people, with different priorities and limits.

Understanding Function.call.bind - step-by-step

Everything started with this Question
Then an answer from #MinusFour
var slice = Function.call.bind(Array.prototype.slice);
I wanted to understand, whats happening under the hood,
my curiosity hence this Question.
what to achieve ? understanding of "Function.call.bind".
Step-by-step approach for the same
Started with MDN
NOTE : I am using NodeJS here
1)
var adder = new Function('a', 'b', 'return a + b');
console.log(adder(2, 6));
**OUTPUT **
8
This is expected, Nothing Fancy
2)
This is our end goal , calling function myFunc from the bounded
function (Function.call.bind(myFunc))
function myFunc(a, b) {
console.log(arguments.length, a, b, a + b);
}
3)
var adder = Function(myFunc);
console.log(adder.toString())
OUTPUT
function anonymous() { function myFunc(a, b) { console.log(a + b); } }
Expected! above code does nothing, because i am calling 'anonymous' ,
and it does nothing.
4)
var adder = Function.call(myFunc);
console.log(adder.toString())
OUTPUT
function anonymous() {
}
Expected!. '.call' calls 'Function', with 'this' set to 'myFunc' and with out any param or function body. so an empty anonymous function is the output. Now, I can do "var adder = Function.call(myFunc,myFunc);" to create the same function from step-3
So far so good
5)
var adder = Function.call.bind(myFunc);
console.log(adder.toString())
adder(2,6);
OUTPUT
function () { [native code] }
1 6 undefined NaN
Here first param is not passed to the 'myFunc' function.
this is taken as 'this' for function 'adder' (the bounded Function.call) ?
Now I understand(or did I misunderstood?) until now, but then
How does below code works ?
var slice = Function.call.bind(Array.prototype.slice);
function fn(){
var arr = slice(arguments);
}
in my case first param to adder is discarded(or Function.call consider it as 'this' for it), same should happen with slice above right ?
Anyway, i wanted to document it for a reference
I'm afraid you've gone off in slightly the wrong direction. This line:
var slice = Function.call.bind(Array.prototype.slice);
never calls Function and never arranges for it to be called later. The only thing Function is being used for there is its call property. Function could have been Object or Date or RegExp or any other function, or could have been Function.prototype; doesn't matter. Function.prototype would have been more direct and possibly less confusing.
This is a bit tricky to explain because it involves two layers of dealing with this, where this is different things at different times:
The call function calls functions with a specific this value you give it as its first argument, passing along any other arguments you give it. For example:
function foo(arg) {
console.log("this.name = " + this.name + ", arg = " + arg);
}
var obj = {name: "bar"};
foo.call(obj, "glarb"); // "this.name = bar, arg = glarb"
There, because we called call on foo, call called foo with this set to obj and passing along the "glarb" argment.
call knows what function it should call based on what this is during the call call. foo.call sets this during call to foo. That can be confusing, so let's diagram it:
foo.call(obj, "glarb") calls call:
call sees this = foo and the arguments obj and "glarb"
call calls this (which is foo):
foo sees this = obj and the single argument "glarb"
With regard to slice, you normally see call used with it used to create an array from something array-like that isn't really an array:
var divArray = Array.prototype.slice.call(document.querySelectorAll("div"));
or
var divArray = [].slice.call(document.querySelectorAll("div"));
There, we call call with this set to Array.prototype.slice (or [].slice, which is the same function) and passing in the collection returned by querySelectorAll as the first argument. call calls the function it sees as this, using its first argument as this for that call, and passing along any others.
So that's the first layer of this stuff.
bind is another function that functions have, and it's similar to call but different: Where call calls the target function with a given this and arguments, bind creates and returns a new function that will do that if you call it. Going back to our foo example:
function foo(arg) {
console.log("this.name = " + this.name + ", arg = " + arg);
}
var obj = {name: "bar"};
var fooWithObjAndGlarb = foo.bind(obj, "glarb");
fooWithObjAndGlarb(); // "this.name = bar, arg = glarb"
This is called binding things (obj and the "glarb" argument) to foo.
Unlike call, since bind creates a new function, we can add arguments later:
function foo(arg) {
console.log("this.name = " + this.name + ", arg = " + arg);
}
var obj = {name: "bar"};
var fooWithObj = foo.bind(obj);
fooWithObj("glarb"); // "this.name = bar, arg = glarb"
Okay, now we have all our working pieces. So what's happening in your code? Let's break it into parts:
// Get a reference to the `call` function from the `call` property
// on `Function`. The reason `Function` has a `call` property is that
// `Function` is, itself, a function, which means its prototype is
// `Function.prototype`, which has `call` on it.
var call = Function.call;
// Get a reference to the `slice` function from `Array.prototype`'s `slice` property:
var rawSlice = Array.prototype.slice;
// Create a *bound* copy of `call` that, when called, will call
// `call` with `this` set to `rawSlice`
var callBoundToSlice = call.bind(rawSlice);
(callBoundToSlice is just called slice in your question, but I'm using callBoundToSlice to avoid confusion.) Binding rawSlice to call was the first layer of this handling, determining what call will see as this. Calling callBoundToSlice will call call with this set to rawSlice. Then call will call the function it sees as this (rawSlice), using its first argument as the value for this during the call (the second layer of this handling) and passing on any further arguments.
So our forEach with a collection from querySelectorAll can now look like this:
callBoundToSlice(document.querySelectorAll("div")).forEach(function(div) {
// Each div here
});
That passes the collecton returned by querySelectorAll into callBoundToSlice, which calls call with this as rawSlice, which calls Array.prototype.slice with this set to the collection. Array.prototype.slice uses this to copy the array.
All of that said, using slice to turn array-like objects into true arrays is a bit out of date. ES2015 introduces the Array.from method, which can be shimmed/polyfilled on JavaScript engines that don't have it yet:
var divArray = Array.from(document.querySelectorAll("div"));

Functional Programming - .bind.apply for curry function

Reading about functional programming - got to currying, example has a simple currying function. I understand everything except the last else block.
var curry = function (fn, fnLength) {
fnLength = fnLength || fn.length;
return function () {
var suppliedArgs = Array.prototype.slice.call(arguments);
if (suppliedArgs.length >= fn.length) {
return fn.apply(this, suppliedArgs);
} else if (!suppliedArgs.length) {
return fn;
} else {
return curry(fn.bind.apply(fn, [this].concat(suppliedArgs)), fnLength - suppliedArgs.length);
}
};
};
If the supplied args are >=, call the function with the supplied arguments.
Else if suppliedArgs.length is falsy, return the original function without doing anything.
Else ???
I think recursively call the function?
I don't understand what .bind.apply accomplishes.
Is [this] just in an array because suppliedArgs.push wouldn't return the array?
Start by looking at how you call Function#bind():
fun.bind(thisArg[, arg1[, arg2[, ...]]])
Then consider how you use Function#apply():
fun.apply(thisArg, [argsArray])
So given for bind() we need to call it on a function, and give it multiple parameters (not an array), and all we have is an array of arguments (suppliedArgs in the code), then how can we do that? Well, the main way you can call a function that takes multiple arguments instead of a single argument that is an array is to use .apply() on the function. So then we have fn.bind.apply(...something...).
The first parameter to .apply() is the this value - which needs to be the function to be bound in the case of .bind() (see below for an explanation of why). Hence fn.bind.apply(fn, ...).
Then, the second parameter to .apply() is an array of all the arguments to the function you are invoking, which in the case of .bind() is thisArg[, arg1[, arg2[, ...]]]. Hence we need a single array, with the first value being the value for this within the function, followed by the other arguments. Which is what [this].concat(suppliedArgs) produces.
So the whole fn.apply.bind(fn, [this].concat(suppliedArgs)) thing produces a correctly bound function that will have the supplied arguments to the current function "prefilled", with the correct this context. This function that is produced is then passed as the fn parameter in a recursive call to curry(), which in turn will produce another function in the same way as the top level call will.
The overall effect is that whenever you call a function created by curry(), if you don't pass the expected number of parameters, you will get a new function which takes the remaining number of parameters, or you will evaluate the original function with the entire list of parameters passed in correctly.
e.g.
function addAllNums(a, b, c, d, e) {
return a + b + c + d + e;
}
var curriedAddAll = curry(addAllNums, 5);
var f1 = curriedAddAll(1); // produces a function expecting 4 arguments
var f2 = f1(2, 3); // f2 is a function that expects 2 arguments
var f3 = f2(4); // f3 is a function that expects 1 argument
var f4 = f3(5); // f4 doesn't expect any arguments
var ans = f4(); // ans = 1 + 2 + 3 + 4 + 5 = 15.
// OR var ans = f3(5); => same result
Why the different thisArg values?
Probably the most confusing thing about this line of code is the two different values for thisArg in .bind() and .apply().
For .apply(), the thisArg is what you want the value of this to be inside the function you are calling .apply() on. e.g. myFunction.apply(myObj, ['param1', 'param2']) is equivalent to myObj.myFunction('param1', 'param2').
In this particular case, .bind() is executed on the fn function, so we want fn to be the this value for .bind(), so it knows what function it is creating a bound version of.
For .bind(), the thisArg is what the value of this will be inside the bound function that is returned.
In our case, we want to return a bound function that has the same this value as we currently have. In other words, we want to maintain the this value correctly within the new function, so it doesn't get lost as you create new functions which happens when you call a curried function with less arguments than it expects.
If we did not maintain the this value correctly, the following example wouldn't log the correct value of this. But by maintaining it, the correct value will be output.
var myObj = {
a: 1,
b: curry(function (a, b, c, d) {
console.log('this = ', this);
return a + b + c + d;
})
};
var c = myObj.b(1,1,1); // c is a function expecting 1 argument
c(1); // returns 4, and correctly logs "this = Object {a: 1, b: function}"
// if "this" wasn't maintained, it would log the value of "this" as
// the global window object.
The last else block is the main and most important part of the curry function, as it is the actual line that carries the logic for currying.
return curry(fn.bind.apply(fn, [this].concat(suppliedArgs)), fnLength - suppliedArgs.length);
This is what returns the new function that needs n-1 arguments from your previous function. Why? It's a combination of multiple things:
fn.bind.apply simply calls a function in the context of the function itself, while supplying the needed args (suppliedArgs). Note how the next parameter to curry is fnLength - suppliedArgs.length, which reduces the arguments needed to what was passed.
Let's explain it with the help of ES6. Things are going to become more obvious.
// Imagine we have the following code written in ES5
function fn(a, b, c) {
console.log(a, b, c);
}
var arr = [1, 2, 3];
var funcWithBoundArguments = fn.bind.apply(fn, [null].concat(arr));
Let's convert ES5 to ES6 code
// ES6
function fn(a, b, c) { console.log(a, b, c) }
let arr = [1,2,3];
let funcWithBoundArguments = fn.bind(null, ...arr)
You see? When you bind a function we have to explicitly enumerate all the arguments like:
fn.bind(null, 1, 2, 3)
But how could we bind the content of an array if we don't know its content in advance?
Right, we have to use .bind.apply() where:
the 1st argument of apply is the function (fn) we bind
the 2nd argument is an array which gets the context (as the first item of array) that we bind our function to and the rest of the items of the array are the arguments (which number is variable) we bind to our function (fn).

Javascript fundamental clarification needed

I know little bit C# and now I have started working with JavaScript and I got some problems in understanding the fundamentals.
Here is my code sample:
function BaseFunc(x, y) {
this.X = x;
this.Y = y;
}
function DerivedFunc(x, y, z) {
this.Z = z;
BaseFunc.call(this, x, y);
}
DerivedFunc.prototype = new BaseFunc;
function Test() {
var d = DerivedFunc(1, 2, 3);
var b = new BaseFunc(4, 5);
d.sayHello();
b.sayHello();
}
DerivedFunc.prototype.sayHello = function () {
alert("Result is: " + (this.X + this.Y + this.Z));
}
In the above code I am trying to make an inheritance.
Everything looks good until I reach the line BaseFunc.call(this, x, y); this line is supposed to call base function but what is the use of this in this context.
Is it just to satisfy the signature of method call, how does it work ?
Second question is, in javascript we can add anything dynamically,
In my case I am adding a sayHello() property and assigning it with an anonymous function.
like DerivedFunc.prototype.sayHello, am I adding a property/method to BaseFunc or DerivedFunc, as it is added to prototype it should be added to BaseFunc as I understand it. But when I execute the above code I get error that sayHello is not defined.
Can someone please clarify me about what is going wrong, thanks?
Everything looks good until I reach the line BaseFunc.call(this, x, y); this line is supposed to call base function but what is the use of this in this context.
It's there so that within the call to BaseFunc, this has the same value it has in the call to DerivedFunc, so that the lines this.X = x; and such in BaseFunc are assigning to the correct instance. (Calling a function setting a specific value for this is what the .call and .apply methods of functions do.)
But when I execute the above code I get error that sayHello is not defined.
If it's d.sayHello where you're having the trouble, it's because you've missed out the new operator on the line d = DerivedFunc(1, 2, 3);. Since DerivedFunc, when just called as a function and not via new, doesn't have any return value, d will be undefined.
Note that the way you're doing inheritance, though common, has issues. The main issue is here:
DerivedFunc.prototype = new BaseFunc;
You're trying to use a function designed to create instances, and which accepts arguments, in order to create the prototype instance that DerivedFunc will assign to things. What then is BaseFunc supposed to do about the arguments that are missing? Then later, you call it again (from DerivedFunc) to initialize the instance. BaseFunc is doing double-duty.
Here's how you correct that, first the long-winded version:
function x() { }
x.prototype = BaseFunc.prototype;
DerivedFunc.prototype = new x;
DerivedFunc.prototype.constructor = DerivedFunc;
Or if you can rely on ES5's Object.create:
DerivedFunc.prototype = Object.create(BaseFunc.prototype);
DerivedFunc.prototype.constructor = DerivedFunc;
Now we're not calling BaseFunc to create the prototype, but we are still getting its prototype object as the underlying prototype of DerivedFunc's prototype object. We no longer have the problem of what to do with BaseFunc's arguments, and BaseFunc is only called in the way it's designed to be called: To initialize individual instances, not prototypes.
Naturally, rather than writing that for every time we want to have derived constructors, you'd have a helper script for it.
If you're interested in JavaScript inheritance hierarchies, you may want to look at my short Lineage script — not necessarily to use, but to understand how these things work. The page showing how to do things without the script and comparing to doing them with the script may be particularly useful.
Hi please go through the following. I hope it will give you some idea about inheritence and call()
<script type="text/javascript">
//inheritence
function parent() {
this.add = function (a, b) {
return a + b;
}
this.subtract = function (a, b) {
return a - b;
}
}
function child() {
this.display = function () {
alert(this.add(11, 23));
}
}
child.prototype = new parent(); //child extends parent.... inheritence
child.prototype.constructor = child; //resetting constructor property
var obj = new child();
obj.display();
/*
.call() and .apply()
They allow our objects to borrow methods from other objects and invoke them as their own
*/
var person = {
name: 'Kundan',
display: function(name) {
alert(this.name + ' welcomes ' + name);
}
};
person.display('Dipa'); //Kundan welcomes Dipa
var person1 = { name: 'Java Master' };
person.display.call(person1, 'Sachin'); //Java Master welcomes Sachin
//here person1 object is passed in the call function
//if we are using call inside a function and want to pass the same function object then this is passed in call function
/*
We can pass more parameters as follows
person.display.call(person1, 'a', 'b', 'c');
The method apply() works the same way as call() but with the difference that all parameters you want to pass to the method of the other object are passed as an array.
*/
person.display.apply(person1, ['a', 'b', 'c']);
</script>

Not understanding function and how it is called from Functional Javascript

I just started reading Functional JavaScript and immediately was introduced to a function that I don't understand:
function splat(fun) {
return function(array) {
return fun.apply(null, array);
};
}
var addArrayElements = splat(function(x, y) { return x + y });
addArrayElements([1, 2]);
//=> 3
How does splat(function(x, y) { return x + y }) work. It's called with the array [1,2], but it seems like the anonymous function inside the call to splat takes two parameters, not one array.
Putting console.log(fun) on line 2 of this code shows that fun is the entirety of the anonymous function(x, y) { return x + y }. console.log(array) after return function(array) { shows that array is [1, 2]. Where does array come from then?
Thanks much.
It might be simpler to see how this function would have been written without using the .apply method:
function splat(fun) {
return function(array) {
return fun(array[0], array[1]);
};
}
First you call splat, passing it a function:
var add = function(x,y){ return x + 1 };
var ff = splat(add);
At this point, ff refers to the function(array) function, meaning its an one-argument function. The private variable fun refers to the add function.
Now, you call ff passing its one argument
ff([1,2]);
and it uses the values in the array to call fun with two arguments
return fun(array[0], array[1]);
The only difference between this and the real example is that the apply method lets you work with any argument array length instead of hardcoding a specific length (2) like I did.
//Every time we call this function, we get another one back
function splat(fun) {
return function(array) { // <-- this one will be returned in splat();
return fun.apply(null, array);
};
}
//Step one, call splat, pass a function as parameter
var addArrayElements = splat(function(x, y) { return x + y });
/*
Get back a function that accepts an array, and will execute the function we just passed in on it
*/
// This will call the newly created function, func will be available because it's in a closure
addArrayElements([1, 2]);
The last thing is that, even if the anonymous function takes two parameters, we call apply on it so it will bind array[0] ==> x and array[1] ==> y
This is an example of a higher order function. That's a function that takes functions as arguments and returns functions instead of just regular values (though functions are "just regular values" in Javascript). In this case:
function splat(fun) {
splat takes a function as its argument...
return function(array) {
...and returns a new function which takes an array...
return fun.apply(null, array);
...and when called calls the first fun function with the array .applied as its arguments.
So splat takes one function which expects several parameters and wraps it in a function which takes an array of parameters instead. The name "splat" comes from languages like Ruby, where a * (a "splat" or "squashed bug") in the parameter list of a function accumulates an arbitrary number of arguments into an array.
var addArrayElements = splat(function(x, y) { return x + y });
addArrayElements is now basically:
function (array) {
// closed over variable:
// var fun = function(x, y) { return x + y }
return fun.apply(null, array);
}
Here this is realized by a closure, which closes over and "preserves" the original fun passed to splat in the new returned function.
addArrayElements = function(array) { fun.apply(null, array); };
BUT
it has a closure whereby the variable context of its containing scope (that of the splat function that created the anonymous function) remains visible and accessible.
In JavaScript, functions are first-class objects that can be referenced and passed as arguments or, as in this case, through the closure mechanism.
Edit: about JavaScript and scope
In most languages, variables are, by default, local to the scope they're defined in (which usually is a function's local symbol table). By contrast, in JavaScript a variable is local only if it is defined using the var keyword; otherwise, the symbol will be looked back in the chain of the containing scopes, up to the implicit root object (which in the case of web browsers is window. I.e.,
function foo() { someVar = "bar"; }
foo();
alert(someVar); // shows "bar"
Not being restricted to the local scope, the symbol has been (purposely or not) leaked to the root scope.
Taking it one step further:
function foo() {
var baz = function() {
someVar = "bar";
};
baz();
}
foo();
alert(someVar); // shows "bar"
However, if you declare someVar within foo:
function foo() {
var someVar;
var baz = function() {
someVar = "bar";
};
baz();
alert("someVar in foo=" + someVar); // shows "bar"
}
foo();
alert("someVar in root=" + window.someVar); // shows "undefined"
Note that in this last version I needed to use window.someVar instead of just someVar because someVar never got defined as a variable in the root scope nor as a property of the root object, which caused an error.
a more functional approach uses bind(), which is short enough you don't really need splat anymore, and it's always nice to eliminate closures:
var addArrayElements = Function.apply.bind( function(x, y) { return x + y } , null );
addArrayElements([1, 2]); // === 3

Categories

Resources