這是stackoverflow上的一個老問題,卻有個幹貨答案,但是擴充的資訊量很大,我隻在此抛個磚。
Not jQuery. Not YUI. Not 等等…
js的架構的确很有用,但是它們卻常常把一些js的醜陋細節和DOM原理給你隐藏了。如果你的目标是做一個精通javascript的工程師,那花大把的時間放在架構上可能恰恰背道而馳了。
下面就有javascript這門語言的一些特性,你應該知道并且深谙此道,但是很多人可能還并不清楚。
一、對象屬性,object.prop和object['prop']是一回事(是以你能停止使用eval了嗎?!3KU);對象的屬性多是String類型(有些也是數組Array)
for…in是什麼情況下使用,什麼情況慎用?
方括号可以通過變量來通路屬性
1 2 3 4 | |
當屬性是帶空格的string時就隻能用方括号了:person['first name'];
for…in 循環輸出的屬性名順序不可預測,使用之前先檢測對象是否為null 或者 undefined
二、屬性檢測;undefined和null;為什麼鮮為人知的in運算符非常有用,以及它和typeof、undefined的差別;hasOwnProperty;delete作用
undefined好了解一般用來表示未定義,而且不能用delete來删除它。
null 表示一個空對象指針 是以 typeof null傳回 object
undefined派生自null alert(null == undefined) 傳回true; 但alert(null === undefined)就傳回false了
關于hasOwnProperty和Object:
hasOwnProperty是js中唯一一個處理屬性但是不查找原型鍊的函數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
var o =new Object();
Object的每個執行個體都具有下列屬性方法:
1.Constructor:儲存着用于建立目前對象的函數 上面例子 構造函數就是 Object()
2.hasOwnProperty(prop):檢查給定的屬性是否在目前對象執行個體中(而不是在執行個體的原型中)。作為參數的屬性必須以string形式指定
3.isPrototypeOf(object):用于檢查傳入的對象是否是另一個對象的原型。
4.propertyIsEnumerable(propertyName):用于檢查給定的屬性是否能夠使用for in語句
5.toLocaleString():傳回對象的字元串表示,與環境的地區對應
6.toString():同上
7.valueOf(): 傳回對象的字元串、number、Boolean表示。通常與toString()相同
三、Number類型就是浮點類型(64位浮點數);使用浮點數會遇到語言無關性的問題;避免使用parseInt時的八進制陷阱
ECMAScript5不具有解析八進制的能力,可在IE7和chrome上測試 parseInt(069);
ES3和ES5之間存在分歧
javascript中的乘法問題:
一般可以用 10000 作為基數
31.12 * 10000 * 9.7 / 10000
四、嵌套函數作用域;避免全局變量導緻的意外而使用var的必要性;閉包的作用域如何結合使用;在循環與閉包的問題
作用域和var關鍵字的面試題
1 2 3 4 5 | |
循環中使用閉包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
之前寫過的閉包的了解關于閉包
五、全局變量和window對象的屬性産生沖突怎麼辦(它們其實是一回事);全局變量和DOM元素在IE中的沖突;在全局作用域中使用var來避免這些問題
六、 function語句在解析時會被提升(不管function被放置在哪裡,它都會被移動到定義時所在作用域的頂層) 函數聲明和函數表達式;為什麼命名函數表達式不應該使用
關于函數聲明提升:
解析器會執行一個函數聲明提升(function decalaration hoisting)的過程,讀取并将函數聲明添加到執行環境中。
對代碼求值時js引擎在第一遍會聲明函數并将它們放到源代碼樹的頂部。
1 2 3 4 5 6 7 8 9 | |
關于命名函數表達式:
1、命名函數表達式即被認為是函數聲明也被認為是函數表達式
1 2 3 4 | |
2、命名函數表達式還能建立兩個不同的函數對象—-這是js的bug
1 2 3 4 5 | |
竟然建立了兩個對象,他們之間還不是引用的關系,是不是很有趣。。。我隻能說:呵呵 interesting……
3、在條件語句中命名函數表達的聲明式仍然會被解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
注:上面的3條準确的說應該是算是jScript的bug
七、構造函數;prototype屬性;new運算符的運作機制;利用這些方法實作一個類-子類-執行個體的系統;在何時應該考慮使基于閉包的對象來替代原型設計
看看面向對象吧
八、this是在函數調用時才被确定的而不是定義的時候;把函數當做參數傳入時不像其他語言那樣執行;如何使用閉包或者Function.prototype.bind來解決這些問題呢
關于this的調用,直接上代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
上面代碼很簡單 請自行補腦……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
之前寫過的關于this的了解
關于Function.prototype.bind(thisArg [, arg1 [, arg2, …]]):
這是ECMAScript 5中的方法看看Opera的對它的介紹吧
簡單翻譯就是:
Function.prototype.bind 傳回一個新的函數對象,該對象的 this 綁定到了thisArg參數上。本質就是:這允許你在其他對象鍊中執行一個函數
但是很多浏覽器不支援,通過一個js的hack看看原理吧:
1 2 3 4 5 6 7 8 9 10 11 12 | |
九、其他的ES5新特性如indexOf 、 forEach 以及Array使用函數式程式設計;舊浏覽器如何相容這些新的方法;使用匿名函數調用這些方法來使代碼更加緊緻具有可讀性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
這些都是 ES5 中 Array 對象的擴充方法
PS:還是點此自行補腦,我也在研究中…..後續會再補充
十、浏覽器和js代碼之間控制流程的原理;同步和異步執行;事件在運作時觸發和事件在控制傳回時觸發的差別;調用同步執行的方法如alert而引起控制流重新進入的潛在問題(翻譯不通,請自行補腦)。
十一、跨window腳本對instanceof的影響 在不同的DOM中跨window腳本對控制流的影響;postMessage怎麼解決這個問題
postMessage就是HTML5解決跨域問題引入的API,使得多個iframe/window實作跨域通信。
寫了個postMessage跨域通信的demo: 點此檢視
最重要的是,你需要批判的去看待javascript,承認因為種種曆史原因而導緻各種不完美(甚至比其他語言還要糟糕),并要避免各種陷阱。Crockford在這方面的研究很值得學習(雖然我不完全認同他的《javascript語言精粹》)
源引:http://blog.jobbole.com/39571/