zoukankan      html  css  js  c++  java
  • Bind, Call and Apply in JavaScript

    原文地址1:https://variadic.me/posts/2013-10-22-bind-call-and-apply-in-javascript.html

    原文地址2:http://blog.csdn.net/rznice/article/details/26134201

    翻译:

    Bind, Call and Apply in JavaScript 有一天,我在tweet中看到了这个整洁的JS代码片段。

    var bind = Function.prototype.call.bind(Function.prototype.bind); // #fp

    乍一看,我可以猜到它做了什么。 它将x.y(z)变成y(x,z)。 有了孩子般的欢乐,我把它给我的同事。 他们问我做什么。 我打开我的嘴来解释和...没有出来。 我转身走开。

    你看,最好的代码将立即告诉你它做什么。 有了一些功能JavaScript的经验,并且阅读了功能JavaScript和JavaScriptAllongé(这两本神奇的书),我读到它没有问题。 但解释它(和为什么一个人甚至会关心这样做)给没有经验的功能编程的人?

    我决定以我的方式通过它,用简单的例子和许多评论。 这是结果。

    // Set up a simple object to use as "context"
    //设立一个简单地对象作为“上下文”
    var context = { foo: "bar" };
    
    // A function that uses a reference to a variable called "foo"
    // on the "this" context.
    //一个在this上下文中指向foo变量的函数
    function returnFoo () {
      return this.foo;
    }
    
    // This variable does not exist on scope, so is undefined.
    // 变量在作用域中不存在,因此显示undefined
    returnFoo(); // => undefined
    
    // But if we bind the function to the context.
    // 如果我们把它绑定在context上下文中
    var bound = returnFoo.bind(context);
    
    // The name variable is now in scope.
    // 现在的作用域中有这个变量了
    bound(); // => "bar"
    
    //
    // That's what Function.prototype.bind does. Since returnFoo
    // is a function, it inherits the function prototype.
    // 这就是Function.prototype.bind的作用.   
    //由于returnFoo也是函数,因此它继承了function的原型
    //
    // If you enjoyed that, keep reading. It just gets better.
    // 如果你觉得享受,接着往下读,下面更精彩
    //
    
    
    // There are many ways of attaching a context to a function.
    // 有许多方法将函数绑定在一个上下文中
    // Call and apply let you call a function with a given context.
    // Call和Apply让你能在上下文中调用函数
    returnFoo.call(context); // => bar
    returnFoo.apply(context); // => bar
    
    // Including adding the function to the object.
    // 将函数添加到对象中
    context.returnFoo = returnFoo;
    context.returnFoo(); // => bar
    
    //
    // Now let's get freaky with it.
    // 现在我们来玩一点诡异的东西
    //
     
     
    // Array.prototype has this sweet method called slice.
    // You call it on an array, and it gives you a copy of
    // the array from start index to end index (exclusive).
    // Array.prototype 中有一个叫做slice的方法
    // 对一个数组调用slice,可以返回一个从start index到end index的数组
    [1,2,3].slice(0,1); // => [1]
    
    // So we grab slice and assign it to a local variable.
    // 因此我们把Array.slice赋值给一个本地变量slice
    var slice = Array.prototype.slice;
    
    // slice is now "unbound". As Array.prototype.slice usually
    // acts on the context it is given, or "this", it will
    // no longer work.
    //现在的slice是"自由的",由于Array.prototype中的slice一般指定了上下文
    //或者默认为this,此时slice将不起作用
    slice(0, 1); // => TypeError: can't convert undefined to object
    slice([1,2,3], 0, 1); // => TypeError: ...
    
    // But if we recall apply and call, they let us supply a context.
    // 但是如果我们使用call或者apply,slice又将在一个上下文中执行
    slice.call([1,2,3], 0, 1); // => [1]
    
    // Apply works like call, but takes arguments as an array.
    // Apply和Call差不多,知识参数要放在一个数组中
    slice.apply([1,2,3], [0,1]); // => [1]
    
    // It sure gets old using .call though. What if we bind it?
    // That's right! Let's bind "call" to slice. Yes.
    // 使用call没错了,那么能不能使用bind呢?
    // 没错,我们来把"call"绑定在slice上
    slice = Function.prototype.call.bind(Array.prototype.slice);
    
    // Now slice uses the first argument as context.
    // 现在slice可以把第一个参数作为上下文了
    slice([1,2,3], 0, 1); // => [1]
    
    //
    // Pretty cool huh? But I got one last thing for you.
    // 很酷,对吧。现在再来完成一件事
    //
    
    // Let's put "bind" itself through the same process
    // we did "slice".
    // 现在我们对bind本身做一件刚才对silce做的事
    var bind = Function.prototype.call.bind(Function.prototype.bind);
    
    // Wrap your mind around that. Think about it.
    // What does it do? We are flipping "call",
    // returning a function that takes a function
    // and a context and returning a fully bound function.
    // 在这里总结一下,好好想想
    // 发生了什么事? 我们改变了call,
    // 返回一个接受函数的函数和上下文并返回完全绑定的函数。
    
    
    // Bringing back our original example.
    // 回到最初的例子
    var context = { foo: "bar" };
    function returnFoo () {
      return this.foo;
    }
    
    // And using our new amazing "bind".
    // 现在来使用神奇的"bind"函数
    var amazing = bind(returnFoo, context);
    amazing(); // => bar

     

    分析:

    var slice = Array.prototype.slice;
    slice.bind([1,2,3], 0, 1)();// => [1]

    所以,这样直接绑定也是有效的。

  • 相关阅读:
    loadrunner12-参数化以及参数化关联
    loadrunner--vugen录制脚本提示“无Internet访问。您可能无法录制并执行业务进程”
    loadrunner--web_url函数用法
    loadrunner12-用Chrome如何录制脚本
    LoadRunner--Analysis各项指标详解
    Windows Error Code(windows错误代码详解)
    CentOS 7 (Linux) 下载百度网盘大文件
    博客园cnblogs:自定义页面风格
    Windows Server 2003 添加“Resin”到“服务”出错
    转:mysql分页原理和高效率的mysql分页查询语句
  • 原文地址:https://www.cnblogs.com/xmyun/p/6434056.html
Copyright © 2011-2022 走看看