与Java不同,Javascript中的赋值运算符是否意味着LHS上的所有操作都会反映在RHS上?
这是问题“”的答案的继续 代码就像一个符咒,但我无法理解它是如何工作的!!所以几天后+我的console.log实际上超过了我的代码行的情况:P。。我的问题是: 下面是JavaScript函数的代码:与Java不同,Javascript中的赋值运算符是否意味着LHS上的所有操作都会反映在RHS上?,javascript,Javascript,这是问题“”的答案的继续 代码就像一个符咒,但我无法理解它是如何工作的!!所以几天后+我的console.log实际上超过了我的代码行的情况:P。。我的问题是: 下面是JavaScript函数的代码: 功能深化(o){ var oo={},t,parts,part; for(变量k in o){ t=oo; 部分=k.分割('.'); var key=parts.pop(); while(零件长度){ part=parts.shift(); t=t[part]=t[part]|{}; } t[
功能深化(o){
var oo={},t,parts,part;
for(变量k in o){
t=oo;
部分=k.分割('.');
var key=parts.pop();
while(零件长度){
part=parts.shift();
t=t[part]=t[part]|{};
}
t[key]=o[k]
}
返回oo;
}
console.log(
加深({'ab.cd.e':'foo','ab.cd.f':'bar','ab.g':'foo2'})
);代码>首先,您使用的不是JSON,而是JS对象。大多数情况下,如果需要Java类比,您应该将对象视为无限的HashMap
你的问题:
t=oo
表示它们都引用在函数开始时创建的同一实例。为什么要使用第二个变量
t=t[part]
您可以直接将t
的条目分配给t
我没有测试代码,但我很确定它有缺陷。测试顶级中有多个名称的对象会发生什么情况,例如,{'a.b':1,'b.a':1}
。不过,您不需要递归,可以使用堆栈
关于您的代码:
使用描述性的名称和注释,尤其是在询问其他人需要理解您的代码的问题时
不要在函数开头定义所有变量。这种老习惯源于C语言的早期,需要改掉
for(var k in o)
不是迭代对象条目的推荐方法。使用
不需要从部件数组弹出,每次迭代都会重置它<代码>for(const part of parts)
也可以
我将首先用一些更好的名称重新定义函数,这样解释就容易多了
function deepen(object) {
var nestedObject = {}, cursor, nestingPath, nodeKey;
for (var dotKey in object) {
cursor = nestedObject;
nestingPath = dotKey.split('.');
var leafKey = nestingPath.pop();
while (nestingPath.length) {
nodeKey = nestingPath.shift();
cursor = cursor[nodeKey] = cursor[nodeKey] || {};
}
cursor[leafKey] = object[dotKey];
}
return nestedObject;
}
我的猜测是,我并不完全知道while循环是如何工作的。重要的是要知道,当两个变量引用同一个对象时,当您更改一个对象时,两个变量都会更改。它们是相同的对象,但您选择了两个控制柄 让我举一个例子:
object = {};
cursor = object;
cursor.foo = "bar";
object; //=> {foo: "bar"}
cursor; //=> {foo: "bar"}
cursor.a = {};
object; //=> {foo: "bar", a: {}}
cursor; //=> {foo: "bar", a: {}}
cursor = cursor.a;
object; //=> {foo: "bar", a: {}}
cursor; //=> {} <- this is ^
cursor.b = "c";
object; //=> {foo: "bar", a: {b: "c"}}
cursor; //=> {b: "c"}
这也可以写成:
if (!cursor[nodeKey]) cursor[nodeKey] = {};
cursor = cursor[nodeKey];
如果动态
nodeKey
属性不存在(falsy),则会将新对象指定给该属性。然后将cursor
指定给中的嵌套对象,类似于我上面的示例cursor=cursor。a
讨论不是以模糊方式编写的代码要容易得多。具体地说,在需要变量时定义变量,并为它们指定描述性名称。如果你需要帮助,我们会在这里帮助你,但不要试图不必要地迷惑我们\这看起来是一个很好的问题——它包含了先前的研究、个人努力、使用降价的良好格式,并显示了代码。但是,请尽量避免在这里的帖子中给出投票建议-大多数用户都没有登录,因此这对他们没有用处,而且在任何情况下给出建议都会鼓励相反的行为!“这个旧习惯源于C语言的早期,需要改掉。”我同意它需要改掉,但Crockford不是也提倡它吗?他有一个合乎逻辑的理由——var
s没有块作用域,所以你不应该在if
或for
中“声明”一个,因为这会误导你认为它在外面是不可见的。因此,他的解决方案是将所有变量放在函数的顶部,以便明确其作用域。作为记录,我发现这比使用if(cond){var x=“whatever”}
更糟糕。像Crockford的很多东西一样,它有意义,但没有用处。当使用var
时,我仍然在函数顶部有所有变量定义。这样,范围就清晰了,因为var
变量被提升。然而,随着let
和const
的引入,我认为没有多少理由使用var
。使用let
或const
定义的变量未被提升,因此我在需要时定义它们。对于@3limin4t0r的延迟回复,我深表歉意。我没有收到通知,所以当我再次访问时,请通读线程。非常感谢。这确实有助于澄清我在理解它时存在的概念差距。我相信这段代码是一个树构造算法的实现?与Java相比,JS看起来是程序化的,您是否建议我重新审视数据结构,作为精通Javascript的必要条件?
if (!cursor[nodeKey]) cursor[nodeKey] = {};
cursor = cursor[nodeKey];