封裝模式
通常,我們會(huì)盡量減少使用全局變量,除非必要。由于js變量作用范圍是函數(shù)作用域而非塊作用域。因此我們可以通過立即執(zhí)行匿名函數(shù)(即:(function(){})())只對外暴露組件的方法名,避免變量沖突和污染全局。
(function() {
var formatNumber = function(num) {
return num.toFixed(2);
};
window.toFixedTwo = formatNumber;
})();
console.log(formatNumber) // => undefined
console.log(toFixedTwo(10)); // => 10.00
對象類型檢測
當(dāng)檢測一個(gè)對象的類型,強(qiáng)烈推薦用 Object.prototype.toString 方法; 因?yàn)檫@是唯一一個(gè)可依賴的方式。typeof 的一些返回值在標(biāo)準(zhǔn)文檔中并未定義,因此不同的引擎實(shí)現(xiàn)可能不同。除非為了檢測一個(gè)變量是否已經(jīng)定義,我們應(yīng)盡量避免使用 typeof 操作符。
console.log(typeof "yunmo"); //string
console.log(typeof 1); //number
console.log(typeof undefined); //undefined
console.log(typeof null); //object
console.log(typeof {}); //object
console.log(typeof []); //object
console.log(typeof true); //boolean
console.log(typeof function() {}); //function
console.log(Object.prototype.toString.call("yunmo")); //[object String]
console.log(Object.prototype.toString.call(1)); //[object Number]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
console.log(Object.prototype.toString.call(null)); //[object Null]
console.log(Object.prototype.toString.call({})); //[object Object]
console.log(Object.prototype.toString.call([])); //[object Array]
console.log(Object.prototype.toString.call(true)); //[object Boolean]
console.log(Object.prototype.toString.call(function() {})); //[object Function]
對于js中的toString()方法,當(dāng)調(diào)用類型是Array, RegExp, Date, Number,這個(gè)方法是被重寫過的。
({name:'yunmo',age:18,place:'China'}).toString(); //"[object Object]"
['yun','mo'].toString(); //"yun,mo"
1..toString(); //"1" ; (1).toString();
此外,instanceof 操作符用來比較兩個(gè)操作數(shù)的構(gòu)造函數(shù)。只有在比較自定義的對象時(shí)才有意義。如果用來比較內(nèi)置類型,將會(huì)和 typeof 操作符 一樣用處不大。instanceof 操作符應(yīng)該僅僅用來比較來自同一個(gè) JavaScript 上下文的自定義對象。正如 typeof 操作符一樣,任何其它的用法都應(yīng)該是避免的。
對象遍歷與Object.keys()
The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
譯:Object.keys()方法返回給定對象自有的可枚舉屬性,返回的屬性名順序和使用for...in循環(huán)相同(區(qū)別在于for...in枚舉的包括該對象原型鏈上的屬性)
Object.keys()和使用for...in + hasOwnProperty達(dá)到同樣效果。在進(jìn)行屬性遍歷的時(shí)候,總是推薦這兩種方式,避免原型鏈查找這種耗時(shí)過程,優(yōu)化性能。hasOwnProperty 是 JavaScript 中唯一一個(gè)處理屬性但是不查找原型鏈的函數(shù)
var array = [1,2,3];
console.log(Object.keys(array)); //["0", "1", "2"]
console.log(Object.getOwnPropertyNames(array)); //["0", "1", "2", "length"]
var object = {name:'yunmo',age:18,place:'China'};
console.log(Object.keys(object)); //["name", "age", "place"]
console.log(Object.getOwnPropertyNames(object)); //["name", "age", "place"]
for(var i in object) {
if(object.hasOwnProperty(i)) {
console.log(i, ' '+ object[i]);
}
}
兼容性:IE9及以上
對象創(chuàng)建
JavaScript可以通過字面量來構(gòu)造對象,比如通過[]構(gòu)造一個(gè)數(shù)組,{}構(gòu)造一個(gè)對象,/regexp/構(gòu)造一個(gè)正則表達(dá)式,我們應(yīng)當(dāng)盡力使用字面量來構(gòu)造對象,因?yàn)樽置媪渴且嬷苯咏忉寛?zhí)行的,而如果使用構(gòu)造函數(shù)的話,需要調(diào)用一個(gè)內(nèi)部構(gòu)造器,所以字面量略微要快一點(diǎn)點(diǎn)。
綜合實(shí)例
var taskHandler = (function () {
//code goes here.....
return {
prepare: function () {
console.log('prepare');
},
analyse: function () {
console.log('analyse');
},
work: function () {
console.log('work');
},
finishingTouch: function () {
console.log('finishingTouch');
},
init: function () {
this.prepare();
this.analyse();
this.work();
this.finishingTouch();
window.work = this.work;
}
}
})();
taskHandler.init();
work();