this在vue和小程序中的使用详解


Posted in Javascript onJanuary 28, 2019

匿名函数下的this

方便本地demo,没有使用webpack

引入两个文件,vue和axios

axios返回一个promise对象,我们通过axios进行ajax请求

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
 <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<body>
  <div id="app">
    {{ message }}
  </div>
</body>

看下js部分

var message = '我是全局message!';
var app = new Vue({
 el: '#app',
 data() {
  return {
   message: '我是vue下的message!'
  }
 },
 created() {
  this.getData()
 },
 methods: {
  getData() {
   axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
    .then(function () {
     console.log(this.message);//=>我是全局message!
    })
  }
 }
})

不必关心axios请求的接口返回的数据

那么在axios下,输出的是=>我是全局message!,为什么呢?我们是想输出=>”我是vue下的message!”

在这里有那么一些人就蒙了,为什么axios下会这样呢?

axios有话说:

this在vue和小程序中的使用详解

出现这种情况,不是axios的锅,

不信你往下看

//其他代码省略
 getData() {
  setTimeout(function () {
   console.log(this.message);//=>我是全局message!
  }, 1000);
 }
}

我们将getData方法下的axios请求换掉,用一个定时器替代,其他部分保持不变

输出依然是=>我是全局message!

为什么?

因为

匿名函数下this指向window

至于原因, 这里解释的很清楚https://www.zhihu.com/question/21958425

你只需要记住一点,默认情况下,匿名函数this指向window

如何处理匿名函数下this指向的问题呢?

通过bind来处理

结合之前所学,我们可以同bind来进行处理

//部分代码省略
created() {
  this.getData()
},
  methods: {
    getData() {
      setTimeout(function () {
        console.log(this.message);//=>我是vue下的message!
      }.bind(this), 1000);
    }
  }

通过bind可以改变this的指向,这是一中解决方式

还有一种比较常用

this赋值暂存

created() {
 this.getData()
},
methods: {
 getData() {
  const that = this
  setTimeout(function () {
   console.log(that.message);//=>我是vue下的message!
  }, 1000);
 }
}

在匿名函数之前,我们先将this赋值给that,在匿名函数中使用that来替代原来的this,同样可以实现我们所希望的效果

如果你的项目支持ES6标准,那么

箭头函数是你最佳选择

getData() {
 axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
  .then(() => {
   console.log(this.message);
  })
}

我们在之前的文章中总结过一个结论

this的指向是在函数执行的时候定义的,而不是在函数创建时定义的,this指向的是最后调用它的对象

我们接下来本篇文章的另一个知识点

箭头函数中的this

看一个栗子

var heroName = '黄蓉';
var heroObj = {
 heroName: '郭靖',
 callName: function () {
  console.log(this.heroName)//=>郭靖
 }
}
heroObj.callName();

this指向最后调用它的对象,所以输出=>郭靖

再看下箭头函数的栗子

var heroName = '黄蓉';
var heroObj = {
 heroName: '郭靖',
 callName: () => {
  console.log(this.heroName)//=>黄蓉
 }
}
heroObj.callName();

对这个输出结果感到意外吗?

不管懵没懵,我们再看一个栗子

var heroName = '黄蓉';
function getHeroName() {
 this.heroName = '郭靖'
 const foo = () => {
  console.log(this.heroName)//=>郭靖
 }
 foo();
}
getHeroName();

放在一起做一下比较:

普通函数:this的指向是在函数 执行 的时候绑定的,而不是在函数 创建 时绑定的

箭头函数:this的指向是在函数 创建 的时候绑定的,而不是在函数 执行 时绑定的。

不管在什么情况下,箭头函数的this跟外层function的this一致,外层function的this指向谁,箭头函数的this就指向谁,如果外层不是function则指向window。

ES6中定义的时候绑定的this是继承的父执行上下文里面的this

小程序中的this

如果项目中的小程序也支持ES6标准,无疑,使用箭头函数是一个不错的选择

//省略。。。
 getLocation() {
  wx.chooseLocation({
   success: res => {
    if (res.address && res.name) {
     this.setData({
      shopAddress: `${res.address}(${res.name})`
     })
    } else if (res.address) {
     this.setData({
      shopAddress: `${res.address}`
     })
    }
   }
  })
 }

