Consequences of this javascript code - javascript

I am reading the book "Secrets of the JavaScript Ninja" by John Resig and in it he is explaining how one can try to anticipate future functionality of the language by extending objects' prototypes with this code:
if(!Array.prototype.forEach){
Array.prototype.forEach = function(fn, callback){
for(var i = 0; i < this.length; i++){
fn.call(callback || null, this[i], i, this);
}
};
}
Now, I understand that the "callback || null" statement prevents from passing a possible undefined value to the "call" function. What I do not understand is what could be the consequences of passing null as the context of the "fn" parameter. Wouldn't that make the code crash?
Thank you for any explanation and/or enlightenment you can provide.

There is no "real" problem with this, the context "this" is just equal to null then.
Thats a common way when using .call() or .apply() if you do not have an appropriate value for the context.

Function.call's first parameter is the scope to run the function in. If that parameter is falsey (null is one form of falsey) then it will run that function in the global scope. In browsers that means the function will run with this set to window.
The callback || null isn't needed, if you pass undefined in as the scope, it will use window. Although possibly there is some obscure browser or situation where it doesn't, which would explain why Resig did that.

No, it won't cause a crash. According to https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/call:
[…] if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.
(In the case of a Web-page, "the global object" is window.)

Related

confusion over how "softBind" function works

