看看Stack和Watch的调用,现在当我按下F10时,“Watch”中的行值变为“object object”,因为一切都发生了,我理解流程直到这个时间,然后发生的是不清楚。现在在病房,为什么即使我在第8行提供断点,代码也不会停在第8行
这是关于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行)中的情况。
答案 0 :(得分:2)
Object.prototype.toString.call(obj[e]) === "[object Object]"
永远不会成真。它总是"[object Undefined]"
一开始:
obj:: {}
prop:: 'foo.bar.foobar'
在从内部函数(if
)第一次调用之前:
obj:: {foo: {}}
prop:: ['bar', 'foobar']
在从内部函数(if
)第二次调用之前:
obj:: {foo: {bar: {}}}
prop:: ['foobar']
在最后一次执行时,prop.length
为1(else
- 不再递归):
obj:: {foo: {bar: {foobar: 'Value'}}}
prop:: []
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
不是对象,那么它将被更改为递归调用本身中的对象。