gpt4 book ai didi

javascript - 这是否包含 JavaScript 闭包?

转载 作者:可可西里 更新时间:2023-11-01 02:33:02 25 4
gpt4 key购买 nike

在尝试学习 JavaScript 闭包时,我自己有点困惑。

根据我在网上收集到的信息,闭包是...

在另一个函数中声明一个函数,并且该内部函数可以访问其父函数的变量,即使在该父函数返回之后也是如此

这是最近项目中的一小段脚本示例。它允许 div 中的文本通过按钮上下滚动。

var pageScroll = (function() {

var $page,
$next,
$prev,
canScroll = true,
textHeight,
scrollHeight;

var init = function() {

$page = $('#secondary-page');

// reset text
$page.scrollTop(0);

textHeight = $page.outerHeight();

scrollHeight = $page.attr('scrollHeight');

if (textHeight === scrollHeight) { // not enough text to scroll

return false;

};

$page.after('<div id="page-controls"><button id="page-prev">prev</button><button id="page-next">next</button></div>');

$next = $('#page-next');

$prev = $('#page-prev');

$prev.hide();

$next.click(scrollDown);

$prev.click(scrollUp);

};

var scrollDown = function() {

if ( ! canScroll) return;

canScroll = false;

var scrollTop = $page.scrollTop();

$prev.fadeIn(500);

if (scrollTop == textHeight) { // can we scroll any lower?

$next.fadeOut(500);

}

$page.animate({ scrollTop: '+=' + textHeight + 'px'}, 500, function() {

canScroll = true;

});

};

var scrollUp = function() {

$next.fadeIn(500);

$prev.fadeOut(500);

$page.animate({ scrollTop: 0}, 500);


};

$(document).ready(init);

}());

这个例子是否使用了闭包?我知道它在函数中有函数,但是否存在使用保留的外部变量的情况?

我是否在不知情的情况下使用它们?

谢谢

更新

如果我把它放在 $(document).ready(init); 语句下面,它会关闭吗?

return {
scrollDown: scrollDown
};

那么,如果我想让文本从 JavaScript 中的其他任何地方向下滚动,我可以这样做吗

pageScroll.scrollDown();

另一个更新

哇,看起来成功了!这是 JSbin 上的代码.请注意,页面滚动器在此示例中并不完全有效(它似乎没有到达文本的底部),但这没关系:)任何可以告诉我为什么它没有滚动到底部的人的奖励积分。

最佳答案

任何时候你定义一个函数,这个函数都会“包含”它定义的作用域链。当这个函数被执行时,这个作用域链在它的主体中是可用的。当一个函数定义在另一个函数内部时,作用域链包括:

  • 父函数的局部定义变量
  • 父函数的参数
  • 父函数的父函数的局部变量和参数等。
  • 全局变量

闭包的真正值(value)是返回一个内部函数,该函数捕获了一个不会改变的封闭变量,如下所示:

        function test (value){
return function(){
alert(value); //using enclosed argument
}
}

var t1 = test("first");
var t2 = test("second");
t1();//alerts "first"
t2();//alerts "second"

闭包的一个危险是它们包含一个对封闭属性的引用,而不是它们值的快照,所以要注意在循环内创建封闭函数,如下所示:

function makeArray (){
var result=[]
for (var i =0; i < 3; ++i){
result.push(function(){
alert("function #" +i); //using enclosed i
})
}
return result;
}

var fnArray =makeArray();
fnArray[0]();//alerts "function #3"
fnArray[1]();//alerts "function #3"
fnArray[2]();//alerts "function #3"

在循环中,您需要找到一种方法来使封闭变量保持不变。下面是一个使用嵌套闭包将重用计数器复制到一次性参数的示例:

function makeArray (){
var result=[]
var wrapFunction=function (counter){
return function(){
alert("function #" +counter); //using enclosed counter
}
}
for (var i =0; i < 3; ++i){
result.push(wrapFunction(i))
}
return result;
}

var fnArray =makeArray();
fnArray[0]();//alerts "function #0"
fnArray[1]();//alerts "function #1"
fnArray[2]();//alerts "function #2"

关于javascript - 这是否包含 JavaScript 闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2646118/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com