构造函数prototype中使用this获取值返回null的技术问题
问题分析与解决方案
你代码里的问题核心很明确:给testThing.prototype.ba赋值时,这里的this根本不是testThing的实例,而是当前全局上下文(浏览器环境是window,Node.js环境是global)。全局上下文里不存在a和b属性,所以你传入的参数是undefined,构造函数将其赋值给实例属性后,最终显示为null(不同环境可能显示undefined,本质逻辑一致)。
而且prototype是构造函数的原型对象,你直接在上面挂载一个提前创建好的testThing实例,这个实例是在构造函数还未生成任何业务实例时就初始化完成的,根本拿不到后续业务实例的a、b值,同时所有业务实例会共享这同一个ba对象,完全不符合你的需求。
可行解决方案
方案1:原型上定义getter方法(推荐)
把ba改成getter,每次访问实例的ba属性时,都会基于当前实例的a和b生成交换后的新对象:
function testThing(a, b){ this.a = a; this.b = b; } Object.defineProperty(testThing.prototype, 'ba', { get: function() { return new testThing(this.b, this.a); } }); // 测试 var test = new testThing(1, 2); console.log(test.ba); // 输出 testThing {a: 2, b: 1}
如果用ES6类语法会更简洁:
class testThing { constructor(a, b) { this.a = a; this.b = b; } get ba() { return new testThing(this.b, this.a); } } const test = new testThing(1, 2); console.log(test.ba);
方案2:构造函数内初始化ba
如果实例创建后a和b不会修改,可以直接在构造函数里给每个实例生成独立的ba:
function testThing(a, b){ this.a = a; this.b = b; this.ba = new testThing(b, a); } var test = new testThing(1, 2); console.log(test.ba); // 输出 testThing {a: 2, b: 1}
这种方式下每个实例的ba是独立的,但后续修改实例的a或b时,ba不会自动更新,这是和getter方案的核心区别。
关于“不通过函数实现”的疑问
要获取实例的a和b值,必须依赖实例的上下文,而只有函数(比如getter、构造函数内的逻辑)才能拿到当前实例的this。直接在原型上挂载静态对象的方式完全做不到,因为静态对象初始化时没有任何实例上下文。所以必须通过函数逻辑来实现你的需求。
内容的提问来源于stack exchange,提问作者ThePlaneGuy45
相关产品推荐
相关产品推荐