I'm currently studying javascript by following the "you dont know js" series.
In section "this & object prototype", the author came up with an way to soft bind this.
However, I am extremely confused by the code. So I was wondering if someone could kindly explain it to me, steps by steps, what the code really does?
//step 1: if "softBind" property does not exist on `Function.prototye`
if (!Function.prototype.softBind) {
//step 2: create a property named "softBind" on "Function.prototype" and assign to "softBind" the following function
Function.prototype.softBind = function(obj) {
//step 3: what is the point of assigning "this" to the variable "fn"?
//what does "this" represent at this point in time?
var fn = this,
//step 4: I understand that "arguments" is an array-like object, i.e. "arguments" is not a true array.
//But you can convert "arguments" to an true array by using "[].slice.call(arguments)".
//The thing I dont understand here is, why the 1?
//I understand it tells "slice" method to start slicing at index 1, but why 1?
//And what is the purpose of "curried" variable?
curried = [].slice.call( arguments, 1 ),
bound = function bound() {
//step 5: I understand what "apply" function does
return fn.apply(
//step 6: I dont really understand how "!this" works.
(!this ||
//step 7: utterly confused...
(typeof window !== "undefined" &&
this === window) ||
(typeof global !== "undefined" &&
this === global)
//step 8: if the above statements evaluates to "true", then use "obj",
//otherwise, use "this"
) ? obj : this,
//step 9: can't I write "curried.concat(arguments)" instead?
//why the convoluted syntax?
curried.concat.apply( curried, arguments )
);
};
//step 10: Why assign the "fn.prototype" as the prototype to "bound.prototype"?
bound.prototype = Object.create( fn.prototype );
return bound;
};
}
I'm very sorry for the long question, but I thought instead of dividing the question into several posts, it is more convenient if they are put into one place.
step 3: what is the point of assigning "this" to the variable "fn"?
The value of this holds a pointer to the currently executing function object. Only function objects can be held, so only things actually created through new() or equivalent notation. This can be useful for passing a reference to an outer object to an inner object created within said outer object.
Here's a minimal example:
function fn1() {
var x = this; // x = fn1.
this.u = 5;
function fn2() {
this.u = 10;
console.log(this.u); // Prints the member of fn2.
console.log(x.u); // Prints the member of fn1.
};
var W = new fn2();
}
var V = new fn1();
The output should be:
10
5
First, an object of type fn1 is created called V. It has a member variable u holding the value 5. Then, we create an object of type fn2 called W within fn1. It also has a member variable u, but here it holds the value 10. If we wanted to print the value of V.u within W, then we need a pointer to V. Calling this.u within W would output its u value (10), which is not what we want. So we define a variable x within the scope of the class fn1, holding the this pointer for us. Now it's possible to access the members of fn1 within fn2.
Step 4
The first argument is the object being bound to. You don't want to pass that to the function being bound, that would break its functionality, for it does not expect an extra argument prepended to its normal list of arguments. So, the first argument has to be removed.
step 6: I dont really understand how "!this" works.
!this is simply a way of checking whether this is defined. If it is not, then the value will be true. Otherwise, since this
would be an object (which evaluate to true when cast to a boolean), then it is false.
step 7: utterly confused...
Here, the original author checks if this is equal to either window, or global. Note; In modern browsers, checking for just window is enough, but IE exists (as do non-browser javascript environments). So, the full statement evaluates to this thing:
If I am not called from within an object, or if I'm called from the object window or global, then return the object softbind was created with. Otherwise, return the object I was called from
Note that this is exactly what the author of the original article wants. When a library function is called with this special binding, then we can be sure that whatever the library does; it can't access the global context through the use of the this variable. But, it can access any other object, allowing you to interface with the library.
step 9: can't I write "curried.concat(arguments)" instead?
Curried holds all arguments the original softbind function was called with, except for the first argument. arguments , at this point, is not equal to arguments in the earlier call. Here, it refers to the arguments the bound function is called with, not those it was bound with. This line integrates the two sets of arguments, allowing you to provide default arguments. The trick used here is to concatenate the arguments, e.g. Suppose your function has default arguments [1,2,3,4] and you supply [5,6]:
[1,2,3,4].concat([5,6]) produces [1,2,3,4,5,6].
Why not simply concatenate, and use the prototype? Arrays are passed by reference in javascript, so this will keep curried the same, while concatenating arguments to the call. Equivalently, you could write this:
curried2 = curried.concat(arguments);
return fn.apply(
(.....)
curried2);
Admittedly, the terseness does not help the understandability of this example. Simply re-naming arguments to calledArguments and curried (an advanced math term not relevant to the explanation) to be defaultArguments and using a simple for loop over each argument would be far easier to understand, if a little more verbose. I guess the author wanted to be fancy.
step 10: Why assign the "fn.prototype" as the prototype to "bound.prototype"?
Go up a bit on the article to the part where the author talks about the default bind function and how it works: basically, the end result of replacing the prototype back with the default prototype during the function call means that when your softbind enabled function is called with the new operator this will be set to itself, rather than the default bound object. prototype will not work when simply calling the bound function.
It also enables inheritance, meaning that creating things for a softbind enabled function using its prototype will not have that prototype be overruled by that of softbind when it is bound. (That would make softbind incompatible with prototypes). Instead, both prototypes are used.
Also see this reddit post.
A word of warning
We're extending the language with new features here. Features that aren't exactly necessary, and are largely concerned with semantics. If you're just interested in learning the language, this really goes way too far, you don't exactly need special binding semantics. Worse, it can be confusing if this does not behave in a way you expect it to.
A simpler alternative
Enable strict mode. Now this will default to undefined whenever it points to the global object. Prevents the problem this convoluted code is trying to solve (by usually resulting in errors from functions trying to access member variables or functions of undefined), while at the same time being far easier to use, and at the same time it will complain about a lot of syntax that is valid regular javascript, but a bug in any normal use-case. Also see the MDN article about it. It will catch a lot of potential errors for you instead of silently doing nonsensical things.
Another alternative
bind tries to resolve 'losing' the object when you pass a member function of it to another function, such as setTimeout. Another way of doing it is by using an anonymous function. Instead of using (soft) binding, assuming obj is an object holding a function fn being passed a parameter param;
setTimeout(obj.fn(param), 500);
You can use:
setTimeout(function(param){obj.fn(param);}, 500);
Which avoids the problem through a layer of indirection by passing an anonymous function. Also see this question.

