__defineGetter__ 激发的思索

本文在我博客上的地点: http://lpgray.me/article/46/

问题

那天朋侪分享了一个面试题,本身当时不会,代码以下:

(function(){
    var u = { a: 1, b: 2 };
    var r = {
        m: function(k){
            return u[k];
        }
    }
    window.r = r;
})()

var R = window.r;
alert(r.m('a'))

很简单,alert的结果是1。

然则问题倒是别的一个说法,能不能经由过程r.m获取到u?

当时听到这个问题也缭乱了,压根就不晓得啥意思,经由过程r.m获取到u?

实际上这个问题问的重点是当u不晓得的时刻,怎样经由过程u[attribute]这类体式格局来取得u的本身。那末问题就来了,你须要通报一个attribute,r.m(attribute) 返回 u。

处理计划

有一个非标准的,而且将被烧毁的要领 Object.prototype.__defineGetter__ 能够给对象指定一个参数而且绑定一个函数,当将来你在此对象的实例上挪用此参数时,绑定的函数会被挪用,该参数是被定义在 prototype 上,所以此参数就是一个实例属性,谁人函数被挪用时,是以当前实例为上下文。

哦?那如许的话u就是一个实例,给u绑定一个参数,当此参数挪用的时刻返回u本身不就好啦?

怎样绑定呢?u是一个Object的实例,它继续自Object,那末就给 Object.prototype 定义一个属性,使得该属性接见时挪用的函数返回 this 就能够了,所以,处理计划以下:

Object.prototype.__defineGetter__('uuu', function(){ return this; });
alert(R.m('uuu'));

此题如许就算处理了,此题的精华主如果三点:

  1. 你可否想到经由过程属性接见本身

  2. 你可否想到运用原型继续来定义接见本身的属性

  3. 你是不是晓得 Object.prototype.__defineGetter__

优化处理计划

为了不污染 Object 原型链,我们应当定义一个随机的参数来返回本身,当运用以后再删除之,那末比较圆满的计划应当是:

Object.prototype.__defineGetter__('x123c3', function(){ return this; });
alert(R.m('x123c3'));
delete Object.prototype['x123c3']

既然烧毁了,有无替换要领?

嗯,原本本身不太清晰,谢谢网友的帮助。

现在存在这么一个API:Object.defineProperty(obj, 'key', { // descriptor }); 参阅API

使得能够直接在某一对象上定义一个属性,这个属性能够是增加或修正现有的属性,前两个参数都很好明白,obj就是要修正的对象,key就是属性名,descriptor是一个对象,用来声明新添属性的一些特征,包含6个参数:

  • configurable:默许false,示意此属性是不是可用delete删除

  • enumerable: 默许为false,示意此属性是不是可被for...in、Object.keys遍历到

  • value:默许undefined,此属性的值,能够是任何JavaScript范例

  • writable:默许为false,此属性是不是可被改写

  • get:默许undefined,指定一个函数,当属性被挪用时,此函数也被挪用,默许为返回属性值

  • set:默许undefined,指定一个函数,当属性被赋值时,此函数也被挪用,仅接收一个参数,参数为属性被赋的值

那末上面的处理计划能够改成:

Object.defineProperty(Object.prototype, 'blablabla', {
    get : function(){
        return this;
    }
});
console.log(R.m('blablabla'));
    原文作者:叔叔张
    原文地址: https://segmentfault.com/a/1190000002407109
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