Created
December 17, 2010 17:34
-
-
Save tj/745333 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function FunctionBind(this_arg) { // Length is 1. | |
if (!IS_FUNCTION(this)) { | |
throw new $TypeError('Bind must be called on a function'); | |
} | |
// this_arg is not an argument that should be bound. | |
var argc_bound = (%_ArgumentsLength() || 1) - 1; | |
if (argc_bound > 0) { | |
var bound_args = new $Array(argc_bound); | |
for(var i = 0; i < argc_bound; i++) { | |
bound_args[i] = %_Arguments(i+1); | |
} | |
} | |
var fn = this; | |
var result = function() { | |
// Combine the args we got from the bind call with the args | |
// given as argument to the invocation. | |
var argc = %_ArgumentsLength(); | |
var args = new $Array(argc + argc_bound); | |
// Add bound arguments. | |
for (var i = 0; i < argc_bound; i++) { | |
args[i] = bound_args[i]; | |
} | |
// Add arguments from call. | |
for (var i = 0; i < argc; i++) { | |
args[argc_bound + i] = %_Arguments(i); | |
} | |
// If this is a construct call we use a special runtime method | |
// to generate the actual object using the bound function. | |
if (%_IsConstructCall()) { | |
return %NewObjectFromBound(fn, args); | |
} | |
return fn.apply(this_arg, args); | |
}; | |
// We already have caller and arguments properties on functions, | |
// which are non-configurable. It therefore makes no sence to | |
// try to redefine these as defined by the spec. The spec says | |
// that bind should make these throw a TypeError if get or set | |
// is called and make them non-enumerable and non-configurable. | |
// To be consistent with our normal functions we leave this as it is. | |
// Set the correct length. | |
var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; | |
%FunctionSetLength(result, length); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment