能否在JavaScript对象中实现深层自引用?
深层对象中实现自引用的问题解析与解决方案
嘿,这个问题核心在于箭头函数的this绑定规则,咱们先拆解为什么你给出的深层对象代码无法得到预期结果,再给出几种可行的解决办法~
为什么原代码不生效?
你写的这段代码:
var foo = { a: 'bar', b: 'baz', c: { ca: 'hello', cb: () => { return this.a + this.b; } } }; console.log(foo.c.cb());
实际运行后并不会输出barbaz,反而会得到undefinedundefined(除非全局作用域刚好有a和b变量)。原因是:
箭头函数没有自己的this,它的this是定义时继承自外层的上下文——这里cb箭头函数定义在全局作用域下,所以this指向全局对象(浏览器里是window,Node.js里是global),自然拿不到foo的a和b属性。
可行的解决方案
方案1:直接引用外层对象变量
把箭头函数改成普通函数,直接通过foo变量访问外层属性:
var foo = { a: 'bar', b: 'baz', c: { ca: 'hello', cb: function() { return foo.a + foo.b; } } }; console.log(foo.c.cb()); // 输出 barbaz
这个方法简单直接,但有个小缺点:如果后续foo变量被重新赋值(比如foo = {}),cb函数就会失效,因为它依赖的是foo变量的指向。
方案2:用bind绑定this到外层对象
先初始化对象,再手动把cb的this绑定到foo上:
var foo = { a: 'bar', b: 'baz', c: { ca: 'hello', cb: function() { return this.a + this.b; } } }; // 把cb的this绑定为foo对象 foo.c.cb = foo.c.cb.bind(foo); console.log(foo.c.cb()); // 输出 barbaz
这种方式下,cb的this被固定为最初的foo对象,哪怕后续foo变量被重新赋值,只要原对象没被垃圾回收,cb依然能正常访问原对象的属性。
方案3:用闭包锁定对象引用
通过立即执行函数(IIFE)创建一个闭包,把对象的引用锁在内部,避免依赖外部变量:
var foo = (function() { // 内部变量obj指向当前对象 const obj = { a: 'bar', b: 'baz', c: { ca: 'hello', cb: function() { return obj.a + obj.b; } } }; return obj; })(); console.log(foo.c.cb()); // 输出 barbaz
这个方法是最安全的,因为cb依赖的是闭包内部的obj引用,和外部的foo变量完全无关,哪怕外部foo被修改,内部函数依然能正确访问原对象的属性。
总结
箭头函数的this绑定特性决定了它没法在深层对象里实现对上层对象的自引用,换成普通函数配合直接变量引用、bind绑定或者闭包锁定的方式,就能轻松解决这个问题啦~
内容的提问来源于stack exchange,提问作者physicsboy
相关产品推荐
相关产品推荐

