你真的知道JS嗎?

你真的知道JavaScript嗎

    JavaScript是一門奇怪的語言,要真正掌握並不容易。廢話很少說,來一個快速測試,5道題目,看看你對JavaScript是否真正掌握。準備好了嗎?開始咯?javascript

題目

No.1

if (!("a" in window)) {
    var a = 1;
}

console.log(a);

No.2

var a = 1,
    b = function a(x) {
        x && a(--x);
    };
console.log(a);

No.3

function a(x) {
    return x * 2;
}
var a;
console.log(a);

No.4

function b(x, y, a) {
    arguments[2] = 10;
    console.log(a);
}
b(1, 2, 3);

No.5

function a() {
    console.log(this);
}
a.call(null);

解析

No.1

    在瀏覽器環境中,全局變量都是window的一個屬性,即
var a = 1 等價於 window.a = 1in操做符用來判斷某個屬性屬於某個對象,能夠是對象的直接屬性,也能夠是經過prototype繼承的屬性。
    再看題目,在瀏覽器中,若是沒有全局變量 a ,則聲明一個全局變量 a (ES5沒有塊級做用域),而且賦值爲1。不少人會認爲打印的是1。非也,你們不要忘了變量聲明會被前置!什麼意思呢?題目也就等價於前端

var a;

if (!("a" in window)) {
    a = 1;
}

console.log(a);

因此其實已經聲明瞭變量a,只不過if語句以前值是undefined,因此if語句壓根不會執行。
最後答案就是 undefinedjava

No.2

這道題有幾個須要注意的地方:git

  1. 變量聲明、函數聲明會被前置,可是函數表達式並不會,準確說相似變量聲明前置,舉個栗子: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

No.3

函數聲明會覆蓋變量聲明,但不會覆蓋變量賦值,舉個栗子簡單粗暴:函數

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) {...}

No.4

這題考察 arguments 對象的用法(詳看?JavaScript中的arguments對象)
通常狀況arguments與函數參數是動態綁定關係(爲何說是通常稍後會解釋),因此很好理解,最後輸出的是10

可是可是可是,咱們不要忘了一個特殊狀況--嚴格模式,在嚴格模式中 arguments 與至關於函數參數的一個拷貝,並無動態綁定關係,舉個栗子:

'use strict'
// 嚴格模式!!

function b(x, y, a) {
    arguments[2] = 10;
    console.log(a);
}
b(1, 2, 3); // 3

No.5

function a() {
    console.log(this);
}
a.call(null);

關於 a.call(null); 根據ECMAScript262規範規定:
若是第一個參數傳入的對象調用者是null或者undefined的話,call方法將把全局對象(瀏覽器上是window對象)做爲this的值。因此,無論你何時傳入null或者 undefined,其this都是全局對象window。因此,在瀏覽器上答案是輸出 window 對象。

可是可是可是,咱們依舊不能忘記一個特殊狀況--嚴格模式,在嚴格模式中,null 就是 nullundefined 就是 undefined ,舉個栗子:

'use strict';
// 嚴格模式!!

function a() {
    console.log(this);
}
a.call(null); // null
a.call(undefined); // undefined

提醒

  1. 在瀏覽器中的全局對象是window,Node.js中是global;

  2. 爲了使代碼更加嚴謹與健壯,建議寫JS都加上嚴格模式'use strict';

  3. ES6已經成爲前端必備技能,呼籲你們都使用ES6,方便高效,可使用babel把ES6轉成ES5甚至ES3,儘可能使用ES6推進前端的發展?

About

GitHub: ?https://github.com/microzz
我的網站: ?https://microzz.com/

相關文章
相關標籤/搜索