zoukankan      html  css  js  c++  java
  • this关键字

    this是JavaScript语言中的关键字。它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。简单的说this所在的函数是当做哪个对象的方法调用的,则该对象就是this所引用的对象,这在编写面向对象的JavaScript编程中起到重要作用。

    下面有四种不同的调用方式的情况。

    第一种:作为函数调用

    [html] view plain copy
     
    1. function test(){  
    2.     this.a=1;  
    3.     alert(this.a);  
    4. }  
    5. test();  //弹出1  

    再次改变。

    [html] view plain copy
     
    1. var a=1;  
    2. function test(){  
    3.    alert(this.a);  
    4. }  
    5. test();  

    深层次进行改变。

    [html] view plain copy
     
    1. var a=2;  
    2. function test(){  
    3.     this.a=1;  
    4. }  
    5. alert(a);    //弹出2  
    6. test();  
    7. alert(a);  //弹出1  

    这里先设置了一个test函数,当执行 test() 时,函数体内的this被绑定到全局对象,接下来执行赋值语句,所以会弹出a的值为1。

    第二种:作为对象方法调用

    [html] view plain copy
     
    1. var test={};  
    2. test.a=1;  
    3. test.b=function{  
    4.      alert(this.a);  
    5. }<pre name="code" class="html">test.b();  
    
    
    
    

    这里先设置了一个test对象,给对象添加了两个属性,当执行 test.b() 时,函数体内的指的是test对象,所以会弹出test对象中的a的值为1。

    [html] view plain copy
     
    1. function test(){  
    2.     alert(this.a);  
    3. }  
    4. var test2={};  
    5. test2.a=1;  
    6. test2.b=test;  
    7. test2.b();  

    这里先设置了test函数和test2对象,给test2对象里设置两个属性,赋予a属性一个值,赋予b属性一个test函数,当执行 test2.b() 时,test2.b函数体内的指的是test2对象,所以会弹出test对象中的a的值为1。

    第三种:作为构造函数调用

    [html] view plain copy
     
    1. function test(){  
    2.      this.a=1;  
    3. }  
    4. var test2=new test();  
    5. alert(test2.a);  //弹出1  

    所谓构造函数,就是通过new一个函数生成新的一个对象。当生成出test2对象,this就指向test2对象,所以结果为2。

    将代码稍作改变,表明this不是全局对象,对全局对象没有任何影响。

    [html] view plain copy
     
    1. var a=2;  
    2. function test(){  
    3.     this.a=1;  
    4. }  
    5. var test2=new test();  
    6. alert(a);  //弹出2  

    第四种:使用apply或者call调用

    在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。apply的用法和call大致相同,只有一点区别,apply只接受两个参数,第一个参数和call相同,第二个参数必须是一个数组,数组中的元素对应的就是函数的形参。注意apply()或者call()参数为空时,默认调用全局对象。

    [html] view plain copy
     
    1. var a=0;  
    2. function test(){  
    3.     alert(this.a);  
    4. }  
    5. var test2={};  
    6. test2.a=1;  
    7. test2.b=test;  
    8. test2.b.apply();  //弹出0  

    由于apply()参数为空,this指的是全局对象。若把最后一行代码修改为

    [html] view plain copy
     
    1. test2.b.apply(test2);  

    此时this指向的就是对象test2。

    扩充内容:

    函数的执行环境

    JavaScript 中的函数既可以被当作普通函数执行,也可以作为对象的方法执行,这是 this 含义如此丰富的主要原因。

    一个函数被执行时,会创建一个执行环境(ExecutionContext),函数的所有的行为均发生在此执行环境中,构建该执行环境时,JavaScript 首先会创建 arguments变量,其中包含调用函数时传入的参数。接下来创建作用域链。然后初始化变量,首先初始化函数的形参表,值为 arguments变量中对应的值,如果 arguments变量中没有对应值,则该形参初始化为 undefined。如果该函数中含有内部函数,则初始化这些内部函数。如果没有,继续初始化该函数内定义的局部变量,需要注意的是此时这些变量初始化为 undefined,其赋值操作在执行环境(ExecutionContext)创建成功后,函数执行时才会执行,这点对于我们理解 JavaScript 中的变量作用域非常重要,我们先不在这里讨论这个话题。最后为 this 变量赋值,如前所述,会根据函数调用方式的不同,赋给 this全局对象,当前对象等。至此函数的执行环境(ExecutionContext)创建成功,函数开始逐行执行,所需变量均从之前构建好的执行环境(ExecutionContext)中读取。

    Function.bind

    this 在 JavaScript 中经常被误用的一种情况:回调函数。JavaScript 支持函数式编程,函数属于一级对象,可以作为参数被传递。请看下面的例子 myObject.handler 作为回调函数,会在 onclick 事件被触发时调用,但此时,该函数已经在另外一个执行环境(ExecutionContext)中执行了,this 自然也不会绑定到 myObject 对象上。
    [html] view plain copy
     
    1. button.onclick = myObject.handler;  

    为了避免这种错误,许多 JavaScript 框架都提供了手动绑定 this 的方法。在ES5中,已经提供了内置的 bind 方法供大家使用。

    [html] view plain copy
     
    1. fun.bind(thisArg[, arg1[, arg2[, ...]]])  

    例如:

    [html] view plain copy
     
    1. var obj = {name:'JSLite.io'};  
    2. /**  
    3.  * 给document添加click事件监听,并绑定EventClick函数  
    4.  * 通过bind方法设置EventClick的this为obj,并传递参数p1,p2  
    5.  */  
    6. document.addEventListener('click',EventClick.bind(obj,'p1','p2'),false);  
    7. //当点击网页时触发并执行  
    8. function EventClick(a,b){  
    9.  console.log(  
    10.   this.name, //JSLite.io  
    11.   a, //p1  
    12.   b //p2  
    13.  )  
    14. }  
    15. // JSLite.io p1 p2  

    当点击网页时,EventClick被触发执行,输出JSLite.io p1 p2, 说明EventClick中的this被bind改变成了obj对象。如果你将EventClick.bind(obj,'p1','p2') 变成 EventClick.call(obj,'p1','p2') 的话,页面会直接输出 JSLite.io p1 p2。

    eval 方法

    JavaScript 中的 eval 方法可以将字符串转换为 JavaScript 代码,使用 eval 方法时,调用者的执行环境(ExecutionContext)中的 this 就被 eval 方法继承下来了。

  • 相关阅读:
    项目数据分析师CPDA印章
    一点想法
    该减肥啦
    PMP证书到手
    Google App Engine之初体验
    转K线理论初级三
    黄小琥没那么简单
    使用webapp框架再现Hello World
    Google App Engine之介绍篇
    转股票中KDJ线的详细分析
  • 原文地址:https://www.cnblogs.com/qianyouluo/p/7147346.html
Copyright © 2011-2022 走看看