最近讀了Javascript Enlightenment。總體感受仍是比較基礎的。這裏記錄跟擴展下其中一些知識點。javascript
JS裏有個不成文的規定,構造函數首字母大寫。因此可能容易讓人產生誤解Math是構造函數。其實Math只是一個簡單的封裝了不少數學相關方法的對象。java
console.log(typeof Math); //"object"
console.log(typeof Array); //"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種常見的方法區分數組:瀏覽器
console.log(Array.isArray([1,2])); //true複製代碼
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只會刪除自身屬性。不會刪除原型鏈上的屬性。函數
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種方法:
當咱們訪問一個變量的時候會造成一個做用域鏈。做用域的頂端就是全局變量(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表明沒值。有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複製代碼