zoukankan      html  css  js  c++  java
  • JavaScript方法call,apply,caller,callee,bind的使用详解及区别

    一、call 方法

    调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容)。

    即  “某个方法”当做“指定的某个对象”的“方法”被执行。

    Js代码

    call([thisObj[,arg1[, arg2[, [,.argN]]]]])

    参数

    thisObj

    可选项。将被用作当前对象的对象。

    arg1, arg2, , argN

    可选项。将被传递方法参数序列。

    说明

    call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

    举例一:

    01 <input type="text" id="myText" value="input text">
    02 function Obj(){
    03     this.value = "对象!";
    04 }
    05  
    06 var value = "global 变量";
    07  
    08 function Fun1() {
    09     alert(this.value);
    10 }
    11  
    12 window.Fun1(); //global 变量
    13 Fun1.call(window); //global 变量
    14 Fun1.call(document.getElementById('myText')); //input text
    15 Fun1.call(new Obj()); //对象!

    举例二:

    01 var first_object = {
    02     num: 42
    03 };
    04  
    05 var second_object = {
    06     num: 24
    07 };
    08  
    09 function multiply(mult) {
    10     return this.num * mult;
    11 }
    12  
    13 multiply.call(first_object, 5); // returns 42 * 5
    14 multiply.call(second_object, 5); // returns 24 * 5

     

    二、apply方法

    apply方法的第一个参数也是要传入给当前对象的对象,即函数内部的this。后面的参数都是传递给当前对象的参数。

    对于apply和call两者在作用上是相同的,但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数:apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始),如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1, [var1,var2,var3])。同时,使用apply的好处是可以直接将当前函数的 arguments对象 作为apply的第二个参数传入

    01 var func = new function() {
    02     this.a = "func";
    03 }
    04  
    05 var myfunc = function(x, y) {
    06     var a = "myfunc";
    07     alert(this.a);
    08     alert(x + y);
    09 }
    10  
    11 myfunc.call(func, "var""fun"); // "func" "var fun"
    12 myfunc.apply(func, ["var""fun"]); // "func" "var fun"

    三、caller 属性

    返回一个对函数的引用,即调用了当前函数的函数体。

    functionName.caller :functionName 对象是所执行函数的名称。

    说明

    对 于函数来说,caller 属性只有在函数执行时才有定义。 如果函数是由 JScript 程序的顶层调用的,那么 caller 包含的就是 null 。如果在字符串上下文中使用 caller 属性,那么结果和 functionName.toString 一样,也就是说,显示的是函数的反编译文本。

    01 function CallLevel(){
    02     if (CallLevel.caller == null) {
    03         alert("CallLevel was called from the top level.");
    04     else {
    05         alert("CallLevel was called by another function: " + CallLevel.caller);
    06     }
    07 }
    08  
    09 function funCaller(){
    10     CallLevel();
    11 }
    12  
    13 CallLevel();
    14 funCaller()

    四、callee属性

    返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文。

    [function.]arguments.callee:可选项 function 参数是当前正在执行的 Function 对象的名称。

    说明

    callee 属性的初始值就是正被执行的 Function 对象。
    callee 属性是 arguments 对象的一个成员,它表示对函数对象本身的引用,这有利于匿 函数的递归或者保证函数的封装性,例如下边示例的递归计算1到n的自然数之和。而该属性仅当相关函数正在执行时才可用。还有需要注意的是callee拥有length属性,这个属性有时用于验证还是比较好的。arguments.length 是实参长度,arguments.callee.length 是形参长度,由此可以判断调用时形参长度是否和实参长度一致。

    01 // callee可以打印其本身
    02 function calleeDemo() {
    03     alert(arguments.callee);
    04 }
    05  
    06 // 用于验证参数
    07 function calleeLengthDemo(arg1, arg2) {
    08     if (arguments.length == arguments.callee.length) {
    09         window.alert("验证形参和实参长度正确!");
    10         return;
    11     else {
    12         alert("实参长度:" + arguments.length);
    13         alert("形参长度: " + arguments.callee.length);
    14     }
    15 }
    16  
    17 //递归计算
    18 var sum = function(n){
    19     if (n <= 0) {
    20         return 1;
    21     else {
    22         return n + arguments.callee(n - 1);
    23     }
    24 }

    五、bind

    01 var first_object = {
    02     num: 42
    03 };
    04  
    05 var second_object = {
    06     num: 24
    07 };
    08  
    09 function multiply(mult) {
    10     return this.num * mult;
    11 }
    12  
    13 Function.prototype.bind = function(obj) {
    14     var method = this,
    15     temp = function() {
    16         return method.apply(obj, arguments);
    17     };
    18  
    19     return temp;
    20 }
    21  
    22 var first_multiply = multiply.bind(first_object);
    23 first_multiply(5); // returns 42 * 5
    24  
    25 var second_multiply = multiply.bind(second_object);
    26 second_multiply(5); // returns 24 * 5

     

     

    +++++++++++++++++++++++++++++++++++++++++++++++++++++

     

    caller 与 callee 区别的一些举例:

     

    01 <script type = 'text/javascript'>
    02 function a() {
    03     b();
    04 }
    05  
    06 function b() {
    07     alert(b === arguments.callee)
    08     alert(b.caller === a)
    09     alert(arguments.callee.caller === a)
    10 }
    11 a();
    12  
    13 </script>

    //———-

    01 <script type="text/javascript">
    02 function calleeTest() {
    03     arguments.callee.say("Mr.CT""您好!"); // 获取当前函数句柄
    04 }
    05  
    06 calleeTest.say = function(userName, value) {
    07     alert(userName + "说:" + value);
    08 };
    09  
    10 function callerTest() {
    11     (function() {
    12         arguments.callee.caller.goodbye("Mr.CT""Canca Torvals"); // 获取调用当前函数的函数
    13     })();
    14 }
    15  
    16 callerTest.goodbye = function(userName, userName2) {
    17     alert(userName + " 向 " + userName2 + " 说再见.");
    18 };
    19  
    20 calleeTest();
    21 callerTest();
    22 </script>

     
  • 相关阅读:
    2017ccpc全国邀请赛(湖南湘潭) E. Partial Sum
    Codeforces Round #412 C. Success Rate (rated, Div. 2, base on VK Cup 2017 Round 3)
    2017 中国大学生程序设计竞赛 女生专场 Building Shops (hdu6024)
    51nod 1084 矩阵取数问题 V2
    Power收集
    红色的幻想乡
    Koishi Loves Segments
    Wood Processing
    整数对
    Room and Moor
  • 原文地址:https://www.cnblogs.com/cosiray/p/4512972.html
Copyright © 2011-2022 走看看