• js this详解


    This的定义:

    它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁实际上this的最终指向的是那个调用它的对象

    这说明this关键字只与函数的执行环境有关,而与声明环境没有关系。下面通过例子来讲解。

    例子1

    function a(){
    
        var user = "哈哈哈";
    
        console.log(this.user); //undefined
    
    console.log(this); //Window
    
    }
    
    a();

    既然this的最终指向的是那个调用它的对象a()的执行就相当于window.a(),所以this指向window.

    例子2

    var o = {
    
        user:"哈哈哈",
    
        fn:function(){
    
            console.log(this.user);  //哈哈哈    
    
    }
    
    }
    
    o.fn();

    这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o,这里再次强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁

    例子3

    var o = {
    
        a:’哈哈哈’,
    
        b:{
    
            a:’呵呵呵’,
    
            fn:function(){
    
                console.log(this.a); //呵呵呵       
    
    }
    
        }
    
    }
    
    o.b.fn();

    如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象(不管有没有this要的东西,没有就输出undefined)

    例子4

    var o = {
    
        a:’哈哈哈’,
    
        b:{
    
            a:’呵呵呵’,
    
            fn:function(){
    
                console.log(this.a); //undefined
    
                console.log(this); //window        
    
    }
    
        }
    
    }
    
    var j = o.b.fn;
    
    j();

    this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和例子3是不一样的,例子3是直接执行了fn

    例子5

    var id = 'windowId';
    
    document.getElementById('myDiv').onclick = function() {
    
       console.log(this.id); //输出myDiv
    
       function fn(){
    
          console.log(this.id); //输出windowId
    
        };
    
        fn(); //普通函数调用
    
    };

    这里补充下:不管函数处于什么样的执行环境,只要是当普通函数调用,this就指向windows.

    例子6

         var a=function(){
    
          console.log(this)//window
    
         }
    
         var o={
    
          name:'小白菜',
    
          b:function(fn){
    
             console.log(this);//{name:'小白菜',b:f(fn)}
    
             fn()
    
             a();
    
          }
    
         }
    
         o.b(function(){
    
          console.log(this)//window
    
         })

    这个例子是我之前的面试题目,也是因为它而让我想写这篇文章。我想大家看到这里大概明白b函数里面的this,就是指向它的执行环境o。迷糊的估计是fn()a()的输出。其实简单理解就像例5我所说的,不管处于什么样的环境下,只要当普通函数调用就指向window。硬要说个理由,就像开头所说的:this的最终指向的是那个调用它的对象。本例子fn()=window.fn()

    补充1

    1、
    
    function fn()  
    
    {  
    
        this.name = '哈哈哈';  
    
        return {};  
    
    }
    
    var a = new fn();  
    
    console.log(a.name ); //undefined
    
    2、
    
    function fn()  
    
    {  
    
         this.name = '哈哈哈';  
    
        return function(){};
    
    }
    
    var a = new fn();  
    
    console.log(a.name ); //undefined
    
    3、
    
    function fn()  
    
    {  
    
        this.name = '哈哈哈';  
    
        return 1;
    
    }
    
    var a = new fn();  
    
    console.log(a.name ); //哈哈哈
    
    4、
    
    function fn()  
    
    {  
    
         this.name = '哈哈哈';  
    
        return undefined;
    
    }
    
    var a = new fn();  
    
    console.log(a.name ); //哈哈哈
    
    5、
    
    function fn()  
    
    {  
    
        this.name = '哈哈哈';  
    
        return null;
    
    }var a = new fn;  
    
    console.log(a.name ); //哈哈哈
    
     

    如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊

    补充2

    this一般指向的是当前被调用者,但也可以通过其它方式来改变它的指向,为什么要改变向上下文呢?主要是为了实现一种情况,当一个对象没有某个方法的时候,而且另外一个对象却有这个方法,这个时候就可以通过改变上下文来使用自己没有的方法了。

    如下面的例子:

    var obj1 = {
        name: '111'
    }
    var obj2 = {
        name: '222'
    }
    window.name = 'window';
    var getName= function(a,b) {
        alert(this.name);
        alert(a);
        alert(b);
    }
    
    getName();//window,undefined,undefined;
    
    getName.call(obj1,'a','b');//111,a,b
    
    getName.apply(obj2,['a','b']);//222,a,b
    
     

    obj1没有showName()方法,obj2有,这个时候可以这个样子使用,var temp=obj1.prototype.call(obj2);这样就可以用obj2的方法了

    那什么时候用call什么时候用apply

    当参数个数是固定不变的时候可以用call,当参数个数不确定可以用apply,把要传递的参数push到一个数组里面然后传递给函数,不清楚callapply可以猛戳百度。

     如想了解this的作用可阅读《this的作用》这篇文章。

  • 相关阅读:
    Emmet 语法
    GitHub常用命令
    ProgressBar.js – 漂亮的响应式 SVG 进度条
    99个漂亮的注册和登录页设计(附PSD)
    android Acitivity之间的几种传值方式(^_^)
    Android 动态生成 EditTest
    Android 小笔记
    winfrom获取用户控件里的控件对象
    MVC+Easeyui dialog的小问题
    bootStrap
  • 原文地址:https://www.cnblogs.com/wangdan0915/p/7737291.html
Copyright © 2020-2023  润新知