• 关于this的使用


    一、关于this的使用   

    javaScript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境

    二、具体到实际应用中,this指向大致可以分为以下4种:

    1、作为对象的方法调用
    2、作为普通函数调用
    3、构造器调用
    4、Function.prototype.call和Function.prototype.apply调用


    三、闭包中使用this对象会导致的一些问题

    this对象是在运行时基于函数的执行环境绑定的,
    1、在全局环境中,this 等于 window
    2、当函数被作为某个对象的方法调用时,this 等于 (那个对象)
    3、匿名函数的执行环境具有全局性,因此其this对象通常指向window

      1 //1作为对象的方法调用
      2     //当函数作为对象的方法被调用时,this指向该对象
      3     var obj = {
      4         a:1,
      5         getA:function(){
      6             console.log(this); // 输出 Object
      7             console.log(this.a); //输出 1
      8         }
      9     };
     10     obj.getA();
     11 
     12 
     13     //2.作为普通函数调用
     14     //当函数不作为对象的属性被调用时,此时的this总是指向全局对象。在javaScript中这个全局对象是window对象
     15     window.name = "globalName";
     16     var getName1 = function (){
     17         return this.name;
     18     };
     19     console.log(getName1()); // 输出 globalName
     20 
     21     //有时候我们会遇到一些困扰,比如在div节点的事件函数内部,
     22     //有一个局部的callback方法,callback被作为普通函数的调用时,
     23     //callback内部的this指向了window,但我们往往是想让它指向该div节点
     24 
     25 
     26     window.id = "windowId";
     27     document.getElementById("div1").onclick = function (){
     28         console.log(this.id);//div1
     29         var callback = function(){
     30             console.log(this.id);//输出windowId,指向全局window对象----???
     31         };
     32         callback();// 自执行函数中的this指向window
     33     };
     34 
     35 
     36     //一种简单的解决方案,用一个变量保存div节点的引用
     37     window.id = 'windowId';
     38     document.getElementById("div1").onclick = function(){
     39         var that = this; //保存div的引用
     40         var callback = function(){
     41             console.log(that.id); // 输出div1
     42         };
     43         callback();
     44     };
     45 
     46     /*ES5下的严格模式下,这种情况下的this已经被规定为不会指向全局对象,而是undefined*/
     47     function func(){
     48         "use strict";
     49         console.log(this);//注意为undefined
     50     }
     51     func();
     52 
     53 
     54 
     55     //3.构造器的调用
     56     //当用new操作符调用函数时,该函数总会返回一个对象,通常情况下,构造器里的this指向返回的那个对象
     57 
     58     var MyClass = function (){
     59         this.name = "six";
     60     };
     61 
     62     var obj = new MyClass();//大部分js函数都可以当做构造器使用
     63 
     64     console.log(obj.name);//six
     65 
     66     /*
     67     * 注意:使用new调用构造器时,还要注意一个问题,如果构造器显示的返回了一个object类型的对象,
     68     * 此次的运算结果最终会返回这个对象,而不是我们之前期待的this
     69     *
     70     * */
     71     var MyClass  = function(){
     72         this.name = "GoUp";
     73         return {//构造器显示的返回了一个object类型的对象
     74             name:"lalala"
     75         };
     76     };
     77 
     78     var obj = new MyClass();
     79     console.log(obj.name);//lalala
     80 
     81     /*
     82      * 注意:如果构造器不显示任何类型数据,或者返回一个非对象类型的数据,就不会造成上述问题
     83      *
     84      * */
     85     var MyClass  = function(){
     86         this.name = "GoUp";
     87         return 'kakaka';//返回string类型
     88     };
     89 
     90     var obj = new MyClass();
     91     console.log(obj.name);//GoUp
     92 
     93 
     94 
     95 
     96     //4.用call()和apply()方法可以修改this的指向
     97     var obj1 = {
     98         name:'seven',
     99         getName:function(){
    100             return this.name;
    101         }
    102     };
    103     var obj2 = { name:'anne'};
    104     console.log(obj1.getName()); // 'seven'
    105     console.log(obj1.getName.call(obj2));// 'anne'
    106 
    107 
    108 
    109     /*
    110     注意:经常遇到问题:丢失this
    111     * */
    112 
    113     var obj = {
    114         myName:'seven',
    115         getName:function(){
    116             return this.myName;
    117         }
    118     };
    119     console.log(obj.getName());//seven
    120     var getName2 = obj.getName;
    121     console.log(getName2);//function (){return this.myName;}
    122     console.log(getName2());//undefined
    123     /* 当调用obj.getName时,getName方法是作为obj对象的属性被调用的,此时的this指向obj对象,所以obj.getName()输出'seven'
    124      当用另外一个变量getName2来引用obj.getName,并且调用getName2时,此时是普通函数调用方式,this指向全局window,所以执行结果是undefined
    125      */
    126 
    127 
    128 
    129     //闭包中出现的问题
    130     var name = "The Window"; //全局变量
    131     var object = {
    132         name : "My Object",
    133         getNameFunc : function(){
    134             return function(){ // 返回匿名函数
    135                 return this.name; //this指向全局对象window
    136             };
    137         }
    138     };
    139     console.log(object.getNameFunc()());//The Window
    140 
    141 
    142 
    143 
    144 
    145     var name = "The Window";
    146     var object = {
    147         name : "My Object",
    148         getNameFunc : function(){
    149             var that = this;//把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了
    150             return function(){
    151                 return that.name;
    152             };
    153         }
    154     };
    155     console.log(object.getNameFunc()());//My Object!!!
     
  • 相关阅读:
    C++ template —— 类型区分(十一)
    C++ template —— 表达式模板(十)
    C++ template —— template metaprogram(九)
    C++ template —— 模板与继承(八)
    [转]2015有得有悟,2016笨鸟起飞
    C++ template —— trait与policy类(七)
    protobuf与json相互转换的方法
    如何通过卡面标识区分SD卡的速度等级
    MyEclipse设置字体和背景的方法
    JAVA中日期转换和日期计算的方法
  • 原文地址:https://www.cnblogs.com/Hmin2199/p/6266858.html
Copyright © 2020-2023  润新知