Angular 9中构造函数无法访问声明对象的问题咨询
问题根源:JavaScript
this 上下文丢失 嗨,这个问题我太熟了——这完全是JavaScript里this上下文绑定搞的鬼!
为什么会出现 Cannot read property 'xxx' of undefined?
在你用传统的function() {}定义回调函数时,this的指向会随着调用上下文改变:
- 在Promise的
then回调(比如getUserMedia的回调)里,this不再指向你的Angular组件实例,而是指向回调函数自身的执行上下文(严格模式下甚至是undefined)。 - 原有代码里的
this.gotDevices、修改后forEach里的this.mydevices,都是因为this已经不是组件实例,所以才会抛出“无法读取undefined的属性”错误。
为什么局部变量tempDevices能正常使用?
tempDevices是你在构造函数里声明的局部变量,回调函数处于构造函数的闭包范围内,所以可以直接访问这个变量,不受this指向的影响。
解决方法:保持this指向组件实例
有两种常用的方式可以解决这个问题:
1. 使用箭头函数(推荐,Angular开发中最常用)
箭头函数不会绑定自己的this,它会继承外层上下文的this(也就是你的组件实例)。把所有回调里的function() {}换成箭头函数即可:
public mydevices = []; constructor(...){ navigator.mediaDevices.getUserMedia(constraints).then((stream) => { navigator.mediaDevices.enumerateDevices().then((devices) => { devices.forEach((device) => { this.mydevices.push(device); }); }); }).catch((err) => { console.error('获取设备失败:', err); }); }
2. 提前保存this的引用
在构造函数里先把组件实例的this存到一个变量(比如self或that),然后在回调里用这个变量代替this:
public mydevices = []; constructor(...){ const self = this; // 保存组件实例的引用 navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { navigator.mediaDevices.enumerateDevices().then(function (devices) { devices.forEach(function (device) { self.mydevices.push(device); // 用self代替this }); }); }).catch(function (err) { console.error('获取设备失败:', err); }); }
总结
在Angular组件中处理异步操作(比如Promise、事件回调)时,一定要注意this的指向问题。箭头函数是最简洁的解决方案,能帮你避免大部分上下文丢失的坑。
内容的提问来源于stack exchange,提问作者Joe Doe
相关产品推荐
相关产品推荐

