success: function(res) {} 和 success: res => {}

本文探讨了微信小程序中使用this关键字时遇到的问题,尤其是在获取userinfo的回调函数中。通过对比function和箭头函数的不同,解释了this指向的差异,并提供了有效的解决方案。

微信小程序在获取userinfo的过程中采用this碰到一些问题

我login的success回调函数为

success: function(res) {
              if(res.statusCode == 200) {
                console.log(res.data)
                this.globalData.sessionId = res.data.sessionId
              }

此处的this会报错如下

Cannot read property 'globalData' of null;

然后我查看了app.js另外一处的success回调函数

success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }

而此处的this有效,我怀疑是success: function(res) {} 和 success: res => {}的区别,于是我修改了第一处的代码为

success: res => {
              if(res.statusCode == 200) {
                console.log(res.data)
                this.globalData.sessionId = res.data.sessionId
              }

然后代码跑通了

如果不想修改回调函数,可以在app.js中增加var that = this,然后此处修改this为that即可。

目前没有没有详细了解相关html和js的知识,目前只发现这两种用法在this使用情况上的区别,另外有没有其他的区别尚不得而知,希望有了解相关知识的人评论指正。

 

————————————————————————分割线————————————————————————

 

箭头函数中this指向window(Page)

而采用如下方式时:

xxx: function() {}

执行xxx就执行了一个匿名函数,其中的this指向包含xxx这个键的对象(js中什么东西都能是对象)。

评论中有人问是不是建议用success: res => {},并不是这个意思。用哪个方式取决于项目,要考虑之前说的this指向问题:你想要this指向哪个对象?如果你想用的就在包含xxx的这个map中,就没必要用箭头函数,而且老浏览器不支持ES6语法。如果你需要的在window(page)对象下,就可以用箭头函数。

或者在外部用另外一个变量储存指向window(page)的this

或者在匿名函数中采用闭包,也可以解决这个问题,不过函数中再写个函数来实现闭包的情形很少

<think&gt;我们正在讨论的是JavaScript中两种函数定义方式的区别:普通函数箭头函数。 在success回调中,有两种写法: 1. success: function(res) { ... } // 普通函数 2. success: (res) =&gt; { ... } // 箭头函数 主要区别在于函数内部的`this`指向。 在普通函数中,`this`的值是在函数被调用时确定的,它指向调用该函数的对象。但在回调函数中,如果没有特殊绑定,普通函数中的`this`可能不会指向我们期望的Vue实例或Page对象。 在箭头函数中,`this`是词法作用域,它继承自外围作用域(定义时的作用域)的`this`值。因此,在箭头函数内部,`this`与定义函数处的`this`相同。 以微信小程序为例,当我们使用普通函数作为回调时,函数内部的`this`可能不是Page对象,导致无法通过`this.setData`更新数据。而箭头函数则可以保留定义时的`this`(即Page对象),从而正确调用`this.setData`。 引用中的例子: [^1] 中展示了普通函数写法的问题: onChange() { this.setData({ window_heigt: 100 }) // 这里的this是Page对象 wx.getSystemInfo({ success: function(res) { // 这里的this不是Page对象,而是wx.getSystemInfo调用时的上下文,可能是undefined或全局对象(严格模式下为undefined) this.setData({ window_heigt: res.windowHeight }) // 会报错,因为this.setData不存在 }, }) } 而如果使用箭头函数: success: (res) =&gt; { this.setData({ window_heigt: res.windowHeight }) // 箭头函数内的this继承自onChange函数的this,即Page对象 } 因此,在需要访问外层this的情况下,使用箭头函数可以避免this指向错误。 另外,引用[^5]也提到,在promise的处理结果中使用箭头函数可以直接使用this。 总结: - 普通函数:有自己的this,由调用方式决定。在回调中容易丢失外层this。 - 箭头函数:没有自己的this,继承外层作用域的this。在需要保持this一致性的回调中非常有用。 注意:箭头函数不能作为构造函数,也不能使用arguments对象(可以使用rest参数代替)。 在uni-app或微信小程序开发中,我们经常需要在回调中访问页面或组件的this,因此推荐在回调中使用箭头函数来避免this指向问题。 相关问题: 1. 如何手动绑定普通函数的this? 2. 在Vue 3的setup语法糖中,如何使用箭头函数普通函数? 3. 箭头函数普通函数在性能上有区别吗?</think&gt;在 JavaScript 中,`success(res){}` `success: (res)=&gt;{}` 的主要区别在于 **`this` 的指向****函数定义方式**,这是理解它们差异的核心: ### 核心区别对比表 | 特性 | `success(res){}` | `success: (res)=&gt;{}` | |------|------------------|----------------------| | **函数类型** | 普通函数声明 | 箭头函数表达式 | | **`this` 指向** | 动态绑定(由调用者决定) | 静态绑定(继承定义时的上下文) | | **适合场景** | 需要动态 `this` 的操作 | 需要固定外层 `this` 的回调 | | **arguments 对象** | 有 | 无 | | **构造函数** | 可做构造函数 | 不可做构造函数 | | **原型属性** | 有 prototype | 无 prototype | ### 详细区别分析 1. **`this` 指向不同(最关键的差异)** - **普通函数 `success(res){}`** `this` **动态绑定**,由调用者决定: ```javascript wx.getSystemInfo({ success: function(res) { console.log(this); // 指向 wx 或 undefined(严格模式) // 报错!无法访问 Page 的 this this.setData({ height: res.windowHeight }); } }) ``` - **箭头函数 `success: (res)=&gt;{}`** `this` **静态绑定**,继承外层作用域: ```javascript Page({ data: { height: 0 }, getHeight() { wx.getSystemInfo({ success: (res) =&gt; { console.log(this); // 指向 Page 实例 ✅ this.setData({ height: res.windowHeight }); // 正常工作 } }) } }) ``` 2. **函数定义方式不同** - `success(res){}` 是**函数声明**,可作为独立函数存在 - `success: (res)=&gt;{}` 是**函数表达式**,通常作为对象属性或回调参数 3. **其他技术差异** - **arguments 对象** 普通函数可使用 `arguments`,箭头函数没有 ```javascript function normal(a,b) { console.log(arguments); // [1,2] } const arrow = (a,b) =&gt; { console.log(arguments); // 报错! } ``` - **构造函数能力** 普通函数可做构造函数,箭头函数不可: ```javascript new normal(); // 正常 new arrow(); // TypeError: arrow is not a constructor ``` ### 微信小程序中的实践建议 在微信小程序/uni-app 开发中,**优先使用箭头函数**: ```javascript // ✅ 推荐 - 箭头函数保留组件 this wx.request({ url: '/api/data', success: (res) =&gt; { this.setData({ list: res.data }) // 正确访问 Page/Component 实例 } }) // ⚠️ 避免 - 普通函数丢失 this wx.request({ url: '/api/data', success: function(res) { this.setData(...) // this 指向错误! } }) ``` ### 何时使用普通函数? 当需要 **动态 `this`** 时使用普通函数: ```javascript const buttonHandler = { message: 'Clicked!', handleClick: function() { console.log(this.message); // 'Clicked!' ✅ } } buttonHandler.handleClick(); // 换成箭头函数会失效: const buttonHandler = { message: 'Clicked!', handleClick: () =&gt; { console.log(this.message); // undefined ❌ } } ``` ### 相关问题延伸 1. 在 Vue 3 的 `setup()` 中,箭头函数普通函数的 `this` 表现有何不同? 2. 如何通过 `.bind(this)` 解决普通函数的 `this` 丢失问题? 3. 为什么在类方法中使用箭头函数会导致内存泄漏风险? 4. 在异步回调中,箭头函数如何影响 `try/catch` 的错误捕获机制? &gt; 箭头函数没有自己的 `this` 绑定,它从封闭的词法环境中继承 `this` 值[^1][^5],这种特性在回调场景中特别有价值[^4]。而普通函数的 `this` 在运行时确定,容易导致上下文丢失[^1][^4]。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值