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