zoukankan      html  css  js  c++  java
  • 【笔记】探索js 的this 对象 (第一部分)

    最近在看 你不知道的javascript 这本书,在第二部分看到了一个比较重要的知识点 那就是 this对象的全面认识,于是做一下笔记

    博主本人在看这本书之前也一直以为 this 是指一切引用类型的本身 但直到最近才明确了 this 对象的见解 关于this 对象误解书上也作了一些解释 下面我来整理一下

    先看下面的例子:

     function foo(num){
        console.log(num);
            this.count++;
     }
    
     foo.count = 0;for (var i = 0; i < 10; i++) {
        if (i > 5) {
        foo(i);
        }
    }
    console.log("函数被调用了多少次?" + foo.count); //0    

    在js 里面 函数即对象 我们将foo 函数定义了a 属性,在循环调用 foo函数中 foo函数的a 属性自增1

    但是为什么最后输出结果为0 ???

    这就是我们对this 对象的第一个误解:this指向函数自身

    实际上this.a 指向了 window对象,不相信??看看下面代码的变化吧

     function foo(num){
        console.log(num);
        this.count++;
     }
    
     foo.count = 0;
     window.count = 0; window.count 还没有被初始化
     for (var i = 0; i < 10; i++) {
        if (i > 5) {
           foo(i);
         }
     }
     console.log("函数被调用了多少次?" + foo.count); //0
    
     console.log("count 属性变成了 window属性了!!但window属性并没有初始化:" + window.count); //NaN

    打开你的编译器试试便知晓~

    函数的执行 this.count 并没有指向 foo函数的本身而是当 foo函数循环执行的时候为 window对象 添加 count属性 并且每次循环为这个属性自增1

    但是因为 window对象中 并没有count 这个属性所以输出的只是 NaN 的结果

    那么我们可以把window.count属性初始化一下

    function foo(num){
        console.log(num);
        this.count++;
    }
    
    foo.count = 0;
    window.count = 0; 
    
    for (var i = 0; i < 10; i++) {
        if (i > 5) {
          foo(i);
        }
    }
    
    console.log("函数被调用了多少次?" + foo.count); //0
    
    
    console.log("count 属性变成了 window属性了!!而且window属性得到了初始化:" + window.count);//调用次数为4

    初始化之后我们就可以看到函数的正确调用次数结果了~

    我们再看看第二个误区:

    我们对this 对象的第二个误解:this对象指向函数的作用域

    看看下面例子:

     window.a = "i'm window";
    
         function fun(){
           var a = "this is fun";
           this.bar();
         }
    
         function bar(){
           console.log(this.a);
         }
    
         fun();// i'm window
         bar.call(window);//上面的行为等价于这个

    解释一下:

    作者在书上的原意是 想把bar 的执行引用绑定在fun 函数中
    但是因为 fun是在 window对象下执行的 所以this对象 指向的是 window对象
    所以 this.bar() 变成了在window对象下执行函数 bar(),或直接等于在 window 对象下直接调用了 bar() 这个函数
    此行为也等价于 bar.call(window)

    当然要让bar 函数在fun 函数里面调用何必要花那么大的功夫

    直接将bar()函数写在 fun中就可以了

    另外声明一点就是:this 对象不指向函数的词法作用域(详情请看 你不知道的javascript 闭包和作用域的一章)

    小结:

    那么this 的对象指的是哪一个呢?

    看了上面的两个例子,我们不难发现this 对象大多数都和 window对象有关系 那是为什么呢?

    再举个例子:

    function fun(){
        this.a = "i'm function fun";
        console.log(this.a);
    }
    
    fun();//i'm function fun
    
    console.log(window.a);//i'm function fun

    表面上看 在fun函数内部定义了 this.a 这一条语句就是给fun 函数添加了一个a 属性

    但是当fun 函数执行的时候 实际上却将a 这个属性赋值给了 window对象
    因此在下一句里面输出 window.a 的结果 和执行fun 函数的结果一样

    归根结底就是因为 fun 函数在 window对象下调用了!

    再看一个例子:

    function foo(){
        console.log(this.a);
    }
    
    function fun(){
        this.a = "i'm function fun";
        console.log(this.a);
    }
    
    var obj = {
        a: "hello i'm a obj",
        foo: foo,
        fun: fun
    }
    
    obj.foo();//hello i'm a obj
    obj.fun();//i'm function fun    

    这里定义了一个对象字面量 obj
    为obj 设置了一个属性 a,值为:"hello i'm a obj"
    然后又定义了两个引用属性:foo 和 fun,他们分别引用 foo函数 和 fun函数

    当通过obj 调用 foo函数的时候 输出结果是obj 的a属性值
    但调用fun 函数的时候输出结果却是函数内部定义的 a属性值

    为什么呢??不是说this 不指向函数本身吗???

    -------分隔线-------

    别混淆了

    上面已经说过 函数里面通过this定义的属性并不是属于函数的作用域
    即这个属性并不是函数本身的(虽说js 的函数也是对象 但不带这么玩)

    实际上 fun 函数里面this.a 这个语句是为函数当前调用环境对象的属性赋值的语句
    通俗的说:
    如果,fun函数在 obj 里面调用 this.a 语句就为 obj 对象里面的a 属性赋值
    如果,fun函数在 window 对象里面调用 this.a 语句就为 window对象里面的 a属性赋值
    如果调用函数的环境下没有匹配的属性 就为其环境创建一个属性并赋值

    所以我们得出总结:

     this 对象指向的是函数执行作用域的对象,即函数在哪里执行,this 对象就指向那里!

     如果上面的代码你觉得啰嗦,直接记住这一点就好

  • 相关阅读:
    luarocks argparse
    Shell中for循环的几个常用写法
    linux
    Docker修改镜像源为阿里云
    ntpdate更新服务器时间失败
    linux文本三剑客之 sed
    [Union]C++中Union学习笔记
    [sublime] 利用sublime搭建C/C++编译器
    [wordpress]WordPress地址(URL)错误,修改解决方案
    [wordpress]更新插件时,免去FTP操作
  • 原文地址:https://www.cnblogs.com/stitchgogo/p/6587207.html
Copyright © 2011-2022 走看看