为对象生成Getter和Setter的函数失效问题求助
问题分析与解决方案
你的代码核心问题有两个:
- var声明的变量作用域问题:循环里用
var key,var是函数级作用域,所有生成的get/set函数共用同一个key变量。循环结束后,key的值会停在最后一个遍历到的属性——也就是getSetGen,所以你调用person.getname()时,函数里的this[key]实际是this['getSetGen'],自然拿不到name的值。 - 没有排除getSetGen本身:循环遍历对象所有属性时,把
getSetGen这个方法也包含进去了,导致生成了多余的getgetSetGen和setgetSetGen函数,完全没必要。
修正方案1(ES6+ 推荐写法)
用let声明循环变量,让每个迭代都拥有独立的作用域,同时跳过getSetGen属性:
person = { id: 1, name: 'John', phone: '123-456-789', getSetGen: function(){ // let声明key,每个循环迭代都有独立作用域 for(let key in this){ // 跳过getSetGen方法本身 if(key === 'getSetGen') continue; this[`set${key}`] = function(value){ this[key] = value; console.log(this[key]); } this[`get${key}`] = function(){ console.log(this[key]); return this[key]; } } } } person.getSetGen() person.getname(); // 正常输出John person.setid(2); // 输出2,id属性被正确更新
修正方案2(兼容ES5环境)
用立即执行函数创建闭包,保存每个循环的key值:
person = { id: 1, name: 'John', phone: '123-456-789', getSetGen: function(){ for(var key in this){ if(key === 'getSetGen') continue; // 用闭包锁定当前迭代的key值 (function(currentKey){ this[`set${currentKey}`] = function(value){ this[currentKey] = value; console.log(this[currentKey]); } this[`get${currentKey}`] = function(){ console.log(this[currentKey]); return this[currentKey]; } }).call(this, key); } } } person.getSetGen() person.getname(); // 正常输出John
补充:基于Object.defineProperty的修正写法
你注释里的思路也可行,但原代码有两个错误:未定义的self、this.key的访问错误,修正后如下:
person = { id: 1, name: 'John', phone: '123-456-789', getSetGen: function(){ for(var key in this){ if(key === 'getSetGen') continue; (function(currentKey){ Object.defineProperty(this, `set${currentKey}`, { value: function(value) { this[currentKey] = value; console.log(this[currentKey]); } }); Object.defineProperty(this, `get${currentKey}`, { value: function() { console.log(this[currentKey]); return this[currentKey]; } }); }).call(this, key); } } }
内容的提问来源于stack exchange,提问作者IBdr
相关产品推荐
相关产品推荐

