javascript在对象中获取值

时间:2017-01-09 13:37:52

标签: javascript

我得到了关于函数编写的测验:



/* ====== can not modify this line below till next dividing line ========= */
function foo() {
    var obj = {
        x : 1,
        y : 2,
        bar : bar()
    }

    function bar() {
/* ====== can not modify this line above ================================= */

        /* so how can I get obj.x and obj.y here and returns their sum ..? */

/* ====== can not modify this line below till next dividing line ========= */
    }
    return obj;
}

console.log( foo().bar ); // expected 3 
/* ====== can not modify this line above ================================= */




我自己找到了两种方法,一种是获得foo.toString()并做一些REGEX魔术。

另一个是注册一个全局变量,如window.run来控制foo()只运行一次。

但是我想知道还有其他方法可以解决这个问题吗?

感谢您的回复〜

3 个答案:

答案 0 :(得分:5)

你做不到。在构造对象之前调用barobj将为undefined,之前属性(12)的已评估值位于某处仅在内存中无法访问。另请参阅Self-references in object literal declarations

鉴于你在一个具有相当任意限制的测验中发现了这个问题,他们似乎期待一个特技答案。有几种方法:

  • 访问源代码并自行评估对象文字
  • 简单地返回一个常量,因为obj.xobj.y在给定代码中也是常量
  • 覆盖console.log进行出价,例如

    function bar() {
        var log = console.log.bind(console);
        console.log = function(p) {
            log(p.valueOf());
        };
        return {
            valueOf: function() {
                return obj.x + obj.y;
            }
        };
    }
    

    由于在调用console.log之前foo()被取消引用,因此无法正常工作。
    类似的方法适用于console.log行为can be customized而无需覆盖任何内容的环境:

    function bar() {
        return {
            inspect: function() {
                return String(obj.x + obj.y);
            }
        };
    }
    
  • 只需自己致电foo()即可获取值,但不要在bar上无限递归:

    function bar() {
        if (foo.stop) return null;
        foo.stop = true;
        var res = foo().x + foo().y;
        foo.stop = false;
        return res;
    }
    

答案 1 :(得分:1)

如果真的“已锁定”进行修改,请使用以下“ magic ”(针对测试用例):

function foo() {
  var obj = {
    x : 1,        
    y : 2,
    bar : bar()
  }

  function bar() {
    var magic_sum = foo.toString().match(/var obj =\s*?\{\s*?x\s*?:\s*?(\d+),\s*?y\s*?:\s*?(\d+),/)
                    .slice(1,3).map(Number);

    return magic_sum[0] + magic_sum[1];
  }
  return obj;
}

console.log(foo().bar);

算法:

foo.toString() - 获取函数文本表示

.match(/var obj =\s*?\{\s*?x\s*?:\s*?(\d+),\s*?y\s*?:\s*?(\d+),/) - 匹配xy属性值

.slice(1,3) - 从捕获的组合中获取值(xy属性)

.map(Number) - 将每个值投射到 Number 类型

答案 2 :(得分:1)

foo.callingTime = foo.callingTime || 1;
    if(foo.callingTime === 1){
      foo.callingTime++;
      foo.tempObj = foo();
      return foo.tempObj.x+foo.tempObj.y;
    }
    else if(foo.callingTime === 2){
      foo.callingTime = 1;
      return;
    }