求高人解释一段代码!!!

浴火_凤凰 2011-06-23 10:57:21

var Bind = function(object, fun) {
var args = Array.prototype.slice.call(arguments).slice(2);
return function() {
return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}

1.我知道Array.prototype.slice这貌似是扩展数组的原始方法。
但是Array.prototype.slice.call(arguments)是什么意思?
这里的arguments是调用slice的时候还是调用Bind的时候传进去的参数???
Array.prototype.slice.call(arguments).slice(2);
这一整句又是什么意思?
我真的很晕。。。
2.args.concat(Array.prototype.slice.call(arguments));
这一句又是什么意思?这段代码是做什么用的?求解释。
...全文
207 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
ZiSheng 2011-07-06
  • 打赏
  • 举报
回复
是为了绑定this。
ZiSheng 2011-07-05
  • 打赏
  • 举报
回复
那在这个环境里边呢:
http://topic.csdn.net/u/20090319/01/ec60caf1-af16-47b5-a89b-bb91e1c5c6e2.html
这个幻灯片切换里边的代码Bind方法的用意似乎和星期六的黄昏解释的不一样。
ZiSheng 2011-07-05
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 xingqiliudehuanghun 的回复:]
引用 12 楼 zisheng 的回复:
而是再加入一个匿名函数之后。???

如果象你那样用的话,返回的是函数的执行结果,就失去了套用的本意。
套用的本意就是将一个原本可以输入多个参数的函数进行加工,使其中的
前几个参数固定下来,使更便于使用。
就好比有一个函数
fn(n1, n2, n3, n4){}
如果你需要连续调用n次,且每次前三个参数都一样,那么你可以这样:
fn(1……
[/Quote]
解释的太详细了,明白了,星期六的黄昏,谢谢了,嘿嘿。
这个sum += i;应该是sum += arguments[i];
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zisheng 的回复:]
而是再加入一个匿名函数之后。???
[/Quote]
如果象你那样用的话,返回的是函数的执行结果,就失去了套用的本意。
套用的本意就是将一个原本可以输入多个参数的函数进行加工,使其中的
前几个参数固定下来,使更便于使用。
就好比有一个函数
fn(n1, n2, n3, n4){}
如果你需要连续调用n次,且每次前三个参数都一样,那么你可以这样:
fn(1, 2, 3, 0);
fn(1, 2, 3, 1);
fn(1, 2, 3, 2);
fn(1, 2, 3, 3);
fn(1, 2, 3, 4);
……

如果你不嫌麻烦,你可以那样用,而且好理解。但是如果你想偷懒的话
可以对函数进行下包装。
var fn2 = curry(fn);
fn2(0);
fn2(1);
fn2(2);
fn2(3);
……
两种风格实现的功能一样,就看你喜欢那一种了。
ZiSheng 2011-07-04
  • 打赏
  • 举报
回复
而是再加入一个匿名函数之后。???
ZiSheng 2011-07-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xingqiliudehuanghun 的回复:]
这个是函数式编程中的套用,所谓套用就是将一个接受多个参数的函数
进行包装,返回一个需要输入的参数个数较少的新函数,使其更方便
使用.

