• 你不知道的JS系列 ( 18) - this 的错误认识


    第一种误解:this 理解成指向函数本省,函数看作一个对象,this 并不像我们所想的那样指向函数本身。
    function foo(num){
      console.log('foo: ' + num);
      this.count++;
    }
    foo.count = 0;
    var i;
    for(i=0; i<10; i++){
      if (i > 5) {
        foo(i);
      }
    }
    console.log(foo.count); // 0

    foo 确实被调用了 4 次,但是 foo.count 仍然是 0.显然从字面意思来理解 this 是错误的。如果我增加的 count 属性和预期不一样,那么增加的是哪个 count?实际上,如果深入探索的话,就会发现这段代码在无意中创建了一个全局变量,它的值是 NaN。那我们如何解决这个问题?

    function foo(num){
      console.log('foo: ' + num);
    
      // 记录 foo 被调用的次数
      data.count++;
    }
    var data = {
      count: 0
    }
    var i;
    for(i=0; i<10; i++){
      if (i > 5) {
        foo(i);
      }
    }
    console.log(data.count); // 4

    从某种角度来说这个方法确实解决了问题,但可惜它忽略了真正的问题——无法理解 this 的含义和工作原理——而是返回舒适区,使用了一种更熟悉的技术,词法作用域



    function foo(num){
      console.log('foo: ' + num);
    
      // 记录 foo 被调用的次数
      foo.count++;
    }
    foo.count = 0;
    var i;
    for(i=0; i<10; i++){
      if (i > 5) {
        foo(i);
      }
    }
    console.log(foo.count); // 4

    然而,这种方法同样回避了 this 的问题,并且依赖于变量 foo 的词法作用域

    function foo(num){
      console.log('foo: ' + num);
      this.count++;
    }
    foo.count = 0;
    var i;
    for(i=0; i<10; i++){
      if (i > 5) {
        foo.call(foo, i);
      }
    }
    console.log(foo.count); // 4

    这次我们接受了 this,没有回避它。



    第二种误解:this 指向函数的作用域。在某种情况下它是正确的,但明确的是,this 在任何情况下都不指向函数的词法作用域。
    function foo() {
      var a = 2;
      this.bar();
    }
    function bar(){
      console.log(this.a);
    }
    foo(); // undefined

    这段代码非常完美的展示了 this 多么容易误导人。首先 this.bar() 来引用 bar() 函数。这是绝对不可能成功的。调用 bar() 最自然的方法是省略前端的 this。此外,开发者试图使用 this 联通 foo() 和 bar() 的词法作用域。每当你想要把 this 和词法作用域的查找混合使用时,一定要提醒自己,这是无法实现的。

    学习 this 的第一步是明白 this 既不指向函数自身也不指向函数的词法作用域。
    this 是在运行时进行绑定的,并不是在编写时绑定。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。







  • 相关阅读:
    媒体查询漫谈——@media Queries
    JavaScript工具函数集
    什么是BFC、IFC、GFC和FFC
    HTTP与HTTPS的区别
    reflow 和 repaint
    客户端检测
    ajax
    批量删除
    数据访问
    登录主页面代码
  • 原文地址:https://www.cnblogs.com/wzndkj/p/12400209.html
Copyright © 2020-2023  润新知