zoukankan      html  css  js  c++  java
  • javascript 函数执行上下文

    在js里,每个函数都有一个执行的上下文,我们可以通过this来访问。

    如:

    全局函数

    function test(){

    var local = this;

    }

    我们发现local等于window(dom根对象),也就是说全局函数实际上是window的一个属性。

    同理全局变量也是如此。

    比如 var name = ‘phil’; 我们可以通过window[‘name’]或者window.name 来访问。

    而当函数是某一个对象的属性的时候,该函数的上下文就是该对象。

    var student = {};

    student.age = 20;

    student.getAge = function(){

    return this.age;

    }

    当有函数嵌套的时候,事情就变得稍微复杂点了。

    var seq = [1,2,3,4];

    for(var i in seq){

    var name = ‘phil’ + i;

    window.setTimeout(function(){

            $('p’).apend(name);

    },i*1000)

    }

    有人可能认为输出是phil1phil2phil3phil4,实际上结果是phil4phil4phil4phil4

    因为函数window.setTimeout(实际上我们常常会省略掉window)的上下文实际上是window,而函数体中的name实际上就是window.name

    他的值就是最后一次循环后的值phil4。

    那如果我们需要的结果是phil1phil2phil3phil4那该怎么写:

    var seq = [1,2,3,4];

    for(var i in seq){

    var name = ‘phil’ + i;

    var obj = {};

    obj.name = name;

    obj.setTimeout  = function(){

            var local = this;                  // 该方法是对象obj的属性方法,所以this就是obj

    window.setTimeout(function(){

            $('p’).apend(local.name);        // 此处千万不可以用this,因为此处的this实际上是window。

    },i*1000)

    }

    }

    call和apply通常用来修改函数的上下文,函数中的this指针将被替换为call或者apply的第一个参数

    //定义一个人,名字为jack
    var jack = {
        name : "jack",
        age : 26
    }
     
    //定义另一个人,名字为abruzzi
    var abruzzi = {
        name : "abruzzi",
        age : 26
    }
     
    //定义一个全局的函数对象
    function printName(){
        return this.name;
    }
     
    //设置printName的上下文为jack, 此时的this为jack
    print(printName.call(jack));
    //设置printName的上下文为abruzzi,此时的this为abruzzi
    print(printName.call(abruzzi));
     
    print(printName.apply(jack));
    print(printName.apply(abruzzi));

    只有一个参数的时候call和apply的使用方式是一样的,如果有多个参数:

    function setName(value){

    this.name = value;

    }

     

    setName.apply(jack, ["Jack Sept."]);
    print(printName.apply(jack));
     
    setName.call(abruzzi, "John Abruzzi");
    print(printName.call(abruzzi));

  • 相关阅读:
    [Python自学] day-10 (多进程、数据交互、进程锁、__main__、进程池、协程、gevent、简单爬虫、事件驱动异步IO、select poll epoll)
    [Python自学] day-9 (paramiko、SSH RSA、线程、GIL、互斥锁、信号量、事件、队列)
    [Python自学] day-8 (SocketServer)
    [Python自学] day-7 (静态方法、类方法、属性方法、类的其他、类的来源、反射、异常处理、socket)
    MyBatis学习 之 一、MyBatis简介与配置MyBatis+Spring+MySql
    深入浅出MyBatis-快速入门
    spring整合myBatis
    MyBatis入门学习(一)
    Mybatis中几个重要类
    ibatis源码分析
  • 原文地址:https://www.cnblogs.com/philzhou/p/3282216.html
Copyright © 2011-2022 走看看