Javascript prototype.js函数绑定代码说明
发件人: 有人能告诉我为什么在fn.apply之前需要第二次申报吗 还有,有人能解释为什么需要args.concat吗?为什么不改写为:Javascript prototype.js函数绑定代码说明,javascript,jquery,prototypejs,resig,Javascript,Jquery,Prototypejs,Resig,发件人: 有人能告诉我为什么在fn.apply之前需要第二次申报吗 还有,有人能解释为什么需要args.concat吗?为什么不改写为: fn.apply(object, args) 而不是 return fn.apply(object, args.concat(Array.prototype.slice.call(arguments))); 第二个返回是必需的,因为否则我们将丢失绑定函数的任何返回值 你可能已经知道了这一点,但说出来也无妨。如果我们不在另一个函数中包装f
fn.apply(object, args)
而不是
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
第二个返回是必需的,因为否则我们将丢失绑定函数的任何返回值 你可能已经知道了这一点,但说出来也无妨。如果我们不在另一个函数中包装fn.apply,那么我们直接调用次优函数fn,因为bind只需要设置执行上下文,而不是调用它 Javascript方法可以通过调用调用或对其应用方法来调用。下面是一个小例子:
function example() {
alert("useless example");
}
example.apply() // or example.call(), alerts "useless example";
原型绑定中的外部函数应该像一个围绕绑定函数的不可见包装器一样工作。因此,传递给包装器的任何参数也应该传递给绑定函数,并且它必须返回绑定函数返回的任何值,这就是返回语句存在的原因
在fn.apply内执行args.concat的原因是不同的,它不是可选的。Prototype中的bind允许将参数前置到绑定函数
args表示调用函数bind时传递的参数。arguments表示调用绑定函数时传递的参数。我们基本上连接了两个数组
根据上述示例:
var obj = { x: 'prop x' };
var boundExample = example.bind(obj, 12, 23); // args => 12, 23
boundExample(36, 49); // arguments => 36, 49
// arguments that our example() function receives => 12, 23, 36, 49
第二个返回是必需的,因为否则我们将丢失绑定函数的任何返回值 你可能已经知道了这一点,但说出来也无妨。如果我们不在另一个函数中包装fn.apply,那么我们直接调用次优函数fn,因为bind只需要设置执行上下文,而不是调用它 Javascript方法可以通过调用调用或对其应用方法来调用。下面是一个小例子:
function example() {
alert("useless example");
}
example.apply() // or example.call(), alerts "useless example";
原型绑定中的外部函数应该像一个围绕绑定函数的不可见包装器一样工作。因此,传递给包装器的任何参数也应该传递给绑定函数,并且它必须返回绑定函数返回的任何值,这就是返回语句存在的原因
在fn.apply内执行args.concat的原因是不同的,它不是可选的。Prototype中的bind允许将参数前置到绑定函数
args表示调用函数bind时传递的参数。arguments表示调用绑定函数时传递的参数。我们基本上连接了两个数组
根据上述示例:
var obj = { x: 'prop x' };
var boundExample = example.bind(obj, 12, 23); // args => 12, 23
boundExample(36, 49); // arguments => 36, 49
// arguments that our example() function receives => 12, 23, 36, 49
旧职位,但新方法
Function.prototype.bind = function(){
var fn = this,
context = arguments[0],
args = Array.prototype.slice.call(arguments, 1);
return function(){
return fn.apply(context, args.concat([].slice.call(arguments)));
}
}
obj = {'abc':'x'};
var func = function() {
console.log(arguments);
alert(this.abc);
}
var x = func.bind(obj);
console.log(x(1,2,3));
这是一个很好的例子来解释。运行它并检查控制台日志。
然后修改代码以省略
[].slice.call(arguments)
您将看到x1,2,3执行的console.log不再显示参数。这是因为arguments对象是所有函数中的局部变量。
这听起来可能有点混乱,但它的意思基本上是:
var x = func.bind(obj,1,2,3);
在内部返回此函数:
function() {
return fn.apply(obj, [1,2,3].concat([].slice.call(arguments)));
}
因此,它更像是函数的模板
当您现在以如下方式运行它时:
x(4,5,6)
这将运行:
fn.apply(obj, [1,2,3].concat([].slice.call(arguments)))
使用特殊参数对象={0:4,1:5,2:6},可以使用[].slice.call将其转换为数组
其中,参数是一个本地对象,在函数调用过程中自动分配。旧帖子,但新方法
Function.prototype.bind = function(){
var fn = this,
context = arguments[0],
args = Array.prototype.slice.call(arguments, 1);
return function(){
return fn.apply(context, args.concat([].slice.call(arguments)));
}
}
obj = {'abc':'x'};
var func = function() {
console.log(arguments);
alert(this.abc);
}
var x = func.bind(obj);
console.log(x(1,2,3));
这是一个很好的例子来解释。运行它并检查控制台日志。
然后修改代码以省略
[].slice.call(arguments)
您将看到x1,2,3执行的console.log不再显示参数。这是因为arguments对象是所有函数中的局部变量。
这听起来可能有点混乱,但它的意思基本上是:
var x = func.bind(obj,1,2,3);
在内部返回此函数:
function() {
return fn.apply(obj, [1,2,3].concat([].slice.call(arguments)));
}
因此,它更像是函数的模板
当您现在以如下方式运行它时:
x(4,5,6)
这将运行:
fn.apply(obj, [1,2,3].concat([].slice.call(arguments)))
使用特殊参数对象={0:4,1:5,2:6},可以使用[].slice.call将其转换为数组
其中参数是一个本地对象,在函数调用期间自动分配