JavaScript函數(shù)學(xué)習(xí)總結(jié)以及相關(guān)的編程習(xí)慣指南
null 和 undefined
Undefined相當(dāng)于一個(gè)變量并沒有明確的被賦值(是否被賦值, 可能無心忽略, 邏輯問題) JS的怪異之處就在于undefined真的是一個(gè)可以使用的值。
> var foo; > foo undefined
同理,當(dāng)缺失參數(shù)時(shí) JavaScript 會(huì)分配一個(gè) undefined:
> function id(x) { return x } > id() undefined a = 1; a !== undefined // true a = undefined var b a === b //true
Null相當(dāng)于變量被明確指定了沒有值,而不是由于意外的原因被忽略掉了(賦值null, 正當(dāng)邏輯)
參與運(yùn)算
JS的null如果進(jìn)入運(yùn)算,真的會(huì)被解析成為0或false:
(1 + null) # 1 (1 * null) # 0 (1 * null) # Infinity
undefined進(jìn)入運(yùn)算,一律得到NaN:
(1 + undefined) # NaN (1 * undefined) # NaN (1 / undefined) # NaN
邏輯判斷
null和undefined邏輯判斷時(shí)都認(rèn)為是false。
只用一個(gè)判斷,就可以同時(shí)檢驗(yàn)這兩項(xiàng)是否為真:
//也會(huì)把 false, -0, +0, NaN 與 '' 當(dāng)成“空值” if (v) { // v 有值 } else { // v 沒有值 }
但是如果碰到大坑==的時(shí)候
var foo; console.log(foo == null); // true console.log(foo == undefined); // true console.log(foo === null); // false console.log(foo === undefined); // true console.log(null == undefined); // true
好的做法, 一律使用===
判斷一個(gè)量已定義且非空,只使用:if (a !== null && a !== undefined)。
=== 和 ==
1.==用來判斷兩個(gè)值是否相等
當(dāng)兩個(gè)值類型不同時(shí),會(huì)發(fā)生自動(dòng)轉(zhuǎn)換,得到的結(jié)果非常不符合直覺,這可能不是你想要的結(jié)果。
"" == "0" // false 0 == "" // true 0 == "0" // true false == "false" // false false == "0" // true false == undefined // false false == null // false null == undefined // true " \t\r\n" == 0 // true
2.===
類型+值比較
"如果兩邊的操作數(shù)具有相同的類型和值,===返回true,!==返回false。"——《JavaScript:語言精粹》
最佳實(shí)踐:
任何時(shí)候在比較操作中使用 === 和 !==
json操作
var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} }; var stringFromPerson = JSON.stringify(person); /* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}" */ var personFromString = JSON.parse(stringFromPerson); /* personFromString is equal to person object */ to string var obj = { name: 'myObj' }; JSON.stringify(obj);
函數(shù)對象及匿名函數(shù)
函數(shù)對象賦值
var slice_func = [].slice //slice_func() var a = function() { }; // a() var a = { fun : function() { }; } // a.fun() someElement.addEventListener("click", function(e) { // I'm anonymous! });
以及
var f = function foo(){ return typeof foo; // foo是在內(nèi)部作用域內(nèi)有效 }; // foo在外部用于是不可見的 typeof foo; // "undefined" f(); // "function"
匿名函數(shù)
from var name = 'Chris'; var age = '34'; var status = 'single'; function createMember(){ // [...] } function getMemberDetails(){ // [...] } to var myApplication = function(){ var name = 'Chris'; var age = '34'; var status = 'single'; return{ createMember:function(){ // [...] }, getMemberDetails:function(){ // [...] } } }(); // myApplication.createMember() and // myApplication.getMemberDetails() now works.
最佳實(shí)踐
1.定義多個(gè)變量時(shí),省略var關(guān)鍵字,用逗號(hào)代替
var someItem = 'some string'; var anotherItem = 'another string'; var oneMoreItem = 'one more string';
更好的做法
var someItem = 'some string', anotherItem = 'another string', oneMoreItem = 'one more string';
2.謹(jǐn)記,不要省略分號(hào), 不要省略花括號(hào)
省略分號(hào),可能導(dǎo)致更大的,未知的,難以發(fā)現(xiàn)的問題
var someItem = 'some string' function doSomething() { return 'something' }
更好的做法
var someItem = 'some string'; function doSomething() { return 'something'; }
3.使用{}代替 new Ojbect()
在JavaScript中創(chuàng)建對象的方法有多種??赡苁莻鹘y(tǒng)的方法是使用”new”加構(gòu)造函數(shù),像下面這樣:
var o = new Object(); o.name = 'Jeffrey'; o.lastName = 'Way'; o.someFunction = function() { console.log(this.name); }
更好的做法
var o = {}; //空對象
var o = { name: 'Jeffrey', lastName = 'Way', someFunction : function() { console.log(this.name); } };
只要把多個(gè)全局變量都整理在一個(gè)名稱空間下,擬將顯著降低與其他應(yīng)用程序、組件或類庫之間產(chǎn)生糟糕的相互影響的可能性?!狣ouglas Crockford
4.使用[]代替 new Array()
var a = new Array(); a[0] = "Joe"; a[1] = 'Plumber';
更好的做法:
var a = ['Joe','Plumber'];
5.typeof判斷
typeof一般只能返回如下幾個(gè)結(jié)果:number,boolean,string,function,object,undefined
expr:
typeof xx === '' typeof xx !== ''
e.g.
// Numbers typeof 37 === 'number'; typeof 3.14 === 'number'; typeof Infinity === 'number'; typeof NaN === 'number'; // 盡管NaN是"Not-A-Number"的縮寫,意思是"不是一個(gè)數(shù)字" // Strings typeof "" === 'string'; typeof "bla" === 'string'; typeof (typeof 1) === 'string'; // typeof返回的肯定是一個(gè)字符串 // Booleans typeof true === 'boolean'; typeof false === 'boolean'; // Undefined typeof undefined === 'undefined'; typeof blabla === 'undefined'; // 一個(gè)未定義的變量,或者一個(gè)定義了卻未賦初值的變量 // Objects typeof {a:1} === 'object'; typeof [1, 2, 4] === 'object'; // 使用Array.isArray或者Object.prototype.toString.call方法可以分辨出一個(gè)數(shù)組和真實(shí)的對象 typeof new Date() === 'object'; // Functions typeof function(){} === 'function'; typeof Math.sin === 'function'; typeof null === 'object'; // 從JavaScript誕生以來,一直是這樣的.
6.三元運(yùn)算符 :強(qiáng)大且風(fēng)騷
語法
expression ? xxx : yyy bad var direction; if(x < 200){ direction = 1; } else { direction = -1; } good var direction = x < 200 ? 1 : -1;
7.使用邏輯 AND/OR 做條件判斷
var foo = 10; foo == 10 && doSomething(); // 等價(jià)于 if (foo == 10) doSomething(); foo == 5 || doSomething(); // 等價(jià)于 if (foo != 5) doSomething(); //默認(rèn)值 a = b || 'default' return b || c || d > 1 ? 0 : 2
8.給一個(gè)變量賦值的時(shí)候不要忘記使用var關(guān)鍵字
給一個(gè)未定義的變量賦值會(huì)導(dǎo)致創(chuàng)建一個(gè)全局變量。要避免全局變量
9.自我調(diào)用的函數(shù)
自調(diào)用匿名函數(shù)(Self-Invoked Anonymous Function)或者即時(shí)調(diào)用函數(shù)表達(dá)式(IIFE-Immediately Invoked Function Expression)。這是一個(gè)在創(chuàng)建后立即自動(dòng)執(zhí)行的函數(shù)
(function(){ // some private code that will be executed automatically })(); (function(a,b){ var result = a+b; return result; })(10,20)
10.避免使用 eval() 和 Function 構(gòu)造函數(shù)
Eval=邪惡, 不僅大幅降低腳本的性能(譯注:JIT編譯器無法預(yù)知字符串內(nèi)容,而無法預(yù)編譯和優(yōu)化),而且這也會(huì)帶來巨大的安全風(fēng)險(xiǎn),因?yàn)檫@樣付給要執(zhí)行的文本太高的權(quán)限,避而遠(yuǎn)之
使用 eval 和 Function 構(gòu)造函數(shù)是非常昂貴的操作,因?yàn)槊看嗡麄兌紩?huì)調(diào)用腳本引擎將源代碼轉(zhuǎn)換成可執(zhí)行代碼。
var func1 = new Function(functionCode); var func2 = eval(functionCode);
11.避免使用 with()
使用 with() 會(huì)插入一個(gè)全局變量。因此,同名的變量會(huì)被覆蓋值而引起不必要的麻煩
12.腳本放在頁面的底部
記住——首要目標(biāo)是讓頁面盡可能快的呈獻(xiàn)給用戶,腳本的夾在是阻塞的,腳本加載并執(zhí)行完之前,瀏覽器不能繼續(xù)渲染下面的內(nèi)容。因此,用戶將被迫等待更長時(shí)間
13.避免在For語句內(nèi)聲明變量
bad
for(var i = 0; i < someArray.length; i++) { var container = document.getElementById('container'); container.innerHtml += 'my number: ' + i; console.log(i); }
good
var container = document.getElementById('container'); for(var i = 0, len = someArray.length; i < len; i++) { container.innerHtml += 'my number: ' + i; console.log(i); }
14.給代碼添加注釋
// 循環(huán)數(shù)組,輸出每項(xiàng)名字(譯者注:這樣的注釋似乎有點(diǎn)多余吧). for(var i = 0, len = array.length; i < len; i++) { console.log(array[i]); }
15.instanceof
instanceof 方法要求開發(fā)者明確地確認(rèn)對象為某特定類型
var oStringObject = new String("hello world"); console.log(oStringObject instanceof String); // 輸出 "true" // 判斷 foo 是否是 Foo 類的實(shí)例 function Foo(){} var foo = new Foo(); console.log(foo instanceof Foo)//true // 判斷 foo 是否是 Foo 類的實(shí)例 , 并且是否是其父類型的實(shí)例 function Aoo(){} function Foo(){} Foo.prototype = new Aoo();//JavaScript 原型繼承 var foo = new Foo(); console.log(foo instanceof Foo)//true console.log(foo instanceof Aoo)//true
16.apply/call
someFn.call(this, arg1, arg2, arg3); someFn.apply(this, [arg1, arg2, arg3]);
apply
Function.apply(obj,args)方法能接收兩個(gè)參數(shù)
obj:這個(gè)對象將代替Function類里this對象
args:這個(gè)是數(shù)組,它將作為參數(shù)傳給Function(args-->arguments)
call
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:這個(gè)對象將代替Function類里this對象
params:這個(gè)是一個(gè)參數(shù)列表
使用哪個(gè)取決于參數(shù)的類型
相關(guān)文章
javascript窗口寬高,鼠標(biāo)位置,滾動(dòng)高度(詳細(xì)解析)
javascript窗口寬高,鼠標(biāo)位置,滾動(dòng)高度(詳細(xì)解析)。需要的朋友可以過來參考下,希望對大家有所幫助2013-11-11JavaScript SetInterval與setTimeout使用方法詳解
本文講解了JavaScript SetInterval與setTimeout的區(qū)別,并用代碼示例演示了使用方法2013-11-11JavaScript ES6中的簡寫語法總結(jié)與使用技巧
我們在看編寫的JS ES6代碼時(shí)經(jīng)常會(huì)看到許多簡寫的語法,本篇文章就為大家一一介紹JavaScript ES6可以簡寫的語法2018-12-12