本文在我博客上的地点: 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'));
此题如许就算处理了,此题的精华主如果三点:
你可否想到经由过程属性接见本身
你可否想到运用原型继续来定义接见本身的属性
你是不是晓得
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'));