感覺這篇寫了很久....

都是上班無聊有想到才開來寫一下這樣

這篇也是我的學習心得之一,當然還有一些工作上常用到,但初學者可能也不太了的東西

因為本人學習還蠻不求甚解的,只要覺得好玩就會去玩一下

所以看到有一些用法很有趣,或學完之後會讓人覺得很厲害的話就會來學一下

以下就列出這些進階用法或小常識

但對一些不是初學者的人可能會覺得是個P,請多多包涵

因為實在寫得有點長,下一篇放在第二篇好了

 

利用 && 與 || 的特性

一般來說 && 與 || 使用來做邏輯運算,但它回傳的不是 true or false

&& 代表如果左邊的運算元成立,就會檢查右邊,右邊也成立的話就會返回右邊的運算元

|| 則是只要左邊成立就忽略右方運算元,返回左邊的運算元

ex : 

0  &&  'ok';

// return 0;

'left' && 'right';

// return 'right';

'left' || 'right';

// return 'left'

所以可以利用這個特性來給予初始值或是定義

ex : 

var fun = fun || {};

如上,有 fun 物件就使用 fun 物件,沒有就給一個空物件

 

如果有需要直接將物件轉為數字,可以使用 valueOf 方法

var car = {

color: 'red',

valueOf: function () {

return 100

}

}

alert(car + 1);

//  101

 

要直接將物件輸出成字串用 toString 方法

var car = {

color: 'red',

valueOf: function () {

return 100

}, toString: function () {

return "123"

}

}

alert("1" + car)

//  "1123"

 

合併物件與預設值

此例子常用在有多種輸入參數,且有提供預設值的情況

以下取網路上的例子

function doSome(option) {

return {

x : option.x || 1,

y : option.y || 2,

z : option.z || 3

};

}

var processed = doSome({

x : 10,

y : 20

});

function log(obj) {

for(var p in obj) {

console.log(p + ': ' + obj[p]);

}

}

log(processed);

 

函數的輸入參數

使用函數時的輸入參數,不一定要跟函數定義的參數個數一致

缺少的參數就是 undefined

ex : 

function add(a, b, c) {

//這裡利用了上面講過的 || 特性給予初始值

a = a || 0; b = b || 0; c = c || 0;

return a + b + c;

}

add(10);  // 10

add(10,2);  // 12

add(10,2,4);  // 16

 

也可以多給參數

多出來的參數則可以使用函數內自行產生的 arguments 去取得

arguments 中會有所有參數的資訊

ex : 

function add(a, b, c) {

var sum = 0;

for (var i = 0; i < arguments.length; i++) {

sum += arguments[i];

}

return sum;

}

add(10,2,4,5,6); // 27

 

陣列的操作方法

可以看之前寫的這篇 Javascript 常用的陣列操作指南 

 

善用callback 處理執行順序

一般正常來講函數先呼叫的會先執行

拿網路上的範例來改一下,這是最一般的情況

function a() {

console.log('a');

}

function b() {

console.log('b');

}

a();

b();

結果為 : 

==============

a

b

但! 如果 a() 執行時間比 b() 來的久

或是 a() 裡面根本就是個 ajax,b() 都跑完了a() 結果還沒回來

例如這樣 : 

下面用 setTimeout 模擬函數 a() 需要長時間執行

function a() {

setTimeout(function () {

console.log('a');

},1000)

}

function b() {

console.log('b');

}

a();

b();

結果為 : 

==============

b

a

又例如最常用的 ajax ,a 雖然先執行,但它去了 test2.html 還沒回來咧

所以雖然先呼叫,但是結果卻比 b() 還晚返回

function a() {

$.get("test2.html", function () {

alert('a');

});

}

function b() {

alert('b');

}

a();

b();

結果為 : 

==============

b

a

以上的問題可以用 callback 來克服,callback 也大量運用在node.js之中

有寫過node.js的人應該會覺得很親切

由於函數的輸入參數可以是另一個函數,回傳值也可以是函數

所以用這個特性把 b() 傳進去 a() 就好了,待 a() 執行完後再執行 b() 就是正確順序

ex : 

