Javascript 容易忽視的文法點__Java

來源:互聯網
上載者:User
使用 typeof bar === “object” 判斷 bar 是不是一個對象有何潛在的弊端。如何避免這種弊端。
    var arr = [];    var obj = {};    var nl  =  null;    console.log(typeof arr === 'object'); //true    console.log(typeof obj === 'object'); //true    console.log(typeof nl  === 'object'); //true// 從上面的輸出結果可知, 使用 typeof 並不能準確判斷 bar 就是一個 Object。// 可以通過 Object.prototype.toString.call(bar) === "[object Object]" 來避免這種弊端:    console.log(Object.prototype.toString.apply(arr));     //[object Array]    console.log(Object.prototype.toString.apply(obj));    //[object Object]    console.log(Object.prototype.toString.apply(nl));    // [object Null]
另外,在控制台檢查會發現, if([])  {    console.log('[] is true')  }  點擊Enter鍵[] is trueundefined[]==true  點擊Enter鍵false[]===true 點擊Enter鍵false[]==false   點擊Enter鍵true ([]和 false值相同 )[]===false  點擊Enter鍵false ([]和 false類型不相同,===三個等號表示值和類型都相同)[object Array] VS [object Boolean]

2.下面的代碼會在 console 輸出神馬。為什麼。

(function(){ var a = b = 3;})();console.log("a defined? " + (typeof a !== 'undefined')); console.log("b defined? " + (typeof b !== 'undefined'));
    // 函數所建立的範圍中的局部變數,JS中只有函數可以建立作用。    // JS不存在塊級範圍    // JS中是詞法範圍(與之對立的為動態範圍),在代碼寫好的那一刻,範圍就已經確定了    // 詞法範圍的規則:    // 函數允許訪問函數外的資料    // 如果當前範圍中有了該變數,就不考慮外面的同名變數    (function() {        var a = b = 3;        // 這一句等價於:        // b = 3;     全域變數        // var a = b;     })();    console.log(a); //  Uncaught ReferenceError: a is not defined  報錯後,後面的不執行,要想後面代碼執行,需要屏蔽這一句。    console.log(typeof a); // undefined    console.log(b); //3    console.log("a defined? " + (typeof a !== 'undefined')); //false    console.log("b defined? " + (typeof b !== 'undefined'));    // true

3.下面的代碼會在 console 輸出神馬。為什麼。

    var myObject = {        foo: "bar",        func: function() {            var self = this;            console.log("outer func: this.foo = " + this.foo);            console.log("outer func: self.foo = " + self.foo);            (function() {                console.log("inner func: this.foo = " + this.foo);                console.log("inner func: self.foo = " + self.foo);            }());        }    };    myObject.func();

