属性封装的重要性
属性封装:需要暴露给外界使用的对象,应该提供get和set方法,不允许直接操作变量值
之前我一直不理解,在get和set中没有别的逻辑的时候,这与直接操作变量值的区别在哪里
场景
我维护的连接管理sdk,对外提供一个connected属性,标识当前连接是否建立,同时sdk内部逻辑中也依赖这个属性执行逻辑
在我的假想中,这个属性我给到使用者用来判断连接是否建立,他可以执行重连操作
问题
最近,业务端报障,连接管理一直处于重连状态,后续的消息都没法传输
我在chrome里debug,connected属性连接成功后赋值为true,一段时间就会变成false,导致后续逻辑执行混乱
过程
百思不得其解,我的代码中只有对象初始化时和连接关闭才会赋值false,甚至我都一度怀疑是js事件循环初始化代码未执行完成就去执行连接函数,然后回来继续初始化赋值false,求证js专业选手,js并不会这样做
我意识到有人改了connected属性,可是我没有证据...
思考
如果connected属性我封装了set方法,这样我至少可以在set方法里打一个断点或者加一行日志,确定属性被修改了几次,以致找到属性是在哪里修改的
后续
查证下来,业务端这里为了可以监测connected属性变化,代理了这个属性,初始值这里没有处理好,执行了赋值操作
Object.defineProperty(provider, 'wsconnected', {
configurable:true,
get() {
return wsStatus;
},
set(newVal){
if (newVal !== wsStatus) {
wsStatus = newVal;
setWSConnected(newVal);
}
},
});
注意:
try{
wsconnected = false
} catch(e) {
}
wsconnected变化时,会触发set方法,若此时set方法内部报错,则会进入catch代码块。