js時間+函數+匿名函數,...

題目一數組

var test = function (x) {
    var y = new Date();            
    y = y.getMonth() + x;    
    return y.toString();
};
console.log(test(3));
console.log(x);
複製代碼

答案: 5 報錯 x is not function瀏覽器

解析:此題注意:getMonth()獲取到的是0-11 當前月份爲3月 getMonth() + 1 = 3; y.getMonth() = 2; x爲3,因此第一個結果爲5. 第二個由於x沒有定義,是形參因此報錯。bash

程序題時間數據結構

用js程序輸出今天的日期,以YYYY-MM-DD的方式,好比今天2019年1月1日,輸出2019-01-01。異步

function getTime(){
    var date = new Date();
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    var d = date.getDate();
    function addZero(num){
        return num >= 10 ? num : '0'+num;
    }
    return y + '-' + addZero(m) + '-' + addZero(d);
}
var res = getTime();
console.log(res);
複製代碼

js運行機制函數

js主要用途是與用戶互動和操做DOM。決定只能是單線程。假若有兩個線程,一個線程,一個線程在某個DOM節點添加內容,另外一個線程刪除了節點,瀏覽器應該以哪一個線程爲主?ui

單線程意味着全部的任務都須要排隊,前一個任務執行完才能執行後面一個任務。 全部的任務分爲兩種,一種是同步任務(在主線程上排隊執行的任務,前面的任務執行完才能執行後面的任務。)另外一種是異步任務(不進入主線程,而進入任務隊列的任務。)只有任務隊列通知主線程,某個異步任務能夠執行了,任務纔會進入主線程執行。this

同步任務在主線程上,造成一個執行棧。棧中的代碼調用各類外部API,加入各類事件spa

異步任務在任務隊列(先進先出的數據結構,排在前面的事件,優先被主線程讀取)上線程

任務隊列(click,load,回調函數,IO設備事件,還包括鼠標點擊,頁面滾動等事件)。還能夠放置定時事件

只要主線程空了,就會去讀取任務隊列。這個過程會不斷重複。

定時器:定時某些代碼多少時間後執行。也就是定時執行的代碼。

題目一

var arr = ['第一次輸出', '第二次輸出', '第三次輸出'];
for (var i = 0; i < arr.length; i++) {
    setTimeout(function () {
        console.log(arr[i]);
        //獲取數組中下標不存在的數,結果是undefined
    }, i * 2000)
}
複製代碼

答案:undefined

解析:

for循環在主線程內,setTimeout回調函數是異步方法,在任務隊列中,當i=0時,執行循環體代碼,setTimeout在任務隊列等待。i++, i = 1時,setTimeout在任務隊列等待,繼續i++,當i=2時,setTimeout在任務隊列等待,i++,i = 3時,arr.length爲3,不符合條件,循環結束,此時執行延遲的回調函數setTimeout,就會去讀取任務隊列裏的代碼。執行任務隊列裏的代碼setTimeout=>此時i爲3,arr[3]數組中沒有下標爲3的,因此打印3次undefined。打印時間分別爲0s,1s,2s。

題目2

for (var i = 1; i <= 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, 0);
}
複製代碼

答案:5個6

解析:for循環在主線程內,setTimeout回調函數是異步方法,在任務隊列中,當for循環結束後纔去執行任務隊列裏的代碼。此時有五個setTimeout方法等待在隊列中。i爲6.因此打印五個6.

題目3

for (var i = 1; i <= 5; i++) {
    if (i == 1) {
        setTimeout(function () {
            console.log(i);
        }, 0);
    }
};
複製代碼

答案: 6

解析:for循環在主線程內,setTimeout回調函數是異步方法,在任務隊列中,當for循環結束後纔去執行任務隊列裏的代碼。此時主線程有個判斷i爲1,那麼任務隊列裏只有一個回調函數在等待。for循環結束的時候i爲6。因此執行這一個setTimeout輸出i爲6.

什麼是回調函數?

一個函數被做爲參數傳遞給另一個函數。回調函數也叫回調模式。舉例:

$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});   
複製代碼
function() 函數做爲參數傳遞給click方法中

1.定義匿名函數做爲回調函數
function getFn(fn){
    console.log(111);
}
getFn(function(){
    console.log('我是匿名函數');
})
2.定義命名函數,做爲參數傳遞到另外一個函數中
function login(data){
    console.log(123);
}
一個接受兩個參數的函數,後面一個是回調函數。
function getInfo(options,callback){
    callback(options);
}
調用getInfo時,把login做爲一個參數傳遞給它。
getInfo({name:'admin',psw:'123'},login);

複製代碼

匿名函數

(function () { var a = b = 1; console.log(a); })()

console.log(a, b);

答案:1 報錯

解析: var a = 1; b = 1; a是局部變量,b是全局變量。若是在console.log(a,b)前打印b則爲1。而在外面打印a報錯

函數聲明和函數表達式區別

sum(1,2); //3
 function sum(x,y){
     alert(x+y);
}
複製代碼
ss(1,2); //報錯,顯示undefined is not a function
 var ss = function(x,y){
     alert(x+y);
 }
複製代碼

解析器會率先讀取函數聲明。而函數表達式,則必須等到解析器執行到它所在的代碼行,纔會真正的被解析。

深刻理解匿名函數

function(){
    //定義並當即調用
    //這是個函數表達式。最後的()表示當即調用這個函數。
})()
複製代碼
如下兩個都報錯
function foo(){ /* code */ }();

function foo(){ /* code */ }( 1 );
複製代碼

以上代碼要實現,必需要賦值。改爲如下兩種能夠

var aa = function(x){
    alert(x);
}(5);//5
複製代碼
(function(x){
    alert(x);
}(5))
複製代碼

自執行函數

即定義和調用合爲一體。

(function () { /* code */ } ()); // 推薦使用這個
(function () { /* code */ })(); // 可是這個也是能夠用的
複製代碼
var i = function () { return 10; } ();
true && function () { /* code */ } ();
0, function () { /* code */ } ();
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();
// 還有一個狀況,使用new關鍵字,也能夠用,但我不肯定它的效率
new function () { /* code */ }
new function () { /* code */ } () // 若是須要傳遞參數,只須要加上括弧()
複製代碼

單獨的匿名函數 會報錯 沒法運行 也沒法調用

function(){
    return 'lee';
}
複製代碼

經過表達式的自我執行

(function(){
    alert('lee');
})();
複製代碼

把匿名函數賦值給變量

var cat = function(){
    return 'lee';
}
alert(cat()); //調用
複製代碼

把匿名函數自我執行的返回值賦值給變量

var box = (function(){
    return 'lee';
})();
alert(box);
複製代碼

自我執行匿名函數的傳參

(function(num){
    alert(num);
})(100);
複製代碼

題目

var test = (function(a) {
  this.a = a;
  return function(b) {
      return this.a + b;
  }
} (function(a, b) {
  return a;
}(1, 2) ));

console.log(test(4));
複製代碼

答案:5

解析:

(function(a, b) {
  return a;
}(1, 2) )    => 1
複製代碼
var test = (function(a) {
  this.a = a;
  return function(b) {
      return this.a + b;
  }
} (1))

test => (function(a) {
  this.a = a;
  return function(b) {
      return this.a + b;
  }
} (1))

test() => function(b) {
      return this.a + b;
  }
  
test(4) => b = 4;  上面a = 1 ;  this.a + b = 5;

匿名函數自調用 this指向的window
複製代碼
相關文章
相關標籤/搜索