我們在sublime中寫出來,實踐出真知:

    var myObject = {        foo: "bar",        func: function() {            var self = this;             //self指的是myObject對象            console.log(this);             //這裡的this指的是myObject對象            console.log("outer func: this.foo = " + this.foo);            // bar 。。            console.log("outer func: self.foo = " + self.foo);            // bar            (function() {                console.log(this);//這裡的this指window                console.log(self); //self就是myObject                console.log("inner func: this.foo = " + this.foo);                // undefined window上是沒有foo屬性的                console.log("inner func: self.foo = " + self.foo);                // bar            }());        }    };    myObject.func();第一個和第二個的輸出不難判斷,self和this都是指的調用func的對象myObject,所以列印結果都是bar。對於第三個,因為 this (指的是window)在可訪問到的範圍內是 undefined,第四個輸出是 undefined。在 ES6 之前,JavaScript 只有函數範圍,所以 func 中的 IIFE 有自己的獨立範圍,並且它能訪問到外部範圍中的 self,所以第四個列印也是bar。

如果你知道閉包,下面的內容也是很好理解的:

    var myObject = {        foo: "bar",        func: function() {            var self = this;            (function(test) {                // 當myObject.func();執行完畢後,下面的IIFE等於放在最外層執行,此時的this指的是window                console.log("inner func: this.foo = " + this.foo); //'bar'                // 這裡實參傳遞給形參等價於下面兩行代碼                // var test;                // test = self;                console.log(self); //self就是myObject                console.log(test); //test就是self也即myObject                console.log("inner func: this.foo = " + test.foo); //'bar'                console.log("inner func: self.foo = " + self.foo);            }(self));        }    };    myObject.func();

4.將 JavaScript 程式碼封裝含在一個函數塊中有什麼意思呢。為什麼要這麼做。
這個問題其實就是看你是否掌握了閉包,關於閉包我打算專門寫一篇博文,這個問題也可以理解為,IIFE的作用是什麼
IIFE即是: 立即執行函數運算式(Immediately-Invoked Function Expression)
先看下下面這段代碼:

    for(var i =0;i<6;i++){        setTimeout(function(){            console.log(i);        }, 1000);    }列印結果是什麼呢。六個6很經典的一個問題:所有的主任務的代碼執行完畢之後,去檢查所有的setTimeout回呼函數,如果到時間了就執行,此時i已經變為6了。可以用閉包來解決這個問題,關於閉包,我總結了三個關於閉包的特點,其實不用看我的總結,只要你觀察下閉包,基本上也就是這三個特點:    // 1.IIFE    // 2.函數裡面的內容不會立即執行,調用的時候(時間到了或者使用者點擊的時候)才會執行    // 3.1 函數裡面內容雖然不會立即執行,如果再每次迴圈階段(預解析階段)把值以函數參數的形式傳進去之後,在函數執行階段,用的就是當時傳進去的值    // 3.2 函數裡面內容雖然不會立即執行,如果在內層作為傳回值return出來的函數中,定義一個變數,引用了外層的變數,那麼執行階段,用的就是預解析階段引用的值   好,我們看下鋼材那個問題,如果想要輸出0,1,2,3,4,5該怎麼改寫代碼       for (var i = 0; i < 6; i++) {        function foo(j) {            return function() { /第2條                console.log(j);            }        }        var f = foo(i); //第1條  第3.1條(至於第3.2條,等我專門寫閉包了再講吧)        setTimeout(f, 1000);    }好了上面是IIFE的第一個常用之處。---------- 另外 JQuery/Node 的外掛程式和模組開發中,為避免變數汙染,也是一個大大的 IIFE:(function($) {  //代碼 } )(jQuery);而不是直接的function(){    jQuery...}

5.下面兩個函數的傳回值是一樣的嗎。為什麼。

    function foo1() {        return {            bar: "hello"        };    }    function foo2() {        return  //這裡換行        {            bar: "hello"        };    }    var o1 = foo1();    var o2 = foo2();    console.log(o1.bar); //hello    console.log(o2.bar); //Uncaught TypeError: Cannot read property 'bar' of undefined在程式設計語言中,基本都是使用分號(;)將語句分隔開,這可以增加代碼的可讀性和整潔性。而在JS中,如若語句各占獨立一行,通常可以省略語句間的分號(;),JS 解析器會根據能否正常編譯來決定是否自動填滿分號:var test = 1 + 2console.log(test); //3在上述情況下,為了正確解析代碼,就不會自動填滿分號了,但是對於 return 、break、continue 等語句,如果後面緊跟換行,解析器一定會自動在後面填充分號(;),所以第二個函數報錯,第二段代碼等價於:    function foo2() {        return;  //這裡換行        {            bar: "hello"        };    }

6.神馬是 NaN,它的類型是神馬。怎麼測試一個值是否等於 NaN?

NaN 是 Not a Number 的縮寫,JavaScript 的一種特殊數值,可以通過 isNaN(param) 來判斷一個值是否是 NaN:console.log(isNaN(NaN));       // trueconsole.log(isNaN(123));       // falseconsole.log(isNaN("1111"));    // falseconsole.log(isNaN("1asd"));    // trueconsole.log(isNaN("asdaa222"));//  trueconsole.log(isNaN("'ssss'"));  //  trueconsole.log(isNaN==isNaN);     //  trueconsole.log(isNaN===isNaN);    //  trueconsole.log(Object.prototype.toString.apply(isNaN));//  [object Function]console.log(Object.prototype.toString.call(isNaN)); // [object Function]console.log(typeof isNaN)  // function

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.