search

Home  >  Q&A  >  body text

javascript - A JS written test question, I don’t quite understand it, please explain


function A(params) {
    params = params || {};
    for(var key in params){

        Object.defineProperty(this, key, {
            get : function() {
                return params[key]
            },
            enumerable : false
        });
    }
}


var a = new A({
    'x' : 'X',
    'y' : 'Y',
    'z' : 'Z'
})

console.log(a.x);

The result is Z, which is a bit hard to understand. The console output example is as follows:

phpcn_u1582phpcn_u15822867 days ago521

reply all(4)I'll reply

  • 滿天的星座

    滿天的星座2017-05-19 10:42:23

    The reason is actually very simple, the problem lies in the for loop

    for(var key in params){
        Object.defineProperty(this, key, {
            get : function() {
                return params[key]
            },
            enumerable : false
        });
    }

    The final key here === 'z', and the results of other attributes return params[key], which is params['z']

    reply
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-19 10:42:23

    This is an object copy function. The only difference from the original object is that the attributes of the copied object a cannot be traversed using a for loop. Because of the closure, the keys called by the get function are all z.
    a= {

    'x' : 'X',
    'y' : 'Y',
    'z' : 'Z'

    }

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-05-19 10:42:23

    Create a closure, or use let

    function A(params) {
        params = params || {};
        for(var key in params){
        
            (function(key){
                Object.defineProperty(this, key, {
                    get : function() {
                        return params[key]
                    },
                    enumerable : false
                });
            }).call(this,key);
        }
    }
    
    
    var a = new A({
        'x' : 'X',
        'y' : 'Y',
        'z' : 'Z'
    })
    
    console.log(a.x);
    

    Or change var key to let key

    reply
    0
  • 阿神

    阿神2017-05-19 10:42:23

    Object.defineProperty(this, key, {
        get : function() {
            return params[key]
        },
        enumerable : false
    });

    here,Object.defineProperty(this, key, {})这里的key是立即读取使用的,所以是预期行为x,y,z

        get : function() {
            return params[key]
        }

    This function is executed at a point in time in the future, so it reads the last key值,即z when running. This is the same as the classic closure problem.

        for(var i=0; i<5; i++) {
            dom[i].onclick = function() { // dom为一个dom数组
                console.log(i)
            }
        }

    Everything printed is 5.

    reply
    0
  • Cancelreply