摘要:總之,在的時候盡量不要用字符串的參數(shù),因為具有許多不可預見的危險性,比如說可能有意外的運行結(jié)果可能隱式創(chuàng)建全局變量,閉包作用域解析過多消耗,,運行慢啊巴拉巴拉之類的。但是我們也需要了解下的一些黑魔法,以防到時候懵逼。
題目為什么叫setTimeout的第一個參數(shù)而不是回調(diào)函數(shù)?如果你心中有稍有疑惑,或許應該看看下面的文章
我們?nèi)粘J褂胹etTimeout(),一般是將函數(shù)作為第一個參數(shù),但是也有例外情況,先看以下代碼:
function test() { ? var cl = function() { ? ? console.log(666) ? } ? setTimeout("cl()", 1500) } test()
將以上代碼CV到chrome中的console,運行發(fā)現(xiàn):
Uncaught ReferenceError: cl is not defined
沒有定義cl函數(shù),奇怪是并沒有報Uncaught SyntaxError: Unexpected identifier這樣的語法錯誤,查javascript MDN我們就會發(fā)現(xiàn):
setTimeout允許講一個字符串作為第一個參數(shù),而且js內(nèi)部將會調(diào)用eval()函數(shù)用來動態(tài)執(zhí)行一段字符串腳本,至于為什么找不到cl函數(shù),我們猜想是作用域問題,既然是eval動態(tài)執(zhí)行,我們在字符串參數(shù)中輸出當前this綁定的對象:
function test() { ? var cl = function() { ? ? console.log(666) ? } ? setTimeout("console.log(this);cl()", 1500) } test()
執(zhí)行后發(fā)現(xiàn):
原來this綁定window全局對象,這下明白了,eval()執(zhí)行動態(tài)腳本的時候,在全局作用域并沒有找到我們定義在函數(shù)test內(nèi)部的cl,所以會報錯。
我們將cl定義移到外部:
ok了
————分割線————
var cl = function() {console.log(666)} setTimeout(cl(), 1500)
經(jīng)??吹接行氯嗽谏鐓^(qū)上問這段代碼為什么沒有延遲執(zhí)行,只需注意這邊的cl()是一個函數(shù)執(zhí)行而不是函數(shù)定義,如果想延遲執(zhí)行,我們需要傳遞一個函數(shù)地址,比如:
var cl = function() {console.log(666)} setTimeout(cl, 1500)
或者直接return一個函數(shù):
var cl = function() { return function() { console.log(666) } } setTimeout(cl(), 1500)
又或者參數(shù)處直接定義:
setTimeout(function() {console.log(666)}, 1500)
歸根結(jié)底還是搞清引用函數(shù)地址和執(zhí)行函數(shù)的區(qū)別
————分割線————
以上規(guī)則也同樣適用于字符串參數(shù),只是字符串參數(shù)中要加上()保證eval的時候執(zhí)行,不要到時候只是eval了一個地址 =。=,比如這樣:
var cl = function() { ? ? console.log(666) ? } function test() { ? setTimeout("cl", 1500) } test()
執(zhí)行一下,啥屁也沒看到 = 。=
總之,在setTimeout的時候盡量不要用字符串的參數(shù),因為eval()具有許多不可預見的危險性,比如說可能有意外的運行結(jié)果,可能隱式創(chuàng)建全局變量,閉包作用域解析過多消耗,xss,運行慢啊巴拉巴拉之類的。但是我們也需要了解下js的一些黑魔法,以防到時候懵逼。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/86890.html
摘要:閉包閉包是指有權訪問另一個函數(shù)作用域中的變量的函數(shù)當某個函數(shù)被調(diào)用時,會創(chuàng)建一個執(zhí)行環(huán)境及相應的作用域鏈。要注意通過第句聲明的這個方法屬于構(gòu)造函數(shù)生成的對象,而不屬于構(gòu)造函數(shù)的變量對象,也就是說,并不存在于作用域鏈中。 看到評論里有仁兄建議我試試箭頭函數(shù),真是受寵若驚,本來寫這篇文章也只是想記錄寫要點給自己日后看的。今天早上看到一篇總結(jié)javascript中this的文章JavaScr...
摘要:瀏覽器是多進程的,而瀏覽器的內(nèi)核渲染進程是多線程的。如果已經(jīng)將回調(diào)函數(shù)放進任務隊列,但是主線程正在執(zhí)行一個非常耗時的任務,當這個任務執(zhí)行完畢后,主線程去任務隊列中取任務,這個時候,就會出現(xiàn)連續(xù)執(zhí)行的情況,也就是說相當于失效了。 前言 ??在刷筆試題的時候,經(jīng)常會碰到setTimeout的問題,只知道這個是設置定時器;但是考察的重點一般是在一個方法中包含了定時器,定時器中的打印和方法中打...
摘要:不單單是因為引起的。用與要注意的地方這里要注意的是這二個函數(shù)的第一個參數(shù)都會把指向還有第一個參數(shù)可以為但不要這樣用因為這樣等于自己隱式使用了。 自動分號插入 Js不像其他語言強制要求;號結(jié)尾不然編譯不過,原因是JS有自動;號的插入。 var text=function(){} text() 這樣你不加;號也能運行其實在內(nèi)部js是需要;號去幫助解析的 var text=function(...
摘要:執(zhí)行,輸出,宏任務執(zhí)行結(jié)束。到此為止,第一輪事件循環(huán)結(jié)束。參考入門阮一峰系列之我們來聊聊一道關于應用的面試題阿里前端測試題關于中函數(shù)的理解與應用這一次,徹底弄懂執(zhí)行機制一個面試題原生的所有方法介紹附一道應用場景題目異步流程控制 說明 最近在復習 Promise 的知識,所以就做了一些題,這里挑出幾道題,大家一起看看吧。 題目一 const promise = new Promise((...
摘要:是一種異步編程的解決方案相比傳統(tǒng)回調(diào)函數(shù)更合理立即執(zhí)行性立即執(zhí)行返回成功后執(zhí)行控制臺輸出立即執(zhí)行后執(zhí)行返回成功對象表示未來發(fā)生的事件在創(chuàng)建時作為參數(shù)傳入的函數(shù)是會被立即執(zhí)行的只是其中執(zhí)行的代碼可以是異步代碼有些人會認為當對象調(diào)用方法時接受的 Promise是一種異步編程的解決方案,相比傳統(tǒng)回調(diào)函數(shù)更合理. 1.Promise立即執(zhí)行性 let p = new Promise((reso...
閱讀 1533·2023-04-25 16:31
閱讀 2113·2021-11-24 10:33
閱讀 2806·2021-09-23 11:33
閱讀 2620·2021-09-23 11:31
閱讀 3025·2021-09-08 09:45
閱讀 2413·2021-09-06 15:02
閱讀 2730·2019-08-30 14:21
閱讀 2385·2019-08-30 12:56