JavaScript工厂函数sink方法无法修改sunk属性问题求助
问题根因
- 基础类型和引用类型的赋值逻辑差异导致了这个现象:
- 你的工厂函数内部的
sunk是布尔值,属于基础类型,return对象时是直接把sunk的当前值(初始为false)拷贝给返回对象的sunk属性,闭包内的局部变量sunk和返回对象的sunk属性后续是完全独立的两个值,没有关联。你调用sink()修改的只是闭包里的局部变量,不会同步到返回对象的属性上。 - 而
hits是数组,属于引用类型,return时拷贝的是内存地址,闭包内的hits和返回对象的hits指向同一个数组实例,所以hit()修改数组内容时,外部读取能看到变化。 - 额外注意你原代码的
hit方法边界判断有漏洞:position <= hits.length会允许索引等于数组长度,而数组索引最大为length-1,会出现越界赋值问题。
- 你的工厂函数内部的
修复方案
方案1:为sunk属性添加getter(最常用,保留闭包私有特性)
每次读取sunk属性时,直接返回闭包里最新的局部变量值:
const Ship = (name, length, orientation = 'horizontal') => { let sunk = false; const hits = Array(length).fill(false); const hit = (position) => { // 修复边界判断 if (position < hits.length) hits[position] = true; }; function sink() { sunk = true; } return { name, length, orientation, // 定义getter,每次读取都返回闭包内的最新值 get sunk() { return sunk }, hits, hit, sink, }; };
方案2:直接修改实例自身属性
放弃用闭包私有变量存sunk,直接在方法内修改实例对象的属性:
const Ship = (name, length, orientation = 'horizontal') => { const hits = Array(length).fill(false); const hit = (position) => { if (position < hits.length) hits[position] = true; }; const ship = { name, length, orientation, sunk: false, hits, hit, sink() { this.sunk = true; } }; return ship; };
内容的提问来源于stack exchange,提问作者LearningPython
相关产品推荐
相关产品推荐

