search

Home  >  Q&A  >  body text

javascript - 前端面试题,利用给定接口获得闭包内部对象

var o = (function() {
    var person = {
        name: 'Vincent',
        age: 24,
    };
    return {
        run: function(k) {
            return person[k];
        },
    }
}());

在不改变上面的代码情况下, 怎么得到原有的 person 对象?


假如在 person 中加上 __proto__: null,原先大家回答的方法就失效了,但此时仍旧有​​解,有兴趣者欢迎挑战。

巴扎黑巴扎黑2818 days ago303

reply all(8)I'll reply

  • 巴扎黑

    巴扎黑2017-04-10 15:30:22

    Object.prototype.__defineGetter__('get', function(){
        return this;
    });
    
    
    console.log(o.run('get'));
    

    reply
    0
  • 阿神

    阿神2017-04-10 15:30:22

    基于 @小俞 的方法,我写个可能是更好的选择的吧!

    javascriptObject.defineProperty(Object.prototype, 'self', {
        get: function () {return this;},
        set: function (value) {return this},
        configurable: true
        // 该属性的存在是确保该属性可被delete方法删除
    });
    
    var person = o.run('self');
    delete Object.prototype.self;
    //由于不推荐使用prototype来扩展自己定义的属性(扩展标准规定的除外),这里把扩展再去掉。
    

    相较 小俞 的做法,这里面的用到的都是共有方法,不是__xxx__这种更为私有的方法(__xxx__)这种可能在不同浏览器里的实现不一样。

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 15:30:22

    对于这种问题我们首先要分析它的代码结构:
    1.看它的返回值,我们看到它最终的一个返回值是一个json对象,这个json对象有一个run的函数。
    2.分析函数,run这个函数实际上只做了一件事件,接受参数通过参数调用上面声明的person对象的值。
    3.再看你的问题,你是想问在如何不修改已有的代码情况下打印person对象。
    4.返回来看第2点,我们已经知道,通过o.run("name");实际上就是操作person对象本身,它返回的结果是Vincent

    reply
    0
  • PHPz

    PHPz2017-04-10 15:30:22

    你的提问并不是很明确...
    1、你指的“把正规person对象打印出来”是用console.log这类方法显示在控制面板里?
    2、这道题目其实是闭包的问题,javascript里的闭包是设计成对外隐藏内部变量的。如果你想用“正规”方式打印出来,貌似是对js闭包变量安全性做一次否定。
    3、你确定这道题目是个前端面试题?那你心中是否已经从面试者那获得了这道题的答案?如果是你自己对闭包概念的疑问的话,还望你别加上前端面试题这一title

    Ps: 如果想在chrome这类浏览器的console面板里查看这个闭包里的数据到时可以通过console.log(o),找到run函数下的查看里面的person,也就是你指的原始person对象

    reply
    0
  • 高洛峰

    高洛峰2017-04-10 15:30:22

    Object.defineProperty(Object.prototype, 'get', {get: function(){
        return this;
    }});
    
    
    console.log(o.run('get'));
    

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-10 15:30:22

    赞,其实想到了通过Object.prototype去做,只是忘了给它加方法把自己返回出来。

    reply
    0
  • 阿神

    阿神2017-04-10 15:30:22

    这个如果能做到的话。 js的闭包定义就得重新定义了。更何况这哥们还把 person的_proto__指向了null。
    对于一个意味着即将被回收的null数据 你外界怎么获取他?

    var person = {
       __proto__ : null,
       x : 'x'
    };
    
    person instanceof person;  //  false  哥们 这是 false  怎么用你们定义的Object.prototype.get 方法?
    
    Object.defineProperty(Object.prototype, 'self', {
        get : function(){console.log('xxxxxxxxxxxxx');}
     });
    
    person.self  // undefined  他就不能用Object的方法
    

    reply
    0
  • 迷茫

    迷茫2017-04-10 15:30:22

    小白觉得题已经完全变味了,题主该再起一贴讨论。

    reply
    0
  • Cancelreply