JavaScript是一門奇怪的語言,要真正掌握並不容易。廢話很少說,來一個快速測試,5道題目,看看你對JavaScript是否真正掌握。準備好了嗎?開始咯?javascript
if (!("a" in window)) { var a = 1; } console.log(a);
var a = 1, b = function a(x) { x && a(--x); }; console.log(a);
function a(x) { return x * 2; } var a; console.log(a);
function b(x, y, a) { arguments[2] = 10; console.log(a); } b(1, 2, 3);
function a() { console.log(this); } a.call(null);
在瀏覽器環境中,全局變量都是window
的一個屬性,即var a = 1
等價於 window.a = 1
。in
操做符用來判斷某個屬性屬於某個對象,能夠是對象的直接屬性,也能夠是經過prototype
繼承的屬性。
再看題目,在瀏覽器中,若是沒有全局變量 a
,則聲明一個全局變量 a
(ES5沒有塊級做用域),而且賦值爲1。不少人會認爲打印的是1。非也,你們不要忘了變量聲明會被前置!什麼意思呢?題目也就等價於前端
var a; if (!("a" in window)) { a = 1; } console.log(a);
因此其實已經聲明瞭變量a
,只不過if
語句以前值是undefined
,因此if
語句壓根不會執行。
最後答案就是 undefined
java
這道題有幾個須要注意的地方:git
變量聲明、函數聲明會被前置,可是函數表達式並不會,準確說相似變量聲明前置,舉個栗子:github
console.log('b', b); // b undefined var b = function() {} console.log('b', b); // b function () {}
2.具名的函數表達式的名字只能在該函數內部取到,舉個例子(排除老的IE?):瀏覽器
var foo = function bar () {} console.log('foo', foo); // foo function bar(){} console.log('bar', bar); // Uncaught ReferenceError: bar is not defined
綜合這兩點,再看題目,最後輸出的內容就爲 1babel
函數聲明會覆蓋變量聲明,但不會覆蓋變量賦值,舉個栗子簡單粗暴:函數
function foo(){ return 1; } var foo; console.log(typeof foo); // "function"
函數聲明的優先級高於變量聲明的優先級,但若是該變量foo
賦值了,那結果就徹底不同了:測試
function foo(){ return 1; } var foo = 1; console.log(typeof foo); // "number"
變量foo
賦值之後,變量賦值初始化就覆蓋了函數聲明。這個須要注意
再看題目網站
function a(x) { return x * 2; } var a; console.log(a); // function a(x) {...}
這題考察 arguments
對象的用法(詳看?JavaScript中的arguments對象)
通常狀況,arguments
與函數參數是動態綁定關係(爲何說是通常稍後會解釋),因此很好理解,最後輸出的是10
可是可是可是,咱們不要忘了一個特殊狀況--嚴格模式,在嚴格模式中 arguments
與至關於函數參數的一個拷貝,並無動態綁定關係,舉個栗子:
'use strict' // 嚴格模式!! function b(x, y, a) { arguments[2] = 10; console.log(a); } b(1, 2, 3); // 3
function a() { console.log(this); } a.call(null);
關於 a.call(null);
根據ECMAScript262規範規定:
若是第一個參數傳入的對象調用者是null
或者undefined
的話,call
方法將把全局對象(瀏覽器上是window
對象)做爲this的值。因此,無論你何時傳入null
或者 undefined
,其this
都是全局對象window
。因此,在瀏覽器上答案是輸出 window
對象。
可是可是可是,咱們依舊不能忘記一個特殊狀況--嚴格模式,在嚴格模式中,null
就是 null
,undefined
就是 undefined
,舉個栗子:
'use strict'; // 嚴格模式!! function a() { console.log(this); } a.call(null); // null a.call(undefined); // undefined
在瀏覽器中的全局對象是window
,Node.js中是global
;
爲了使代碼更加嚴謹與健壯,建議寫JS都加上嚴格模式'use strict';
ES6已經成爲前端必備技能,呼籲你們都使用ES6,方便高效,可使用babel把ES6轉成ES5甚至ES3,儘可能使用ES6推進前端的發展?
GitHub: ?https://github.com/microzz
我的網站: ?https://microzz.com/