Why 'this' points to window inside a function when apply() or call() is being called?

I'm reading Nicholas Z.Zakas' Professional JavaScript for web developer 3rd edition and inside the Reference types chapter I got a bit confused at the function type part.
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments);
}
alert(callSum1(10,10)); //20
He says:
"In this example, callSum1() executes the sum() method, passing in this as the this value (which is equal to window because it's being called in the global scope) and also passing in the arguments object."
I understand what he says, but I don't understand the why. This supposed to point to the function doesn't it? Now I'm confused that it's pointing to the window because it's being called in the global scope ..
Can someone be kind to explain it to me? :)
I'm not sure if I will or I have to use this technique later, but I want to make sure I understand it, especially the this part. More details about this and its usage will come in the OOP section, but it's now an interesting question.
Thanks in advance!
The value of this depends on how you call a function.
If you call a function using call or apply then the value of this will be the first argument to that function.
Here you have sum.apply(this, arguments); so it will pass the current value through. As usual, that value is determined by how you call the function.
Since you call callSum1(10,10) with no context, this will be window.
(If you were in strict mode, it would be undefined. If you weren't in a browser, it would be whatever the default object of the JS environment you were using was).
Here:
alert(callSum1(10,10)); //20
...you're calling callSum without doing anything to set this during the call, and so this is defaulted to the global object (window, on browsers). (In loose mode; in strict mode, this would have been undefined.)
Since you're then using apply and passing that same this into it:
return sum.apply(this, arguments);
...naturally the global object is also used when calling sum.
I understand what he says, but I don't understand the why. This supposed to point to the function doesn't it?
No, this almost never refers to functions. (It can, of course, it just very rarely does.)
Now I'm confused that it's pointing to the window because it's being called in the global scope ..
It's not because it's being called in the global scope; it would be the same if it were being called from inside a function. What matters isn't where the call occurs, but how. Any time you call a function without doing anything to set this, in loose mode, this during the function call will be the global object. It doesn't have to be at global scope; what matters is how you call the function.
The rule is actually a lot simpler than people make it out to be: If you call a function without doing anything to set this, during the call, this will be the global object (in loose mode) or undefined (in strict mode). Here are the things you can do to set this during a function call:
Call the function as part of an expression getting the function from a property on an object. For example, foo.bar(); retrieves a reference to the function from the bar property on foo, then calls bar. Because we did it that way, during the call to bar, this refers to foo.
Call the function using .call or .apply; this will be what you pass in the first argument. (In loose mode, if you pass undefined, null, or a non-object in the first argument, during the call this will be the global object. In strict mode, it'll be what you pass.)
Call a bound function. That's a function created via Function#bind (an ES5 feature). Bound functions have this "baked into" them.
More (on my blog):
Mythical methods
You must remember this
Under the Window object part ~20 pages later, I'm reading this: "As mentioned previously, the this value is equivalent to the Global object when a function is executed with no explicit this value specified (either by being an object method or via call()/apply())." :)
Maybe I didn't get it before, but now it's clear with his words as well. By the way, the book is awesome! Now with Math object I can understand much more the apply() method, too.
var values = [1,2,3,4,5,6];
var max = Math.max.apply(Math, values);

JavaScript: how to protect from "undefined" is defined confusion?

In JavaScript undefined is not a keyword, it is a variable. Sort of special variable. This is known to cause trouble because undefined could be reassigned. I do not really know why would anyone want to do that, but this is possible, and maybe you can experience this by using one of those genius frameworks out there, see the code:
function f() {
var z, undefined = 42
console.log(z, undefined, z == undefined)
} f()
Outputs:
undefined 42 false
Now how does one protect himself from such a confusion? Should one just cross his fingers that undefined is undefined?
Just use void 0, it's simply bulletproof. And it's a keyword too.
You can pass undefined as a function parameter, this will ensure that undefined is undefined in the scope of the function.
Many JavaScript libraries use this technique, for example look at jQuery source code
//jQuery
(function( window, undefined ) {
...
})( window );
Because the function expects two formal parameters, but we only give it one, the other gets the (true) value undefined, and then we can rely on that within the function.
one possibility is to check the type of the variable instead of checking equality to undefied:
if (typeof(VARIABLE) != "undefined")
or read on here: How to check for “undefined” in JavaScript?.

Immutable undefined in self invoking functions

It's been a while since ECMAScript 5 came out and is being supported quite well in most modern browsers (IE9, CH 19+, FF 4+) and with it so is the "Immutable undefined". Though I keep seeing "undefined" being passed like so:
(function ( ..., undefined ) {
})(...);
From what I can tell Crockford's JSLint tool doesn't really like it:
Expected an identifier and instead saw 'undefined' (a reserved word).
Even though it's not being passed (there's no argument on the function call) and it's really an identifier. I understand that his tool isn't a bible we should follow to the death and on the other hand JSHint doesn't seem to care about it.
Is this still considered a best practice today and how does it affect code performance/security? Considering browser support >= IE9.
Is this still considered a best practice today and how does it affect code performance/security? Considering browser support >= IE9.
Much like undefined, Infinity is a non-writable property of the global object rather than a literal like null, so it can be used as a parameter name without raising an error. Lets consider a function like this
function example(Infinity) {
return Infinity;
}
In example, Infinity is no longer a non-writable property and instead acts like any other parameter to a function, initialised as undefined if nothing is passed or otherwise taking the value of the argument. This means in this function you can't just assume Infinity will mean Infinity, because it doesn't, but you could assume it will mean undefined.
So let's go back to the question of undefined. It will be initialised as undefined so the meaning will stay the same, however, it has now lost it's immutability within the function and therefore any typos assinging a values to undefined will have this error carried forward. Additionally, if a parameter is passed to the function the value will be different from the start.
Therefore to conclude, it does have an effect on security, as an undefined like this is no longer as "safe" because it has lost it's immutable status and can be changed.
It may be interesting to note that undefined is not actually a reserved word. If you require an undefined for compatibility, rather than adding it as a parameter name, I would suggest using a simple var undefined; at the top of the function or in the global namespace where you will find var undefined; undefined = 1; undefined; // undefined where it is immutable.
If you wanted to comply with jsLint, you could use another variable that is not a reserved word instead of undefined. The following complies with jsLint:
(function (window, document, undef) {
'use strict';
}(window, document));
You would, however, need to remember to use your newly defined variable (in this case undef instead of undefined). The strict mode above was added to comply with jsLint. This is mostly used so that you know for certain that the variable you are testing to be undefined is actually undefined.
Note, that if you're running this example in the text area provided on the jsLint website, you may need to define window and document. I was receiving two errors until I did so.
var window = window; //global window object
var document = document; //global window object
However, I'm of the opinion that:
(function (..., undefined) {
'use strict';
}(...));
is perfectly fine and more importantly, highly recommended.
There are cases where reserved words can be changed from their normal states. Such as setting undefined to true. Paul Irish discusses this briefly in his video: http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/

null passed as context to a function call

Please explain what hack is used here (I can see that null is passed as a context to a function returning a property of it's context. So I can't clearly understand what is actually happening here.
function getGlobal(){
return (function(){
return this.dust;
}).call(null);
}
Setting the context to null will make this pointing to the global object. So the code provided will act as accessing the dust property of the global object.
According to the specification of ECMA 262 v5, 10.4.3 Entering Function Code
if thisArg is null or undefined, set the ThisBinding to the global object.
see http://es5.github.com/#x10.4.3
The trick is to use the fact that if you don't have a receiver of the function, window (in fact the global object of the executed script, hence the name) is used.
So this trick enables to bypass a property (dust) defined in the nearest embedding context and use the one defined in the global object.

Categories