zoukankan      html  css  js  c++  java
  • JS call和apply用法(转)

    每个JavaScript函数都会有很多附属的(attached)方法,包括toString()、call()以及apply()。听起来,你是否会 感到奇怪,一个函数可能会有属于它自己的方法,但是记住,JavaScript中的每个函数都是一个对象。看一下 这篇文章 ,复习一下(refresher)JavaScript特性。你可能还想知道JavaScript中函数和方法的区别。我认为“函数”和“方法”的描述, 仅仅是JavaScript的习惯约定而已。函数立足于它们自己(例如:alert()),而方法是函数内部一个对象的属性(dictionary),我 们通过对象来调用方法。每个JavaScript对象都有一个toString()方法,下面通过代码举例说明,在一个函数对象中,我们可以使用 toString()方法。

    function foo(){
     alert('x');
    }
    alert(foo.toString());

    因为函数都是对象,它们有自己的属性和方法。我们可以把它们看作数据(data)。这篇文章,我们只关注两个函数的方法apply()以及call()。

    我们从下面的代码开始:

    var x = 10;
    function f(){
     alert(this.x);
    }
    f();

    我们定义了一个全局函数f()。f()通过this关键字访问变量x,但是需要注意的是,我们不能通过一个对象的实例来调用这个函数。this指向 的是什么对象呢?this会指向这个全局对象。我们的变量x就是在这个全局对象中定义的。上面的代码能够正常运行,运行结果会显示一个对话框,对话框中显 示10。

    我们可以通过this来调用call()和apply()。正如下面的例子展示如何使用call():

    var x = 10;
    var o = { x : 15};
    function f(){
     alert(this.x);
    }
    f();
    f.call(o);

    首先调用f()将会显示10的对话框,因为this这个时候指向的是全局对象。然后我们调用f函数的call()方法,传入的参数是o,运行结果显 示的是o中x属性的值15。call()方法会用它的第一个参数作为f函数的this指针。也就是说,我们会告诉运行时,f函数中的this指向的是哪个 对象。

    this跳转听起来有些滑稽,甚至对于C++、Java以及C#程序员来说有些反常。这些都是ECMAScript中有趣的部分。

    通过call()也可以给函数传递参数:

    var x = 10;
    var o = { x : 15};
    function f(){
     alert(this.x);
    }
    f();
    f.call(o);

    apply()和call()类似的,只是apply()要求第二个参数必须是一个数组。这个数组会作为参数传递给目标函数。

    var x = 10;
    var o = {x : 15};
    function f(message) {
     alert(message);
     alert(this.x);
    }
    f('invoking f');
    f.apply(o, ['invoking f through apply']);

    apply()方法是很有用的,因为我们可以创建一个函数而不用去关心目标方法的参数。这个函数可以通过apply()的第二个数组参数来传递额外的参数给方法。

    var o = {x : 15};
    function f1(message1) {
     alert(message1 + this.x);
    }
    function f2(message1, message2) {
     alert(message1 + (this.x * this.x) + message2);
    }
    function g(object, func, args) {
     func.apply(object, args);
    }
    g(o, f1, ['the value of x = ']);
    g(o, f2, ['the value of x squared = ', '. Wow!']);

    这样的语法有点问题。为了调用apply()方法,我们强制目标函数使用数组中的参数。幸运的是,有一个方法可以让这种语法更简单。在此之前,我们必须先介绍一个:参数标识符。

    在JavaScript中,其实每个函数都有一个可变长度的参数列表。这意味着,即使一个函数只有一个参数的时候,我们也可以传递5个参数给它。下面的代码不会有错误,而且结果显示的是“H”。

    function f(message) {
     alert(message);
    }
    f('H', 'e', 'l', 'l', 'o');

    在f()中,如果我们不想去接受其他的参数,我们可以用关键字arguments。arguments代表一个参数对象,它有一个代表长度的属性类似于数组。

    function f(message) {
     // message的值和arguments[0]是一样的
     for(var i = 1; i < arguments.length; i++){
      message += arguments[i];
     }
     alert(message);
    }
    // 结果显示“Hello”
    f('H', 'e', 'l', 'l', 'o');

    你应该知道,严格来讲,arguments不是一个数组。arguments有一个length属性,但是没有split、push、pop方法。在前面的g()函数中,我们可以从arguments中拷贝需要的参数,组成数组,然后把这个数组传递给apply()。

    var o = {x : 15};
    function f(message1, message2) {
     alert(message1 + ( this.x * this.x) + message2);
    }
    function g(object, func) {
     // arguments[0] = object
     // arguments[1] = func
     var args = [];
     for(var i = 2; i < arguments.length; i++) {
      args.push(arguments[i]);
     }
     func.apply(object, args);
    }
    g(o, f, 'The value of x squared = ', '. Wow!');

    当我们调用g(),we can pass additional arguments as parameters instead of stuffing the arguments into an array。

  • 相关阅读:
    BeautifulSoup模块
    爬取校花网视频
    爬虫基本原理
    python学习笔记-50 使用SQLAlchemy
    python学习笔记-49 使用MySQL
    PTA天梯 L3-007 天梯地图
    VS2013 创建ASP.NET MVC 4.0 未指定的错误(异常来自HRESULT: 0x80004005(e_fail))
    动态规划--新手
    文件上传绕过
    C# → 数据库
  • 原文地址:https://www.cnblogs.com/net-study/p/4969020.html
Copyright © 2011-2022 走看看