JScript code
function add(){
var i, args = arguments, len = args.length, sum = 0;
for(i=0; i < len; i++){
su……
[/Quote]
为何curry不这样
function curry(fn){
var args = [].slice.call(arguments, 1);
return fn.apply(null,args);
}
wangliwei230 2011-06-23
  • 打赏
  • 举报
回复
路过 学习!!!
JParser 2011-06-23
  • 打赏
  • 举报
回复
字面上的解释就是将一个对象绑定到一个函数,本质上就是改变这个函数运行时上下文环境,主要就是改变函数里的this.类库差不多都有这方法。第一个arguments为被用Bind时的,其它的如1楼所述。2楼的说法不太对。
calm_down2010 2011-06-23
  • 打赏
  • 举报
回复
up.
  • 打赏
  • 举报
回复
js中的数组具有concat方法, 该方法会在当前数组的基础上追加元素形成一个新数组返回。concat的参数中
可以包含数组,若为数组的话会依次将数组中的内容展开后再追加。但是有一点比较麻烦arguments并不是一个
数组元素,所以需要将其转化为一个数组。转化的方法就是调用:Array.prototype.slice.call(arguments)
  • 打赏
  • 举报
回复
这个是函数式编程中的套用,所谓套用就是将一个接受多个参数的函数
进行包装,返回一个需要输入的参数个数较少的新函数,使其更方便
使用.
function add(){
var i, args = arguments, len = args.length, sum = 0;
for(i=0; i < len; i++){
sum += i;
}
return sum;
}

function curry(fn){
var args = [].slice.call(arguments, 1);
return function(){
var moreArgs = [].slice.apply(arguments)
return fn.apply(null, args.concat(moreArgs ));
}
}

var fn = curry(add, 1, 2, 3);//产生一个可以不用反复输入前三个参数的新函数
alert(fn(4,5,6));
挨踢直男 2011-06-23
  • 打赏
  • 举报
回复
这段是改变对象的作用域时候用的吧
Array.prototype.slice.call(arguments)在arguments对象上调用 数组的slice方法
Array.prototype.slice.call(arguments).slice(2)返回一个arguments中的子数组
args.concat(Array.prototype.slice.call(arguments));把子数组与原有的arguments连接起来
这么操作估计是想在转移过程中保持参数不变吧

<input type="button" id="x" />
<input type="button" id="y" />
<script type="text/javascript">
var Bind = function(object, fun) {
var args = Array.prototype.slice.call(arguments).slice(2);
return function() {
return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}
var o = new Object()
o.f=function(){alert(this)};
document.getElementById("x").onclick=o.f;
document.getElementById("y").onclick=Bind(o,o.f);
</script>
lsw645645645 2011-06-23
  • 打赏
  • 举报
回复

你说的两点,我都很认同,受教了
JParser 2011-06-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 lsw645645645 的回复:]

JScript code

<script type="text/javascript">

var Bind = function (object, fun) {
var args = Array.prototype.slice.call(arguments).slice(2);
return function () {
……
[/Quote]

这里有很多不对的地方,
首先arguments不是数组,为object。你可以看Object.prototype.toString.call(arguments)的结果是[object Object]而不是[array Object],同样你可以用constructor去验证,一个简单的就是你可以直接打印出一个数组,而arguments你是打印不出来的。
第二,“Array.prototype.slice.call(arguments)这句是扩张arguments,给它一个slice方法”,Array.prototype.slice.call(arguments)不是扩张arguments,而是在arguments这个object下执行Array的slice方法,返回一个数组,这个数组的元素是arguments里能用数字索引到的,如果arguments[0];这时再接一个slice(2),前面的以经返回了一个数组,就和[1,2,3].slice(2)一样了,不是什么扩张出来的slice,跟本没有这种说法。

Array.prototype.slice.call(arguments).slice(2)可以写成Array.prototype.slice.call(arguments,2);
皮特张 2011-06-23
  • 打赏
  • 举报
回复
顶一下。
lsw645645645 2011-06-23
  • 打赏
  • 举报
回复

<script type="text/javascript">

var Bind = function (object, fun) {
var args = Array.prototype.slice.call(arguments).slice(2);
return function () {
return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}

//首先说下arguments
//对于每个函数它都有个隐形的参数,就是arguments,它是个数组
//例如
function a(p1) {
alert(arguments[0])
}
a(1)//输出1
function b(p1,p2){
alert(arguments[0] + ',' + arguments[1])
}
b(1,2)//输出(1,2)

//arguments 它的类型是Array,但它是个特殊的Array,它没有slice方法

//Array.prototype.slice.call(arguments)这句是扩张arguments,给它一个slice方法,

//然后调用刚刚扩张出来的slice(2)方法,取得函数function(object,fun) 第二个参数后面的所有参数。

//args.concat 这个是合并两个数组的意思,把args 和 arguments 合并起来

//return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));

//这个的意思,就是把所有参数传入到 fun 这个数里面,所有的参数包括(之前的args,还有后面args.concat的)

//这个函数的作用域是Object(至于作用域和call,apply 可以搜索相关资料)

//最后举个例子,例如,有两个人,一个是645,男,一个是abc,女
var obj = {
name: '645',
sex:true,//男
say: function () {//自我介绍
if (this.sex) {
alert('Hi my name is ' + this.name + ' ,I am boy');
}
else {
alert('Hi my name is ' + this.name + ' ,I am girl');
}
}
};
obj.say(); //输出 'Hi my name is 645 I am boy'

//下面我换人了,但是没有加性别
var obj2 = {
name:'abc'
}
//把这些变更,绑定到say函数上
var fn = Bind(obj2, obj.say, false)//这个性别改成flase,为女,注意,false(性别女)也传入到函数里了,这里是关键

fn(); //输出 'Hi my name is abc I am girl'

//有说的不对的,望高人指正

</script>

87,915

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