這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1. 代碼輸出結果 (function(){ var x = y = 1; })(); var z; console.log(y); // 1 console.log(z); // undefined console.log(x); // ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
1. 代碼輸出結果
(function(){ var x = y = 1; })(); var z; console.log(y); // 1 console.log(z); // undefined console.log(x); // Uncaught ReferenceError: x is not defined
這段代碼的關鍵在於:var x = y = 1; 實際上這裡是從右往左執行的,首先執行y = 1, 因為y沒有使用var聲明,所以它是一個全局變數,然後第二步是將y賦值給x,講一個全局變數賦值給了一個局部變數,最終,x是一個局部變數,y是一個全局變數,所以列印x是報錯。
2. 代碼輸出結果
var a, b (function () { console.log(a); console.log(b); var a = (b = 3); console.log(a); console.log(b); })() console.log(a); console.log(b);
輸出結果:
undefined undefined 3 3 undefined 3
這個題目和上面題目考察的知識點類似,b賦值為3,b此時是一個全局變數,而將3賦值給a,a是一個局部變數,所以最後列印的時候,a仍舊是undefined。
3. 代碼輸出結果
var friendName = 'World'; (function() { if (typeof friendName === 'undefined') { var friendName = 'Jack'; console.log('Goodbye ' + friendName); } else { console.log('Hello ' + friendName); } })();
輸出結果:Goodbye Jack
我們知道,在 JavaScript中, Function 和 var 都會被提升(變數提升),所以上面的代碼就相當於:
var name = 'World!'; (function () { var name; if (typeof name === 'undefined') { name = 'Jack'; console.log('Goodbye ' + name); } else { console.log('Hello ' + name); } })();
這樣,答案就一目瞭然了。
4. 代碼輸出結果
function fn1(){ console.log('fn1') } var fn2 fn1() fn2() fn2 = function() { console.log('fn2') } fn2()
輸出結果:
fn1 Uncaught TypeError: fn2 is not a function fn2
這裡也是在考察變數提升,關鍵在於第一個fn2(),這時fn2仍是一個undefined的變數,所以會報錯fn2不是一個函數。
5. 代碼輸出結果
function a() { var temp = 10; function b() { console.log(temp); // 10 } b(); } a(); function a() { var temp = 10; b(); } function b() { console.log(temp); // 報錯 Uncaught ReferenceError: temp is not defined } a();
在上面的兩段代碼中,第一段是可以正常輸出,這個應該沒啥問題,關鍵在於第二段代碼,它會報錯Uncaught ReferenceError: temp is not defined。這時因為在b方法執行時,temp 的值為undefined。
6. 代碼輸出結果
var a=3; function c(){ alert(a); } (function(){ var a=4; c(); })();
js中變數的作用域鏈與定義時的環境有關,與執行時無關。執行環境只會改變this、傳遞的參數、全局變數等
7. 代碼輸出問題
function fun(n, o) { console.log(o) return { fun: function(m){ return fun(m, n); } }; } var a = fun(0); a.fun(1); a.fun(2); a.fun(3); var b = fun(0).fun(1).fun(2).fun(3); var c = fun(0).fun(1); c.fun(2); c.fun(3);
輸出結果:
undefined 0 0 0 undefined 0 1 2 undefined 0 1 1
這是一道關於閉包的題目,對於fun方法,調用之後返回的是一個對象。我們知道,當調用函數的時候傳入的實參比函數聲明時指定的形參個數要少,剩下的形參都將設置為undefined值。所以 console.log(o);
會輸出undefined。而a就是是fun(0)返回的那個對象。也就是說,函數fun中參數 n 的值是0,而返回的那個對象中,需要一個參數n,而這個對象的作用域中沒有n,它就繼續沿著作用域向上一級的作用域中尋找n,最後在函數fun中找到了n,n的值是0。瞭解了這一點,其他運算就很簡單了,以此類推。
8. 代碼輸出結果
f = function() {return true;}; g = function() {return false;}; (function() { if (g() && [] == ![]) { f = function f() {return false;}; function g() {return true;} } })(); console.log(f());
輸出結果: false
這裡首先定義了兩個變數f和g,我們知道變數是可以重新賦值的。後面是一個匿名自執行函數,在 if 條件中調用了函數 g(),由於在匿名函數中,又重新定義了函數g,就覆蓋了外部定義的變數g,所以,這裡調用的是內部函數 g 方法,返回為 true。第一個條件通過,進入第二個條件。
第二個條件是[] == ![],先看 ![] ,在 JavaScript 中,當用於布爾運算時,比如在這裡,對象的非空引用被視為 true,空引用 null 則被視為 false。由於這裡不是一個 null, 而是一個沒有元素的數組,所以 [] 被視為 true, 而 ![] 的結果就是 false 了。當一個布爾值參與到條件運算的時候,true 會被看作 1, 而 false 會被看作 0。現在條件變成了 [] == 0 的問題了,當一個對象參與條件比較的時候,它會被求值,求值的結果是數組成為一個字元串,[] 的結果就是 '' ,而 '' 會被當作 0 ,所以,條件成立。
兩個條件都成立,所以會執行條件中的代碼, f 在定義是沒有使用var,所以他是一個全局變數。因此,這裡會通過閉包訪問到外部的變數 f, 重新賦值,現在執行 f 函數返回值已經成為 false 了。而 g 則不會有這個問題,這裡是一個函數內定義的 g,不會影響到外部的 g 函數。所以最後的結果就是 false。