Javascript 对象上下文未声明的变量

标签 javascript

我遇到了一些奇怪的事情,我想与你分享,以便你能帮助我解决我的困惑。 (我花了一段时间才弄清楚出了什么问题)

我想创建一个递归函数,它可以在嵌套 <ul> 上呈现类似树的数据结构。元素。

数据结构采用以下形式:

var contents = [
    { 
        name : 'test',
        contents : [
            {
                name : 'test > test 1'
            },
            {
                name : 'test > test 2'
            },
            {
                name : 'test > test 3'
            }                
        ]
    },
    {
        name : 'test 2'
    }        
];

我将代码添加到对象 block 上,如下所示:

var dummy = {
    do : function() {
        var element = $('<ul>');
        dummy.recursive(element, contents);

        $("#content").append(element);
    },
    recursive : function( element, contents ) {
        for( i = 0; i < contents.length; i++ ) {
            var item = contents[i];

            var li = $('<li> (' + i + ') ' + item.name + '</li>');

            if( item.contents && item.contents.length ) {
                var ul = $('<ul>');
                dummy.recursive(ul, item.contents);

                li.append(ul);
            }
            element.append(li);
        }
    }
};

我发现变量i之后dummy.recursive运行后第一个元素的内容不再是 0 而是 2。这意味着虽然 i在其私有(private)上下文中正在被递归函数取代。

我还添加了一个jsfiddle来说明这里的问题:http://jsfiddle.net/MWQJC/2/

问题出在变量 i 上没有通过执行 var i = 0 来显式声明在函数的开头。 (如下所示:http://jsfiddle.net/h8gtd/1/)

默认情况下,每个访问的未声明变量都是在对象作用域中创建的。是这样吗?

最佳答案

It looks like by default every undeclared variable accessed is being created in the object scope. Is this so?

没有。

每次访问(读取)变量的值时,JS 引擎都会尝试在当前作用域中查找该变量,然后在当前作用域的外部作用域中查找,然后在该作用域的外部作用域中查找,依此类推,直到您找到该变量。找到全局范围。此时,如果变量仍未声明,则会抛出错误。

当您向变量设置(写入)值时,会遵循相同的过程,但最后一步有所不同。如果该变量尚未在全局作用域中声明,则将在全局作用域中创建具有该名称的变量。

例如:

// global scope
!function() { // scope 1
  var x; // comment this line to log 7 instead
  !function() { // scope 2
    x = 7;
  }()
}();

console.log(x) // undefined, because it never reached the global scope

在您的特定示例中,您是正确的,问题是 i 尚未在递归函数中声明为变量,因此该递归函数的所有调用都将使用相同的 i 在某些外部作用域或全局作用域中定义的变量。

编辑:我一直使用作用域这个词,但忘了提及,与许多其他语言不同,JavaScript 没有 block 作用域,而是具有函数作用域。

关于Javascript 对象上下文未声明的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20097612/

相关文章:

javascript - 未捕获的TypeError : Cannot read property 'transaction' of null with an indexeddb

javascript - 为什么 Youtube 评论不触发 DOM 突变?

javascript - backbone.js 模型属性在运行时不可用

javascript - 正则表达式失败 javascript

javascript - 将 slider 的下一张和上一张按钮更改为下一张或上一张图片的预览

javascript - 当我改变位置时停止改变宽度

php - 通过单击按钮添加 addcart 的金额

javascript - 尽管导入了变量,但 Winless NameError

javascript - jQuery 复选框被锁定为选中状态

javascript - HTML 5 Canvas 和移动对象