很多场景就不需要缓存中转this

var that = this//使用箭头函数替代此方案

合理的使用this会使我们事半功倍

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery选择器 $实现原理
Dec 02 Javascript
jQuery 淡入淡出 png图在ie8下有黑色边框的解决方法
Mar 05 Javascript
js网页版计算器的简单实现
Jul 02 Javascript
Jquery性能优化详解
May 15 Javascript
全面理解闭包机制
Jul 11 Javascript
jQuery学习之DOM节点的插入方法总结
Jan 22 Javascript
Vue组件库发布到npm详解
Feb 17 Javascript
Vue 中使用vue2-highcharts实现top功能的示例
Mar 05 Javascript
Vue CLI3搭建的项目中路径相关问题的解决
Sep 17 Javascript
JavaScript 2018 中即将迎来的新功能
Sep 21 Javascript
利用node 判断打开的是文件 还是 文件夹的实例
Jun 10 Javascript
详谈vue中router-link和传统a链接的区别
Jul 22 Javascript
Vue加载json文件的方法简单示例
Jan 28 #Javascript
Vue项目安装插件并保存
Jan 28 #Javascript
vue 左滑删除功能的示例代码
Jan 28 #Javascript
详解Next.js页面渲染的优化方案
Jan 27 #Javascript
在Vue项目中取消ESLint代码检测的步骤讲解
Jan 27 #Javascript
在Vue项目中引入JQuery-ui插件的讲解
Jan 27 #jQuery
在vue项目中使用Jquery-contextmenu插件的步骤讲解
Jan 27 #jQuery
You might like
php5 pdo新改动加载注意事项
2008/09/11 PHP
一个比较简单的PHP 分页分组类
2009/12/10 PHP
单台服务器的PHP进程之间实现共享内存的方法
2014/06/13 PHP
使用YUI+Ant 实现JS CSS压缩
2014/09/02 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
对JavaScript的eval()中使用函数的进一步讨论
2008/07/26 Javascript
javascript:void(0)的真正含义实例分析
2008/08/20 Javascript
Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)
2010/06/11 Javascript
js+html+css实现鼠标移动div实例
2013/01/30 Javascript
JS下拉框内容左右移动效果的具体实现
2013/07/10 Javascript
JS字符串截取函数实例
2013/12/27 Javascript
JSONP跨域GET请求解决Ajax跨域访问问题
2014/12/31 Javascript
jQuery实现tab标签自动切换的方法
2015/02/28 Javascript
jquery解析XML及获取XML节点名称的实现代码
2016/05/18 Javascript
一览画面点击复选框后获取多个id值的方法
2016/05/30 Javascript
JS 实现随机验证码功能
2017/02/15 Javascript
关于vue-router的那些事儿
2018/05/23 Javascript
JS中封装axios来管控api的2种方式
2019/09/11 Javascript
JS async 函数的含义和用法实例总结
2020/04/08 Javascript
详解vue-cli项目在IE浏览器打开报错解决方法
2020/12/10 Vue.js
[01:06:32]DOTA2上海特级锦标赛D组资格赛#1 EG VS VP第一局
2016/02/28 DOTA
举例简单讲解Python中的数据存储模块shelve的用法
2016/03/03 Python
Python常见排序操作示例【字典、列表、指定元素等】
2018/08/15 Python
Python中反射和描述器总结
2018/09/23 Python
python pandas时序处理相关功能详解
2019/07/03 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
2019/11/19 Python
Python使用GitPython操作Git版本库的方法
2020/02/29 Python
Python3交互式shell ipython3安装及使用详解
2020/07/11 Python
Jupyter notebook命令和编辑模式常用快捷键汇总
2020/11/17 Python
巴西独家产品和现场演示购物网站:Shoptime
2019/07/11 全球购物
PyQt QMainWindow的使用示例
2021/03/24 Python
公证书标准格式
2014/04/10 职场文书
春风化雨观后感
2015/06/11 职场文书
联村联户简报
2015/07/21 职场文书
2015年度优秀员工获奖感言
2015/07/31 职场文书
MySQL数据库如何使用Shell进行连接
2022/04/12 MySQL