function a(callback) {

setTimeout(function () {

console.log('a');

callback();

}, 1000)

}

function b() {

console.log('b');

}

// 把 b() 傳入 a()

a(b);

結果為 : 

a

b

如果是 ajax 也一樣

function a(callback) {

$.get("test2.html", function () {

alert('a');

callback()

});

}

function b() {

alert('b');

}

// 把 b() 傳入 a()

a(b);

結果為 : 

a

b

 

減少使用全域變數

減少使用全域變數可以提高程式碼品質且更好維護

當頁面有一堆全域變數會變得很難維護

因為全域變數有可能會跟第三方套件或頁面上其他變數混用到

你可以在頁面上用一個全域的物件作為命名空間,用它來管理你的全域變數

例如這樣 : 

var grobal = grobal || {};

grobal = {

changeNum: 0,

result: "",

changeControl: []

}

使用時只要這樣就好了

console.log(grobal .changeNum); // 0

給值

grobal .changeNum = 3;

除此之外也可使用立即函數來減少全域變數的產生

立即函數裡面就像是個沙盒

在函數中建立變數,可以避免該變數洩漏到全域變數作用域中

可以參考之前提過的javascript函數的多種寫法 

Javascript 開發學習心得 - 函數的多種寫法與應用限制 

用法如下 : 

var a = (function(){

var str;

........

//return str

})();

用一個括號包住一個匿名函數 function(){}

在外面的最後一個括號 (); 則代表立即執行

立即函數除了可返回值,當然也可輸入參數

你如果常直接打開jQuery 第三方套件的話,有很大機率會看到這樣寫

(function($){

 

})(jQuery);

這就是立即函數,但是傳入了jQuery物件

Javascript 該放置的位置,與網頁載入阻塞(blocking)問題

script : 

網頁解析的時候如果遇到 <script>標籤時,會暫停網頁元素下載,先執行<script>中的程式碼

所以如果你在網頁的<head>之前放了一堆內嵌的 Javascript 的話....(不引用js的方式)

就會讓User看到網頁一開始載入是一片空白 (因為在執行script) 

等待執行完之後才會繼續載入下方的 css 圖片與網頁元素

因此最好是用引用外部js的方式來載入,會比直接寫在頁面上好很多

以上指的是舊版的瀏覽器 (IE8以下)

新版的瀏覽器已經可以同時下載js與元素,但還是會有阻塞情形

如下面搭配css的方式

css

如果引用css的下方放入內嵌的 Javascript 的話 (不引用js直接寫在頁面上的方式)

ex : 

<link href="............/style.css" rel="stylesheet">

<script>

....................

</script>

就會發生阻塞情形 (圖片取自網路資料)

 311947595253277  

如上圖會等 css 載入完之後才處理 js

因此無論如何 js 盡量不要直接寫在網頁之中,尤其又放置於 head css 之後

盡量使用外部載入 js 的方式

ex : <script src="Js/myfun.js"></script>

可以參考這個網站所做的測試

http://www.cnblogs.com/shinnyChen/p/3762704.html

再來新版的瀏覽器中可以使用 defer、async

來讓有支援的瀏覽器利用非同步下載 js,避免阻塞問題

ex : 

<script src="test.js" defer></script>

<script src="test.js" async></script>

defer (html4),不停止網頁繪製,JavaScript的下載會同時進行,等待網頁繪製完成會再執行JavaScript。

async (html5),不停止網頁繪製,JavaScript的下載會同時進行,當JavaScript下載完成後,再停止網頁繪製並執行JavaScript,等待執行完成後再繼續網頁繪製。

結論,最完美的放置位置如下,上面內容不想看就直接看下面就好了 : 

<!DOCTYPE html>

<html>

<head>

<title>test</title>

<link href="Css/css.css" rel="stylesheet" />

</head>

<body>

<div>

...................
    網頁內容
...................

</div>

<script src="Js/myfun.js" type="text/javascript" defer></script>

</body>

</html>

 

 

創作者介紹
創作者 小雕 的頭像
小雕

小雕雕的家

小雕 發表在 痞客邦 留言(0) 人氣()