They’re much less readable when you write them like that, because when you get a few dozen lines down, this is much clearer than c, especially for people trying to read your code who are used to writing idiomatic JavaScript.
Also, I can live with defining such an argument on initial definition, as with Python’s self in method definitions, but having to add an extra argument to every function/method invocation for the execution scope, that must be passed in every time explicitly or everything breaks, is really obnoxious. You could certainly make up a convention for the proper name, but just using this is more straight-forward, and doesn’t really have any particularly significant downsides.
There’s a reason that pretty much every JavaScript framework includes a bind function/method, and that they’re adding it to the official language spec: it’s a convenient and effective pattern.
What’s an “array hack”? Using Array.prototype.slice on the arguments object? You’re going to have to provide some evidence that language designers didn’t intend that to be possible, before you criticize it. It works perfectly well in every JavaScript implementation. From my perspective, it’s quite often the only reasonable way to deal with the arguments object, and one of the most powerful and flexible ways of making functions with useful APIs in JavaScript.
Turning an object into an array isn't a nice way to do things IMHO. Maybe runtimes optimize for these cases, or maybe they create completely new objects every time and you get fantastic object churn.
Yes it works well, but it's not really necessary. It's inefficient wasted effort.
I guess it's fun to make lovely APIs, but that doesn't help people who just want their js to run fast.
> Turning an object into an array isn't a nice way to do things
This doesn’t happen. The object is unchanged when you call array.slice.
> Maybe runtimes optimize
Only insofar as the built-in array methods are optimized anyway.
> maybe they create completely new objects
No, they don’t. Or rather, yes, array.slice creates a new object to put the slice in, but only because that is part of its declared API.
> Yes it works well, but it's not really necessary.
What’s the alternative?
> It's inefficient wasted effort.
Inefficient how? If you time it, it’s faster other ways of accomplishing the same thing. Whose wasted effort? It certainly saves me time as a JavaScript developer.
* * *
To be honest, I think that arguments should just be an array (then we wouldn’t have any of this trouble), but I assume that’s not possible for the language at this point.
>> This doesn’t happen. The object is unchanged when you call array.slice.
You're wrong. Why don't you check instead of reading API docs or saying what you think should happen? It obviously is changed, and is a new object:
Array.prototype.slice.call({0:"hello",1:"world",foo:"bar",length:2});
Results in ["hello","world"] - the result is a completely new object - inefficient wasted effort. Both in cpu and memory.
Offtopic again, but here's an interesting way to make a new N element array, initialized with undefineds...
ok, but once you start using closures everywhere someone has the bright idea to abstract most of that code into a utility function. before you know it, you're back to bind.
function _bind(o, m) {
var bound_arguments = Array.prototype.slice.apply(arguments, [2]);
return function() {
var now_arguments = Array.prototype.slice.apply(arguments);
var args = bound_arguments.slice().concat(now_arguments);
return m.apply(o, args);
}
}
I really like his approach to teaching JS, but I wish he would finally finish his "Secrets of the JavaScript Ninja" book.
If I recall correct, I pre-ordered this book almost 2 years ago, when it had a release date of a few months later.