你可能不知道的JS

最近讀了Javascript Enlightenment。總體感受仍是比較基礎的。這裏記錄跟擴展下其中一些知識點。javascript

Math

JS裏有個不成文的規定,構造函數首字母大寫。因此可能容易讓人產生誤解Math是構造函數。其實Math只是一個簡單的封裝了不少數學相關方法的對象。java

console.log(typeof Math); //"object"
console.log(typeof Array); //"function"複製代碼

Function

構造一個函數實例有2種方法:git

  • 函數聲明
function sum(x, y) {
    return x + y;
}
console.log(sum(3,4)); //7複製代碼
  • 經過構造函數
let multiply = new Function("x", "y", "return x * y;");
console.log(multiply(3,4)); //12複製代碼

工做中常常會有須要用到call或者apply來切換函數執行上下文的狀況。例如:github

function print(){
    console.log(this.a);
}

print.call({a: 'hello'}); //hello複製代碼

有些面試題可能會問爲啥print上沒有定義call方法,可是print.call()調用爲啥不會報錯。實際上是由於print是Function的一個實例化對象,call方法定義在Function.prototype上,經過原型鏈查找到的call方法。面試

數組判斷

typeof能夠用來判斷基礎類型,沒法用typeof區分數組跟對象。數組

console.log(typeof [1,2]); //object
console.log(typeof {}); //object複製代碼

能夠有下面2種常見的方法區分數組:瀏覽器

  • 原生API: Array.isArray
console.log(Array.isArray([1,2])); //true複製代碼
  • toString
console.log(Object.prototype.toString.call([1,2])
            .toLowerCase() === '[object array]'); //true複製代碼

這裏注意下,咱們使用了toString方法,而後用call方法切換toString調用時的上下文爲咱們要進行判斷的數組。因此有些人會誤覺得Object.prototype.toString.call([1,2])跟 [1,2].toString()是等價的。其實否則:bash

console.log(Object.prototype.toString.call([1,2])); //[object Array]
console.log([1,2].toString()); //1,2複製代碼

這是由於原型鏈查找有個就近原則。因此當使用[1,2].toString的時候,查找到並被使用的是Array.prototype.toString,這個方法覆蓋了Object.prototype.toString。app

delete 操做符

delete只會刪除自身屬性。不會刪除原型鏈上的屬性。函數

let obj = {a: 'self'};
Object.prototype.a = 'prototype';
console.log(obj.a); //self
delete obj.a;
console.log(obj.a); //prototype
delete Object.prototype.a;
console.log(obj.a); //undefined複製代碼

全局對象

訪問全局對象有2種方法:

  • 變量方法: 瀏覽器裏用window, Node裏用global
  • 在全局做用域裏使用 this

當咱們訪問一個變量的時候會造成一個做用域鏈。做用域的頂端就是全局變量(i.e. 全局對象下的對應變量)。相對應的咱們也有全局函數和全局屬性。曾經有一段代碼坑了我下:

console.log(hasOwnProperty); //ƒ hasOwnProperty() { [native code] }複製代碼

剛開始我覺得輸出應該是undefined由於印象中hasOwnProperty並不是是全局函數。經過下面的例子你們能夠想下爲何hasOwnProperty不是全局函數可是上面的輸出不是undefined ~

Object.prototype.hasOwnProperty.call(window, 'encodeURI'); // true
'hasOwnProperty' in window //true
Object.prototype.hasOwnProperty.call(window, 'hasOwnProperty'); // false複製代碼

undefined vs null

undefined表明沒值。有2種狀況可能出現沒值。

  • 定義了變量可是未賦值
let s;
console.log(s); //undefined複製代碼
  • 未定義
let obj1 = {};
console.log(obj1.a); //undefined複製代碼

null表示有值,null是這個特殊的值。

let obj2 = {a: null};
console.log(obj2.a); //null複製代碼

若是須要同時過濾undefined跟null的話,可使用弱等於檢查。

console.log(null == undefined); //true
let arr = [null, undefined, 1];
let fil = arr.filter(it => {
    return it != null;
});
console.log(fil); //[1]複製代碼

另外undefined其實也是個全局變量, 可是null確不是。null也不掛載在window下。那麼null是哪來的呢?

window.hasOwnProperty('undefined'); //true
window.hasOwnProperty('null'); //false
window.null //undefined複製代碼

Reference

Javascript Enlightenment

Notice

  • 若是您以爲該Repo讓您有所收穫,請「Star 」支持樓主。
  • 若是您想持續關注樓主的最新系列文章,請「Watch」訂閱
相關文章
相關標籤/搜索