欧美中文字幕第一页-欧美中文字幕一区-欧美中文字幕一区二区三区-欧美中文字幕在线-欧美中文字幕在线播放-欧美中文字幕在线视频

JavaScript 秘密花園

我是創始人李巖:很抱歉!給自己產品做個廣告,點擊進來看看。  

原文: http://bonsaiden.github.io/JavaScript-Garden/ ? 翻譯: 三生石上

其它

setTimeoutsetInterval

由于 JavaScript 是異步的,可以使用 setTimeoutsetInterval 來計劃執行函數。

注意: 定時處理 不是 ECMAScript 的標準,它們在 DOM (文檔對象模型) 被實現。
				function foo() {}
				var id = setTimeout(foo, 1000); // 返回一個大于零的數字
			

setTimeout 被調用時,它會返回一個 ID 標識并且計劃在將來 大約 1000 毫秒后調用 foo 函數。 foo 函數只會被執行 一次

基于 JavaScript 引擎的計時策略,以及本質上的單線程運行方式,所以其它代碼的運行可能會阻塞此線程。 因此 沒法確保 函數會在 setTimeout 指定的時刻被調用。

作為第一個參數的函數將會在 全局作用域 中執行,因此函數內的 this 將會指向這個全局對象。

				function Foo() {
				this.value = 42;
				this.method = function() {
				// this 指向全局對象
				console.log(this.value); // 輸出:undefined
				};
				setTimeout(this.method, 500);
				}
				new Foo();
			
注意: setTimeout 的第一個參數是 函數對象 ,一個常犯的錯誤是這樣的 setTimeout(foo(), 1000) , 這里回調函數是 foo返回值 ,而 不是 foo 本身。 大部分情況下,這是一個潛在的錯誤,因為如果函數返回 undefinedsetTimeout不會 報錯。

setInterval 的堆調用

setTimeout 只會執行回調函數一次,不過 setInterval – 正如名字建議的 – 會每隔 X 毫秒執行函數一次。 但是卻不鼓勵使用這個函數。

當回調函數的執行被阻塞時, setInterval 仍然會發布更多的回調指令。在很小的定時間隔情況下,這會導致回調函數被堆積起來。

				function foo(){
				// 阻塞執行 1 秒
				}
				setInterval(foo, 1000);
			

上面代碼中, foo 會執行一次隨后被阻塞了一分鐘。

foo 被阻塞的時候, setInterval 仍然在組織將來對回調函數的調用。 因此,當第一次 foo 函數調用結束時,已經有 10 次函數調用在等待執行。

處理可能的阻塞調用

最簡單也是最容易控制的方案,是在回調函數內部使用 setTimeout 函數。

				function foo(){
				// 阻塞執行 1 秒
				setTimeout(foo, 1000);
				}
				foo();
			

這樣不僅封裝了 setTimeout 回調函數,而且阻止了調用指令的堆積,可以有更多的控制。 foo 函數現在可以控制是否繼續執行還是終止執行。

手工清空定時器

可以通過將定時時產生的 ID 標識傳遞給 clearTimeout 或者 clearInterval 函數來清除定時, 至于使用哪個函數取決于調用的時候使用的是 setTimeout 還是 setInterval

				var id = setTimeout(foo, 1000);
				clearTimeout(id);
			

清除所有定時器

由于沒有內置的清除所有定時器的方法,可以采用一種暴力的方式來達到這一目的。

				// 清空"所有"的定時器
				for(var i = 1; i < 1000; i++) {
				clearTimeout(i);
				}
			

可能還有些定時器不會在上面代碼中被清除( 譯者注 : 如果定時器調用時返回的 ID 值大于 1000), 因此我們可以事先保存所有的定時器 ID,然后一把清除。

隱藏使用 eval

setTimeoutsetInterval 也接受第一個參數為字符串的情況。 這個特性 絕對 不要使用,因為它在內部使用了 eval

注意: 由于定時器函數不是 ECMAScript 的標準,如何解析字符串參數在不同的 JavaScript 引擎實現中可能不同。 事實上,微軟的 JScript 會使用 Function 構造函數來代替 eval 的使用。
				function foo() {
				// 將會被調用
				}
				function bar() {
				function foo() {
				// 不會被調用
				}
				setTimeout('foo()', 1000);
				}
				bar();
			

由于 eval 在這種情況下不是被 直接 調用,因此傳遞到 setTimeout 的字符串會自 全局作用域 中執行; 因此,上面的回調函數使用的不是定義在 bar 作用域中的局部變量 foo

建議 不要 在調用定時器函數時,為了向回調函數傳遞參數而使用字符串的形式。

				function foo(a, b, c) {}
				// 不要這樣做
				setTimeout('foo(1,2, 3)', 1000)
				// 可以使用匿名函數完成相同功能
				setTimeout(function() {
				foo(a, b, c);
				}, 1000)
			
注意: 雖然也可以使用這樣的語法 setTimeout(foo, 1000, a, b, c) , 但是不推薦這么做,因為在使用對象的 屬性方法 時可能會出錯。 ( 譯者注: 這里說的是屬性方法內, this 的指向錯誤)

結論

絕對不要 使用字符串作為 setTimeout 或者 setInterval 的第一個參數, 這么寫的代碼明顯質量很差。當需要向回調函數傳遞參數時,可以創建一個 匿名函數 ,在函數內執行真實的回調函數。

另外,應該避免使用 setInterval ,因為它的定時執行不會被 JavaScript 阻塞。

本文被轉載1次

首發媒體 Web前端開發 | 轉發媒體

隨意打賞

提交建議
微信掃一掃,分享給好友吧。
主站蜘蛛池模板: 久久乐国产综合亚洲精品 | 亚洲精品高清在线 | 开心久久婷婷综合中文字幕 | 麻豆亚洲精品一区二区 | 中文字幕一区二区三区免费视频 | 天天爽天天操 | 国产精品久久久视频 | 亚洲成人在线视频播放 | 欧美一区二区在线观看免费网站 | 999精品在线| 欧美激情(一区二区三区) | 久久久久久久综合色一本 | 最好看的毛片 | 国产区精品福利在线观看精品 | 日韩二区 | 狠干在线 | 全免费午夜一级毛片真人 | 青青草久草视频 | 男人的天堂在线精品视频 | 亚洲精品中文字幕乱码三区一二 | 亚洲国产精品成人久久 | 色狠狠色综合久久8狠狠色 色狠狠婷婷97 | 久久艹在线观看 | 精品国产一区二区三区四区色 | 四虎影视永久免费 | 色网站视频| 国产成人免费观看 | 日韩欧美国产综合 | 免费视频精品一区二区三区 | 无毒不卡在线播放 | 成人a大片高清在线观看 | 欧美性禁片在线观看 | 国产极品福利 | 99久久国产综合色 | 国产亚洲精aa在线观看不卡 | 国产成人a毛片在线 | 久久er国产精品免费观看1 | 欧美激情一区二区三区中文字幕 | 黄视频福利| 特级毛片aaaa级毛片免费 | 国产免费爱在线观看视频 |