基于Backbone实现地理位置纬度追加功能的技术问题
解决Backbone中Geolocation回调里
this指向错误的问题 这是个非常典型的JavaScript上下文绑定问题,我来给你拆解一下问题根源和解决办法:
问题根源
当你在navigator.geolocation.getCurrentPosition的回调函数里使用this时,这个this已经不再指向你的Backbone视图实例了——因为这个回调是由浏览器的Geolocation API调用的,它的执行上下文是全局对象(浏览器环境下就是window),所以this.$el自然无法找到对应的DOM元素,导致后续的append操作失效。
三种可行的解决方法
1. 提前保存视图的this到变量
这是最经典也最兼容旧环境的写法,在回调函数外部把视图实例的this存到一个变量(比如that或self)里,回调内用这个变量访问视图的属性:
render: function() { // 把视图的this保存到that变量中 var that = this; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { // 这里用that指代视图实例,就能正常访问$el了 that.$el.find(".className").append(position.coords.latitude); }); } return this; }
2. 使用bind()绑定回调的上下文
利用Function.prototype.bind()方法,把回调函数的this强制绑定到你的视图实例上,这样回调执行时this就会指向正确的对象:
render: function() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { this.$el.find(".className").append(position.coords.latitude); }.bind(this)); // 绑定this到视图实例 } return this; }
3. 使用ES6箭头函数(推荐)
箭头函数不会创建自己的this上下文,它会继承外层作用域的this,这里外层就是render方法的上下文(也就是你的Backbone视图实例),写法更简洁:
render: function() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition((position) => { // 直接用this就指向视图实例 this.$el.find(".className").append(position.coords.latitude); }); } return this; }
额外的最佳实践
如果你的视图有可能在定位请求完成前就被销毁(比如用户切换路由),最好在视图销毁时标记状态,避免回调执行时操作已不存在的DOM元素,造成无效操作或内存泄漏:
initialize: function() { this.isDestroyed = false; // 监听视图的destroy事件,标记销毁状态 this.listenTo(this, 'destroy', () => { this.isDestroyed = true; }); }, render: function() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition((position) => { // 先检查视图是否已销毁 if (!this.isDestroyed) { this.$el.find(".className").append(position.coords.latitude); } }); } return this; }
内容的提问来源于stack exchange,提问作者sacora
相关产品推荐
相关产品推荐

