如何在此代码段中进行递归?

时间:2016-08-21 04:42:16

标签: javascript object recursion

看看Stack和Watch的调用,现在当我按下F10时,“Watch”中的行值变为“object object”,因为一切都发生了,我理解流程直到这个时间,然后发生的是不清楚。现在在病房,为什么即使我在第8行提供断点,代码也不会停在第8行

Image这是关于stackoverflow

的问题

我正在尝试理解这段代码

function assign(obj, prop, value) {
    if (typeof prop === "string")
        prop = prop.split(".");

    if (prop.length > 1) {
        var e = prop.shift();
        assign(obj[e] =
                 Object.prototype.toString.call(obj[e]) === "[object Object]"
                 ? obj[e]
                 : {},
               prop,
               value);
    } else
        obj[prop[0]] = value;
}

var obj = {},
    propName = "foo.bar.foobar";

assign(obj, propName, "Value");

递归是如何发生的,因为函数没有返回任何东西? 内部调用中的参数值如何随着最高调用堆栈(赋值函数)中的函数的更改而完成?

感谢大家的答案,但我的确切问题是我在这一特定行(第8行)中的情况。

3 个答案:

答案 0 :(得分:2)

Object.prototype.toString.call(obj[e]) === "[object Object]"永远不会成真。它总是"[object Undefined]"

  1. 一开始:

    obj:: {}
    prop:: 'foo.bar.foobar'
    
  2. 在从内部函数(if)第一次调用之前:

    obj:: {foo: {}}
    prop:: ['bar', 'foobar']
    
  3. 在从内部函数(if)第二次调用之前:

    obj:: {foo: {bar: {}}}
    prop:: ['foobar']
    
  4. 在最后一次执行时,prop.length为1(else - 不再递归):

    obj:: {foo: {bar: {foobar: 'Value'}}}
    prop:: []
    
  5. Javascript中的对象总是作为参考传递,请参阅@Tiny Giant的评论。

答案 1 :(得分:1)

Object.prototype.toString.call(obj[e]) === "[object Object]"只是一种非常难看的说法"(如果)这个对象确实存在......"。我不会详细解释它是如何工作的,因为它不是一个很好的例子,你可能不理解它。

代码想要的是能够添加/编辑对象属性。例如:

var person = {name: 'Liana', hair: {color:'red', style:'long'}};
assing(person, 'name', 'George');

...等。但是如果你想编辑一个嵌套属性,比如头发颜色呢?

assign(person, 'hair.color', 'brown');

基本上,assign函数被调用两次:

  • assign(person, 'hair.color', ...)
  • 这检测到我们正在编辑color内的嵌套属性(hair) 它确保hair内真实存在person
  • 如果没有,则会创建person.hair(这就是丑陋的界限)
  • 然后拨打assing(person.hair, 'color', 'brown');

我个人会写这样的函数:

function assign(object, prop, value) {
    prop = prop.split('.');

    if(prop.length > 1) {
        var first = prop.shift();
        prop = prop.join('.');
        if(typeof object[first] != 'object')
            object[first] = {};
        assign(object[first], prop, value);
    } else {
        object[prop] = value;
    }
}

答案 2 :(得分:1)

  

如何递归递归,因为函数没有返回任何内容   ?

递归发生时不需要返回值。这里,条件prop.length > 1将在将值设置为所需属性

后停止递归
  

内部调用中的参数值如何更改为   最高调用堆栈(赋值函数)中的函数是否完成?

我不确定你在这里问的是什么。我想你在问这条线

assign(obj[e] =
                 Object.prototype.toString.call(obj[e]) === "[object Object]"
                 ? obj[e]
                 : {},
               prop,
               value);

此代码检查obj是否为对象。如果obj不是对象,那么它将被更改为递归调用本身中的对象。