Javascript,设置onclick方法语法

Javascript,设置onclick方法语法,javascript,onclick,Javascript,Onclick,我正在查看一个javascript代码,该代码处理HTML标记,我很难理解它是如何设置“onclick”属性的。它似乎在告诉它用索引变量j更新ytplayer_playitem,然后调用ytplayer_playizy(1000) 但是所有的括号是怎么回事?javascript语法中的哪些细节允许它这样设置 var a = document.createElement("a"); a.href = "#ytplayer"; a.onclick = (function (j) { retu

我正在查看一个javascript代码,该代码处理HTML标记,我很难理解它是如何设置“onclick”属性的。它似乎在告诉它用索引变量j更新ytplayer_playitem,然后调用ytplayer_playizy(1000)

但是所有的括号是怎么回事?javascript语法中的哪些细节允许它这样设置

var a = document.createElement("a");
a.href = "#ytplayer";
a.onclick = (function (j) {
    return function () {
        ytplayer_playitem = j;
        ytplayer_playlazy(1000);
    };
})(i);
这将创建一个“闭包”,以确保绑定到处理程序的
i
的值是
i
“当时”的值,而不是通常的
i

在代码中,
()
中的函数是一个表达式,执行并传递变量
i
。这是您在最后部分看到的
(i)
。在此执行的函数表达式中,
i
成为局部变量
j
。此已执行函数表达式返回要绑定
onclick
事件的处理函数,该事件带有
j
的值,该值当时为
i


如果我没有使用闭包:

//suppose i is 1
var i = 1;

a.onclick = function () {
    ytplayer_playitem = i;
    ytplayer_playlazy(1000);
};

//and changed i
i = 2;

//if you clicked the <a>, it would not be 1 onclick but 2 because you 
//did not assign the value of i "at that time". i is "tangible" this way
//假设我是1
var i=1;
a、 onclick=函数(){
ytplayer_playitem=i;
YTU玩家(1000);
};
//我变了
i=2;
//如果单击,则不会是1 onclick,而是2,因为
//未分配i“当时”的值。我是这样“有形”的
这将创建一个“闭包”,以确保绑定到处理程序的
i
的值是
i
“当时”的值,而不是通常的
i

在代码中,
()
中的函数是一个表达式,执行并传递变量
i
。这是您在最后部分看到的
(i)
。在此执行的函数表达式中,
i
成为局部变量
j
。此已执行函数表达式返回要绑定
onclick
事件的处理函数,该事件带有
j
的值,该值当时为
i


如果我没有使用闭包:

//suppose i is 1
var i = 1;

a.onclick = function () {
    ytplayer_playitem = i;
    ytplayer_playlazy(1000);
};

//and changed i
i = 2;

//if you clicked the <a>, it would not be 1 onclick but 2 because you 
//did not assign the value of i "at that time". i is "tangible" this way
//假设我是1
var i=1;
a、 onclick=函数(){
ytplayer_playitem=i;
YTU玩家(1000);
};
//我变了
i=2;
//如果单击,则不会是1 onclick,而是2,因为
//未分配i“当时”的值。我是这样“有形”的
“但是所有的括号是怎么回事?”

大多数括号只是做了你期望的事情

有一个额外的集合在技术上是不需要的,但通常被用作正在调用函数的提示

                       // v-v---these are part of the function definition like normal
    a.onclick = (function (j) {
           //   ^-----------this and...v
        return function () {
            ytplayer_playitem = j;
            ytplayer_playlazy(1000);
        };
 //  v---...this are technically not needed here, but are used as a hint
    })(i);
 //   ^-^---these invoked the function like normal

“javascript语法中的哪些细节允许它这样设置?”

结果是立即调用函数,并传递
i
,以便立即调用函数中的
j
参数引用其值

for(var i = 0; i < 10; i++) {
    // create the new element
    a.onclick = createHandler(i);
    // append it somewhere
}

function createHandler (j) {
    return function () {
        ytplayer_playitem = j;
        ytplayer_playlazy(1000);
    };
}
这将创建一个变量范围,返回的函数将继续访问该范围。这样,它总是可以访问
j
变量,而不是在循环中被覆盖的
i


在我看来,这些内联函数有点被滥用。如果你简单地把它变成一个命名函数,它会变得更清晰

for(var i = 0; i < 10; i++) {
    // create the new element
    a.onclick = createHandler(i);
    // append it somewhere
}

function createHandler (j) {
    return function () {
        ytplayer_playitem = j;
        ytplayer_playlazy(1000);
    };
}
for(变量i=0;i<10;i++){
//创建新元素
a、 onclick=createHandler(i);
//附加在某处
}
函数createHandler(j){
返回函数(){
ytplayer_playitem=j;
YTU玩家(1000);
};
}
结果处理程序完全相同,但代码不那么神秘

“但是所有的括号是怎么回事?”

大多数括号只是做了你期望的事情

有一个额外的集合在技术上是不需要的,但通常被用作正在调用函数的提示

                       // v-v---these are part of the function definition like normal
    a.onclick = (function (j) {
           //   ^-----------this and...v
        return function () {
            ytplayer_playitem = j;
            ytplayer_playlazy(1000);
        };
 //  v---...this are technically not needed here, but are used as a hint
    })(i);
 //   ^-^---these invoked the function like normal

“javascript语法中的哪些细节允许它这样设置?”

结果是立即调用函数,并传递
i
,以便立即调用函数中的
j
参数引用其值

for(var i = 0; i < 10; i++) {
    // create the new element
    a.onclick = createHandler(i);
    // append it somewhere
}

function createHandler (j) {
    return function () {
        ytplayer_playitem = j;
        ytplayer_playlazy(1000);
    };
}
这将创建一个变量范围,返回的函数将继续访问该范围。这样,它总是可以访问
j
变量,而不是在循环中被覆盖的
i


在我看来,这些内联函数有点被滥用。如果你简单地把它变成一个命名函数,它会变得更清晰

for(var i = 0; i < 10; i++) {
    // create the new element
    a.onclick = createHandler(i);
    // append it somewhere
}

function createHandler (j) {
    return function () {
        ytplayer_playitem = j;
        ytplayer_playlazy(1000);
    };
}
for(变量i=0;i<10;i++){
//创建新元素
a、 onclick=createHandler(i);
//附加在某处
}
函数createHandler(j){
返回函数(){
ytplayer_playitem=j;
YTU玩家(1000);
};
}

结果处理程序完全相同,但代码不那么神秘。

对,我猜周围的代码如下所示:

for (var i = 0; i < playitems.length; i++) {
    // above code here
}
a.onclick = function() {
    ytplayer_playitem = i;
    ytplayer_playlazy(1000);
};
a.onclick = function() { ... }
a.onclick = generate_onclick(i);
但是,这不会很好地工作,因为
i
的值会发生变化。无论单击哪个链接,最后一个链接都将被激活,因为此时的
i
值将是列表中的最后一个

所以你需要防止这种情况发生。您需要通过创建一个新的作用域来实现这一点,该作用域是通过创建一个额外的函数来实现的,该函数将立即被调用:

(function (j) {
    // some code here
})(i);
由于已将
i
传递到函数中,因此传递的是值,而不是对保留变量的引用。这意味着您现在可以定义一个引用正确值的函数。因此,您可以使用额外的函数返回单击处理函数:

a.onclick = (function (j) { // j is the right number and always will be
   return function () { // this function is the click handler
       ytplayer_playitem = j;
       ytplayer_playlazy(1000);
   };
})(i);
return function() { /* ... */ }

因此,每个
a
元素都有自己的click处理程序函数,每个函数都有自己的
j
变量,这是正确的数字。因此,当单击链接时,它们将执行您希望它们执行的功能。

对,我猜周围的代码如下所示:

for (var i = 0; i < playitems.length; i++) {
    // above code here
}
a.onclick = function() {
    ytplayer_playitem = i;
    ytplayer_playlazy(1000);
};
a.onclick = function() { ... }
a.onclick = generate_onclick(i);
但是,这不会很好地工作,因为( function( j ) { return j + 1; } )( 5 ); // => 6
return function() { /* ... */ }
a.onclick = ( function( j ) {
    return function() {
             ytplayer_playitem = j;
             ytplayer_playlazy( 1000 );
           }
  }
)( i );
function() {
  ytplayer_playitem = 9;
  ytplayer_playlazy( 1000 );
}