章节索引 :

this 使用问题

大部分开发者都会合理、巧妙的运用 this 关键字。

初学者容易在 this 指向上犯错,如下面这个 Vue 组件

<div id="app"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
<script>
  // 发送post请求
  const post = (cb) => {
    // 假装发了请求并在200ms后返回了服务端响应的内容
    setTimeout(function() {
      cb([
        {
          id: 1,
          name: '小红',
        },
        {
          id: 2,
          name: '小明',
        }
      ]);
    });
  };

  new Vue({
    el: '#app',
    data: function() {
      return {
        list: [],
      };
    },
    mounted: function() {
      this.getList();
    },
    methods: {
      getList: function() {
        post(function(data) {
          this.list = data;
          console.log(this);
          this.log(); // 报错:this.log is not a function
        });
      },

      log: function() {
        console.log('输出一下 list:', this.list);
      },
    },
  });
</script>

这是初学 Vue 的同学经常碰到的问题,为什么这个 this.log() 会抛出异常,打印了 this.list 似乎也是正常的。

这其实是因为传递给 post 方法的回调函数,拥有自己的 this,有关内容可以查阅 this章节

不光在这个场景下,其他类似的场景也要注意,在写回调函数的时候,如果在回调函数内要用到 this,就要特别注意一下这个 this 的指向。

可以使用 ES6 的箭头函数 或者将需要的 this 赋值给一个变量,再通过作用域链的特性访问即可:

<div id="app"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
<script>
  // 发送post请求
  const post = (cb) => {
    // 假装发了请求并在200ms后返回了服务端响应的内容
    setTimeout(function() {
      cb([
        {
          id: 1,
          name: '小红',
        },
        {
          id: 2,
          name: '小明',
        }
      ]);
    });
  };

  new Vue({
    el: '#app',
    data: function() {
      return {
        list: [],
      };
    },
    mounted: function() {
      this.getList();
    },
    methods: {
      getList: function() {

        // 传递箭头函数
        post((data) => {
          this.list = data;
          console.log(this);
          this.log(); // 报错:this.log is not a function
        });

        // 使用保留 this 的做法
        // var _this = this;
        // post(function(data) {
        //   _this.list = data;
        //   console.log(this);
        //   _this.log(); // 报错:this.log is not a function
        // });
      },

      log: function() {
        console.log('输出一下 list:', this.list);
      },
    },
  });
</script>

这个问题通常初学者都会碰到,之后慢慢就会形成习惯,会非常自然的规避掉这个问题。

前置知识
什么是JavaScript 开发与学习环境准备 调试方案
基础
JavaScript 变量 JavaScript 数据类型 JavaScript if 语句 JavaScript for 语句 JavaScript 算数运算符 JavaScript 比较运算符 JavaScript 逻辑运算符 JavaScript 表达式 JavaScript 函数 JavaScript 对象 JavaScript 字符串 JavaScript 数字 JavaScript 数组 JavaScript switch 语句 JavaScript while 语句 JavaScript break与continue JavaScript with document.cookie
内置对象
JavaScript Function JavaScript Math JavaScript Date JavaScript RegExp JavaScript JSON
JavaScript 与 DOM
什么是DOM DOM和JavaScript的关系 获取和操作 DOM 节点 JavaScript DOM与事件 JavaScript DOM 事件绑定 JavaScript DOM 事件对象 JavaScript DOM 事件流 JavaScript DOM 事件优化 JavaScript DOM 自定义事件
表单处理
使用 JavaScript 校验表单
BOM
BOM window 对象 常用的 BOM 相关对象 BOM 常用属性和方法
AJAX
JavaScript AJAX
进阶知识
JavaScript 异常处理 JavaScript 三元运算符 JavaScript 逗号操作符 JavaScript void JavaScript typeof JavaScript delete JavaScript debugger JavaScript getter &setter JavaScript 原型 JavaScript new操作符和构造函数 JavaScript instanceof JavaScript this JavaScript 严格模式 JavaScript 作用域 JavaScript 闭包 JavaScript 变量提升 JavaScript 对象包装器
常用库
jQuery Lodash moment.js swiper
进阶指南
ECMAScript6 Node.js Babel CSS 预处理器 代码规范 TypeScript Web Components 小程序 Vue / React / Angular JavaScript 关键字
常见疑点与误区
分号问题 对象属性访问问题 this 使用问题 浮点数精度问题 独一无二的 NaN 避免全局污染 控制台观察对象问题 根据环境选择语言特性
扩展
相关资源