猿问

闭包相关的问题

var arr = [ { name: '张三1'},

            { name: '张三2' },

            { name: '张三3' },

            { name: '张三4' } ];

for ( var i = 0; i < arr.length; i++) {

     arr[ i ].sayHello = function () {

         console.log(i);

      };

}

arr[0].sayHello(); // 4

arr[1].sayHello(); //4

var arr = [ { name: '张三1'},

    { name: '张三2' },

    { name: '张三3' },

    { name: '张三4' } ];

for ( var i = 0; i < arr.length; i++) {

    // arr[ i ] 绑定方法

    arr[ i ].sayHello = function () {

        // 打印名字

        console.log(i);

    };

}

for ( var i = 0; i < arr.length; i++ ) {

    arr[ i ].sayHello(); // 0, 1, 2, 3

}

为什么两次执行结果不一样呢


小唯快跑啊
浏览 396回答 1
1回答

繁花如伊

我试着把问题分析得详细一点,通过举例子的方式把问题讲清楚:首先这个问题如三楼所说,不涉及闭包,主要涉及的是作用域问题,下面一步一步来看例1:console.log(i); // undefinedconsole.log(j); // undefinedfor (var i = 0; i < 4; i++) {&nbsp; &nbsp; var j = 100;}console.log(i); // 4console.log(j); // 100先看例1,第一次打印i与j都是undefined(因为没有定义),而第二次却有值了,这是因为在for循环内没有自己的作用域(在es5中只有function有自己的作用域),即是说在for内部定义的变量的作用域不仅限于for内部,外部照样能访问。例2:var x;console.log(x); // undefinedvar y = 200;var y;console.log(y); // 200看例2,变量x使用var声明,但没有被赋值,所以结果为undefined;变量y使用var声明并赋值,所以这时候y的值为200,再使用var重新声明一次,这时候原来的变量y应该是被清除掉了,并重新定义一个新的y,因为没有被赋值,所以此时y应该是undefined,但结果却是200这说明在同个作用域内,使用var多次声明同一个变量名,并不会把原有变量从内存中移除并重新分配内存,而是继续使用原有的内存地址,即是说在同个作用域内,同一个变量名只能被var声明一次,后面的var不起作用。明白了上面两点后,再来看题主的第一段代码var arr = [ { name: '张三1'},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { name: '张三2' },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { name: '张三3' },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { name: '张三4' } ];for ( var i = 0; i < arr.length; i++) {&nbsp; &nbsp; &nbsp;arr[ i ].sayHello = function () {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;console.log(i);&nbsp; &nbsp; &nbsp; };}arr[0].sayHello(); // 4arr[1].sayHello(); //4这段代码只有一个作用域(因为for没有自己的作用域呀),所以在for内部声明的i也属于这个作用域,并且整段代码下来只有一个名为i的变量,所以console.log(i)这里打印的始终是同一个变量i,for循环后i变为4,所以打印结果始终是4再看题主的第二段代码var arr = [ { name: '张三1'},&nbsp; &nbsp; { name: '张三2' },&nbsp; &nbsp; { name: '张三3' },&nbsp; &nbsp; { name: '张三4' } ];for ( var i = 0; i < arr.length; i++) {&nbsp; &nbsp; // arr[ i ] 绑定方法&nbsp; &nbsp; arr[ i ].sayHello = function () {&nbsp; &nbsp; &nbsp; &nbsp; // 打印名字&nbsp; &nbsp; &nbsp; &nbsp; console.log(i);&nbsp; &nbsp; };}for ( var i = 0; i < arr.length; i++ ) {&nbsp; &nbsp; arr[ i ].sayHello(); // 0, 1, 2, 3}这段代码也是只有一个作用域,同样整段代码也是只有一个名为i的变量,不同的是在第二个for循环里,每次循环都改变了这个变量i的值,改变之后再打印这个i,当然结果就是改变后的值了,即0, 1, 2, 3了
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答