譯文地址 bonsaiden.github.io/JavaScript-Garden/zh/#intro.authorsgit
以前被人問到JS一些概念性的東西,感受很模糊,可能層次比較淺,偏理論的東西實踐得較少,發現一處花園, 採點小蜜。github
1 數字不是對象的誤解
2.toString();報語法錯誤的緣由是由於試圖將 點號解析爲浮點數的一部分。
(2).toString()可行的。
2 hasOwnProrotype方法繼承自Object.prototype
是JS中惟一一個處理屬性可是不查找原型鏈的函數。
3 函數名在函數內老是可見的
var a = function b (){b();}//見9
4 'use strict'
嚴格模式下,arguments的 getter 和 setter 方法不會被建立
function f(a) {
"use strict";
a = 42;//setter沒有被建立, arguments[0] 不會變
return [a, arguments[0]];
}
5 ??? 然而,的確有一種狀況會顯著的影響現代 JavaScript 引擎的性能。這就是使用 arguments.callee。
function foo() {
arguments.callee; // do something with this function object
arguments.callee.caller; // and the calling function object
}
function bigLoop() {
for(var i = 0; i < 100000; i++) {
foo(); // Would normally be inlined...
}
}
上面代碼中,foo 再也不是一個單純的內聯函數 inlining(譯者注:這裏指的是解析器能夠作內聯處理), 由於它須要知道它本身和它的調用者。 這不只抵消了內聯函數帶來的性
能提高,並且破壞了封裝,所以如今函數可能要依賴於特定的上下文。
所以強烈建議你們不要使用 arguments.callee 和它的屬性。
6 構造函數
構造函數內部this指向新建立的對象;
新建立的對象prototype被指向構造函數的的prototype;
若是 函數內部沒有顯示的return表達式,就會隱式的返回新建的對象;
若是return 的不是對象,那麼將返回新建的對象;
7 JS函數中只有經過兩種方式聲明局部變量 參數 和 var
8 變量提高(hoist)
變量聲明會被提高,可是缺省值是undefined
函數式聲明也會被提高,並且能夠當即使用
9 JS函數內部變量查找順序
1 查找var聲明
2 查找是否存在以該名稱命名的函數
3 查找函數自身
function sss(){
var sss = 1;
function sss(){}
}
10 遍歷數組的時候, 使用in 會遍歷出原型鏈上的屬性
在使用for(var i=0; L=arr.length; i<L; i++) 緩存數組長度會提升效率
11 相等和比較
JavaScript 是弱類型語言,這就意味着,等於操做符會爲了比較兩個值而進行強制類型轉換。
不像普通的等於操做符,嚴格等於操做符不會進行強制類型轉換。
雖然 == 和 === 操做符都是等於操做符,可是當其中有一個操做數爲對象時,行爲就不一樣了。這裏等於操做符比較的不是值是否相等,只有對象的同一個實例才被認爲是
相等的。 這有點像 Python 中的 is 和 C 中的指針比較。
12 typeof/instanceof 操做符
typeof操做符 是JS設計的缺陷之一,大多數狀況會返回Object。並且老是返回字符串。
要想精確地獲得變量類型,Object.prototype.toString.call('test').slice(8,-1)
instanceof是用來檢測對象的構造函數(會有多個)
13 eval
eval()會執行一段JS字符串,只有被直接調用的時候,纔會在當前做用域中執行。
var a = eval; a('xxx'); 和 eval('xxx')執行環境會有所不一樣。
setTimeout/setInterval也接受字符串做爲第一個參數,而且執行。可是老是在全局做用域中執行,其中的'eval'不是被直接調用。
14 undefined
???全局環境中有個變量叫作undefined, 保存的是undefined類型實際值的副本,所以對它賦新值不會改變undefined類型的值。
15 JS是有分號的語言,須要分號解析源代碼,所以在解析的時候會自動插入分號,會產生隱患。
16
function Foo() {
this.value = 42;
this.method = function() {
console.log(this,3333); //執行函數的時候this指向了window,延遲
};
setTimeout(this.method, 500);//this執行新建的Foo對象,決定使用哪一個方法,當即決定。
}
new Foo();
數組