【问题标题】:javascript how to deep bind an object to a new 'this' valuejavascript如何将对象深度绑定到新的“this”值
【发布时间】:2017-09-29 01:10:10
【问题描述】:

我有一个值,它可能是一个原语或一个函数,或者是一个递归地包含原语/函数/对象的对象。

给定一个theThis 参数,我如何将可能在我的值内的所有函数深度绑定到theThis

我尝试了类似的方法:

function deepBind(o, ths) { 
  Object.getOwnPropertyNames(o).forEach(key => { 
    const desc=Object.getOwnPropertyDescriptor(o, key);
    if (typeof desc === "function") Object.defineProperty(o, key, key.bind(ths)); 
    if (Object.getOwnPropertyNames(key).length>0) deepBind(o.key, ths);
  });
}

但是失败了:(

我查看了一些解决方案,例如 https://github.com/jonschlinkert/deep-bind/blob/master/index.js,但这不是独立的。

我正在寻找一个独立的deepBind(val, theThis) 解决方案。 我需要解决方案来涵盖 getter 和 setter。

谢谢!

【问题讨论】:

  • I looked at some solutions and made some failed attempts but no luck ...比如?
  • “或递归包含原语/函数/对象的对象”“递归”是什么意思?
  • 添加我的尝试
  • guest271314 - 我的意思是 val 可能是一个包含另一个对象作为属性的对象,其中包含一个函数作为属性
  • 指出您的代码有什么问题,key 是一个字符串...您多次使用它,就好像它是您想要的属性一样(您应该经常使用o[key]never o.key 因为它指的是 okey 属性 - 但是,您发布的代码,如果您修复 key 的用法,您最终会得到无限递归

标签: javascript ecmascript-6


【解决方案1】:

这似乎可以按您的意愿工作

function deepBind(o, ths) {
    Object.entries(o).forEach(([key, value]) => {
        if (typeof value === "function") {
            // don't use value here :p
        	o[key] = o[key].bind(ths);
        }
        if (typeof value === 'object' || typeof value === 'function') {
        	deepBind(value, ths);
        }
    });
}
const v = {
    foo:3, 
    fn: function() {
        console.log(this);
    }, 
    obj: { 
        bar: 4,
        fn: function() {
            console.log(this);
        }
    }
};
var someThis = {hello: 'world'};
deepBind(v, someThis);
v.fn();
v.obj.fn();

【讨论】:

  • 好极了,这也包括获取/设置属性吗?
  • 我没有最模糊的想法:p
  • “这是否也包括 get/set 属性?” 原始问题中提到的 get 和 set 属性在哪里?见stackoverflow.com/help/how-to-ask
【解决方案2】:

类似的东西:

function deepBind (o, thisVal) {

   return Object.keys(o)
      .reduce((res, key) => {

          const v = o[key];
          const tv = typeof v;
          switch (tv) {
              case "object":
                  // should be updated for arrays...
                  if ( v !== null ) {
                      res[key] = deepBind(v, thisVal);
                  } else {
                      res[key] = v;
                  }
                  break;
              case "function":
                  res[key] = v.bind(thisVal);
                  break;
              default:
                  res[key] = v;
                  break;
          }
          return res;

      }, {});

}

它递归地从原始对象复制值,将函数道具绑定到thisVal

请注意,递归绑定没有多大意义,因为人们希望通过其调用站点定义词汇上下文。

【讨论】:

    猜你喜欢
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 2016-06-07
    • 2015-07-19
    • 2019-03-10
    • 1970-01-01
    相关资源
    最近更新 更多