如何在对象集合中访问实例的this?构造函数this绑定异常求助
问题分析与解决方案
这个问题的核心是你不小心把保存this的变量变成了全局变量,导致所有实例的方法都共享了同一个引用,最终全部指向最后创建的对象。让我给你详细拆解并给出几种解决办法:
为什么会输出十个9?
你代码里的j = this;没有使用var/let/const声明,这会让j成为全局变量。每次循环创建新的t实例时,都会把当前实例的this赋值给全局的j——循环执行到最后,j自然就指向了i=9时创建的那个实例。而每个实例的k方法都是返回j.u,所以所有调用都会返回最后那个实例的u值,也就是9。
解决办法
1. 用局部变量保存this(最直接的修改)
给j加上声明关键字,把它变成构造函数内部的局部变量,这样每个实例创建时都会拥有自己独立的j引用:
var t = function(x){ var j = this; // 添加var,将j变为构造函数内的局部变量 this.u = x; this.k = function (){ return j.u; } } var g = []; for(var i = 0; i < 10; i++) g.push(new t(i)); for(var i = 0; i < 10; i++) console.log(g[i].k());
这样每个实例的k方法都会绑定自己构造时的j(也就是当前实例),执行后会依次输出0到9。
2. 使用箭头函数绑定this
箭头函数不会创建自己的this,它的this会继承自外层作用域(这里就是构造函数执行时的this,也就是当前实例),所以不需要额外的变量来保存this:
var t = function(x){ this.u = x; this.k = () => { // 替换为箭头函数 return this.u; } } var g = []; for(var i = 0; i < 10; i++) g.push(new t(i)); for(var i = 0; i < 10; i++) console.log(g[i].k());
3. 将方法挂载到原型上(最推荐的优化方案)
如果多个实例的方法逻辑是一样的,把方法放到构造函数的原型上更节省内存——所有实例会共享同一个方法,而且调用方法时this会自动指向当前实例:
var t = function(x){ this.u = x; } // 把k方法挂载到t的原型上 t.prototype.k = function() { return this.u; } var g = []; for(var i = 0; i < 10; i++) g.push(new t(i)); for(var i = 0; i < 10; i++) console.log(g[i].k());
这种方式不仅解决了问题,还避免了每个实例都创建一个新的k函数,是更符合JavaScript原型链设计的写法。
内容的提问来源于stack exchange,提问作者bula
相关产品推荐
相关产品推荐

