JavaScript 基本功--面試寶典

JavaScript數據類型

JavaScript中有哪些基本數據類型

undefinednullnumberstringbooleansymbol(es6中新增)
爲啥沒有object、array、function?他們都屬於複雜的數據類型。看起來有點咬文嚼字。es6

typeof 操做符對各個數據類型的操做結果

string-------------------------string
number-------------------------number
boolean------------------------boolean
function-----------------------function
undefined----------------------undefined
null---------------------------object (null值表示一個空對象指針)
array--------------------------object
object-------------------------object
所以,有些時候typeof並不能準確的判斷某個變量的數據類型。segmentfault

如何區分null和undefined

經過上邊能夠看出,使用typeof就能夠判斷區null和undefined了。
還能夠經過null === undefined這種方式來判斷。瀏覽器

如何準確的判斷一個變量的數據類型

JavaScript 中全部變量均可以看成對象使用,除了 null 和 undefined 兩個例外。因此咱們可使用對象原型鏈上的toString方法來將一個變量轉化成字符串,而後區分他們的類型。
Object.prototype.toString.call(*);示例:閉包

Object.prototype.toString.call(null)           //  "[object Null]"
Object.prototype.toString.call(undefined)      //  "[object Undefined]"

*在IE8中二者結果都爲 "[object Object]"
所以,咱們也能夠用這個方法來區分null和undefined異步

對象建立和使用

建立對象函數

var obj1 = {x:1,'long name':2};
var obj2 = new Object();
var obj3 = Object.create(obj2);

訪問對象屬性this

obj1.x                // 1
obj1["long name"]     // 2 注意,若是屬性名有空格或者中劃線什麼的就只能使用這種方式了

刪除對象屬性prototype

delete obj1.x         // 刪除對象屬性的惟一方法是delete

繼承與原型鏈

前邊咱們說了,能夠認爲 JavaScript 中萬物皆對象。每一個對象都有一個私有 Prototype。它持有一個鏈接到另外一個稱爲其 prototype 對象(原型對象)的連接。該 prototype 對象又具備一個本身的原型,層層向上直到一個對象的原型爲 null。
繼承
上邊建立對象以及能夠看到使用 Object.create 能夠實現繼承。還有可使用Object.prototype來實現繼承。示例:指針

var obj = {a:1}
function P(name){    // 構造函數
    this.name = name
}
P.prototype = obj  // 繼承obj
var p = new P('wesley');     // 實例對象
p.a                  // 1

其次,咱們還可使用es6中的新語法class等關鍵字來實現繼承。
原型鏈
原型鏈的定義複雜拗口,咱們能夠經過 JavaScript 的非標準但許多瀏覽器實現的屬性__proto__來理解原型鏈。
對象的__proto__屬性是該對象的構造函數的prototype屬性。基於上邊構造函數繼承代碼:code

console.log(p.__proto__ === P.prototype)                       // true
console.log(P.prototype === obj)                               // true
console.log(P.prototype.__proto__ === Object.prototype)        // true
console.log(Object.prototype.__proto__ === null)               // true

做用域與命名空間

若是瞭解es6的let用法,那麼就應該只要 JavaScript 有塊級做用域和函數做用域。簡單來講一般咱們使用var建立的變量都屬於函數做用域。
什麼是塊級做用域呢?其實能夠簡單理解爲一對花括號包圍的代碼塊的做用範圍內。
JavaScript 中沒有顯式的命名空間定義,這就意味着全部對象都定義在一個全局共享的命名空間下面。
每次引用一個變量,JavaScript 會向上遍歷整個做用域直到找到這個變量爲止。 若是到達全局做用域可是這個變量仍未找到,則會拋出 ReferenceError 異常。
隱式的全局變量

foo1 = 1;
var foo2 = 2;   // 若是是在函數內部  就是局部變量
let foo3 = 3;   // 若是是在代碼塊內  就是局部變量

能夠經過以下代碼的執行結果來理解let和var

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

若是使用let

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

變量聲明提高
var 表達式和 function 聲明都將會被提高到當前做用域的頂部。要注意的是 let 表達式並不會被提高。
這也正好能夠說明以下代碼能夠正常執行:

test();
function test(){
    console.log(a)
    var a = 5;
}

能夠理解爲提高後的代碼:

function test(){
  var a;  // 此時a爲undefined  因此咱們打印的時候就是undefined了
  console.log(a)
  a = 5;
}
test();

不使用var申明的變量提高示例:

test();
function test(){
  b = 5
}
console.log(b)
// 5

能夠理解爲提高後:

var b;  // undefined
(function test(){
  b = 5
})()
console.log(b)

閉包

閉包是 JavaScript 一個很是重要的特性,這意味着當前做用域老是可以訪問外部做用域中的變量。
能夠理解爲訪問你本不可以訪問到的東西,就是一個閉包。示例:

function Counter(start) {
    var count = start;
    return {
        increment: function() {
            count++;
        },

        get: function() {
            return count;
        }
    }
}

var foo = Counter(4);   // 此時若是咱們在外部直接 console.log(count) 是會拋錯的
foo.increment();
foo.get(); // 5

這裏,Counter 函數返回兩個閉包,函數 increment 和函數 get。這兩個函數都維持着對 Counter 函數內部做用域的引用。
因此若是須要訪問或者說獲取Counter中的變量count,只能經過閉包的方式。
關於閉包,有個很經典的例子:

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
// 10個10

*想一想,爲何。具體能夠看:https://segmentfault.com/a/11...
setTimeout 和 setInterval
因爲 JavaScript 是異步的,可使用 setTimeoutsetInterval 來計劃執行函數。
*注意: 定時處理不是 ECMAScript 的標準,它們在 DOM (文檔對象模型) 被實現。

function foo() {}
var id = setTimeout(foo, 1000); // 返回一個大於零的數字

當 setTimeout 被調用時,它會返回一個 ID 標識而且計劃在未來大約 1000 毫秒後調用 foo 函數。 foo 函數只會被執行一次。因此,一般咱們能夠認爲被setTimeout執行的函數是會被異步執行的。

相關文章
相關標籤/搜索