Skip to content

Commit

Permalink
translate jstips 2015-12-29 - 2016-02-12 articles
Browse files Browse the repository at this point in the history
  • Loading branch information
neighborhood999 committed Feb 21, 2016
1 parent a5c4183 commit 8b53a32
Show file tree
Hide file tree
Showing 44 changed files with 2,538 additions and 0 deletions.
46 changes: 46 additions & 0 deletions _posts/zh_TW/2015-12-29-insert-item-inside-an-array.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
layout: post

title: 在陣列中加入元素
tip-number: 00
tip-username: loverajoel
tip-username-profile: https://github.com/loverajoel
tip-tldr: 在一個存在的陣列加入新的元素是一件很常見的事情,你可以使用 push 將元素加入到陣列的末端,或是使用 unshift 在陣列起始位置加入元素,也可以使用 slice 在陣列中間的地方加入元素。


categories:
- zh_TW
---

在一個存在的陣列加入新的元素是一件很常見的事情,你可以使用 push 將元素加入到陣列的末端,或是使用 unshift 在陣列起始位置加入元素,也可以使用 slice 在陣列中間的地方加入元素。

那些都是已知的方法,但這並不代表沒有更好的效能的方法。讓我們開始吧:

在陣列的末端加入元素我們可以簡單地透過 push() 方式,但以下是更能提升效能方法。

```javascript
var arr = [1, 2, 3, 4, 5];

arr.push(6);
arr[arr.length] = 6; // 在 Mac OS X 10.11.1 下的 Chrome 47.0.2526.106 加快了 43%
```
這兩種方法都是修改原始的陣列。不相信嗎?請參考 [jsperf](http://jsperf.com/push-item-inside-an-array)

現在,如果我們要嘗試在陣列的起始位置加入元素:

```javascript
var arr = [1, 2, 3, 4, 5];

arr.unshift(0);
[0].concat(arr); // 在 Mac OS X 10.11.1 下的 Chrome 47.0.2526.106 加快了 98%
```
這裡有更多的小細節:使用 unshift 修改原始的陣列;concat 返回新的陣列。 [jsperf](http://jsperf.com/unshift-item-inside-an-array)

使用 splice 陣列的中間加入元素是相當容易的,而且是最高效的方法。

```javascript
var items = ['one', 'two', 'three', 'four'];
items.splice(items.length / 2, 0, 'hello');
```

我嘗試在不同的瀏覽器和 OS 執行這些測試,他們的結果是相似的。我希望這些知識對你是有幫助的,也鼓勵你自己進行測試!
37 changes: 37 additions & 0 deletions _posts/zh_TW/2016-01-01-angularjs-digest-vs-apply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
layout: post

title: AngularJs - `$digest` vs `$apply`
tip-number: 01
tip-username: loverajoel
tip-username-profile: https://github.com/loverajoel
tip-tldr: JavaScript 模組以及建構步驟變得更多更複雜,但對於新的框架樣板呢?

categories:
- zh_TW
---

AngularJs 最令人欣賞的特性之一是雙向資料綁定。AngularJS 透過循環方式(`$digest`)來檢查模型和視圖變化來實現這個功能。想要理解框架底層的工作方式,你必須了解這個概念。

當一個事件被觸發時,Angular 會檢查每個 watcher 變化,這是我們所知的 `$digest` 循環。
有時候你需要強迫手動執行一個新的循環,你必須選擇正確的選項,因為這個階段是最影響效能之一。

### `$apply`
這個核心方法可以讓你明確地啟動 `$digest` 循環。意思說所有的 watchers 都會被確認;整個應用程式啟動 `$digest loop`。在內部,執行一個可選的功能參數,它會呼叫 `$rootScope.$digest();`

### `$digest`
在這個情況下,`$digest` 方法在目前的作用域和子作用域啟動 `$digeset` 循環。你應該注意到父作用域不會被確認,也不會受影響。

### 建議
- 當瀏覽器 DOM 事件在 AngularJS 之外被觸發使用 `$apply``$digest`
- 傳送一個函數表達式給 `$apply`,這裡有一個錯誤處理機制,並且允許整合在 `$digest` 循環的變化。

```javascript
$scope.$apply(() => {
$scope.tip = 'Javascript Tip';
});
```

- 如果你只要更新目前的作用域和子作用域,使用 `$digest`,以及防止在整個應用程式執行新的 digest 循環。這在性能上的好處是相當明顯的。
- `$apply()` 對電腦來說是一個相當困難的處理程序,如果過多的綁定會造成性能上的問題。
- 如果你使用 >AngularJS 1.2.X,使用 `$evalAsync`,這是一個核心方法,可以在目前的循環或下一個循環執行表達式,可以增加你的應用程式效能。
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
layout: post

title: 在子元件 Keys 是很重要的
tip-number: 02
tip-username: loverajoel
tip-username-profile: https://github.com/loverajoel
tip-tldr: 從陣列中動態建立所有元件時,你必須傳送 key 屬性。它是一個唯一以及固定的 id,React 用來識別 DOM 裡面的每個元件,並區別它是否為同一個元件。使用 keys 可以確保子元件不會被重覆建立,也可以防止奇怪的事件發生。

categories:
- zh_TW
---

從陣列中動態建立所有元件時,你必須傳送 [key](https://facebook.github.io/react/docs/multiple-components.html#dynamic-children) 屬性。它是一個唯一以及固定的 id,React 用來識別 DOM 裡面的每個元件,並區別它是否為同一個元件。使用 keys 可以確保子元件不會被重覆建立,也可以防止奇怪的事件發生。

> Key 跟效能不太相關,它跟元件識別有關係(反之,它間接提升了效能)。隨機賦值和改變數值將無法識別。[Paul O’Shannessy](https://github.com/facebook/react/issues/1342#issuecomment-39230939)
- 使用物件內存在的唯一值。
- 在你的父元件定義 keys,而不是子元件。

```javascript
//bad
...
render() {
<div key={{item.key}}>{{item.name}}</div>
}
...

//good
<MyComponent key={{item.key}}/>
```
- [使用陣列索引是不好的習慣。](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318#.76co046o9)
- `random()` 將無法使用。

```javascript
//bad
<MyComponent key={{Math.random()}}/>
```


- 你可以建立你自己唯一的 id。確認這個方法夠快速可以附加到你的物件上。
- 當你的子元件數量很多或者含有龐大的元件,使用 keys 可以提高效能。
- [你必須提供 key 屬性給 ReactCSSTransitionGroup 的所有子元件。](http://docs.reactjs-china.com/react/docs/animation.html)
92 changes: 92 additions & 0 deletions _posts/zh_TW/2016-01-03-improve-nested-conditionals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
layout: post

title: 改善嵌套的條件式
tip-number: 03
tip-username: AlbertoFuente
tip-username-profile: https://github.com/AlbertoFuente
tip-tldr: 我們要如何在 javascript 改善並更有效的嵌套 `if` 條件式?

categories:
- zh_TW
---

我們要如何在 javascript 改善並更有效的嵌套 `if` 條件式?

```javascript
if (color) {
if (color === 'black') {
printBlackBackground();
} else if (color === 'red') {
printRedBackground();
} else if (color === 'blue') {
printBlueBackground();
} else if (color === 'green') {
printGreenBackground();
} else {
printYellowBackground();
}
}
```

有一種方式可以改善嵌套 `if` 條件式是使用 `switch` 陳述式。雖然簡潔,而且有排序,但是不建議使用,因為它不容易 debug 錯誤。告訴你[為什麼](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals)

```javascript
switch(color) {
case 'black':
printBlackBackground();
break;
case 'red':
printRedBackground();
break;
case 'blue':
printBlueBackground();
break;
case 'green':
printGreenBackground();
break;
default:
printYellowBackground();
}
```

但是,如果我們語句中都有很多條件檢查呢?在這個情況下,如果我們想要讓它更簡潔,而且有排序,我們可以使用有條件的 `switch`
如果我們傳送 `true` 當作參數給 `switch` 陳述式,允許我們在每個 case 下使用條件式。

```javascript
switch(true) {
case (typeof color === 'string' && color === 'black'):
printBlackBackground();
break;
case (typeof color === 'string' && color === 'red'):
printRedBackground();
break;
case (typeof color === 'string' && color === 'blue'):
printBlueBackground();
break;
case (typeof color === 'string' && color === 'green'):
printGreenBackground();
break;
case (typeof color === 'string' && color === 'yellow'):
printYellowBackground();
break;
}
```

但是我們必須避免使用過多的條件檢查以及避免使用 `switch`。我們使用最有效率的方式,透過 `object`

```javascript
var colorObj = {
'black': printBlackBackground,
'red': printRedBackground,
'blue': printBlueBackground,
'green': printGreenBackground,
'yellow': printYellowBackground
};

if (color in colorObj) {
colorObj[color]();
}
```

這裡你可以找到更多的資訊關於 [switch](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/。
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
layout: post

title: 將帶有音節字元的字串進行排序
tip-number: 04
tip-username: loverajoel
tip-username-profile: https://github.com/loverajoel
tip-tldr: JavaScript 原生的 **sort** 方法讓我們可以排序陣列。做一個簡單的 `array.sort()`, 將每一個陣列元素視為字串並依字母排序。但是當你嘗試排序一個非 ASCII 字元陣列時,你會得到一個奇怪的結果。

categories:
- zh_TW
---

JavaScript 原生的 **[sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)** 方法讓我們可以排序陣列。做一個簡單的 `array.sort()`, 將每一個陣列元素視為字串並依字母排序。你可以提供你的[自定義排序](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters)函式。

```javascript
['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort();
// ["Buenos Aires", "Mumbai", "New York", "Shanghai"]
```

但是當你嘗試排序一個非 ASCII 字元陣列像是: `['é', 'a', 'ú', 'c']`,你會得到奇怪的結果: `['c', 'e', 'á', 'ú']`。這個問題是因為排序功能只適用於英語。

請看以下的範例:

```javascript
// 西班牙語
['único','árbol', 'cosas', 'fútbol'].sort();
// ["cosas", "fútbol", "árbol", "único"] // bad order

// 德文
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort();
// ["Wann", "Woche", "wäre", "wöchentlich"] // bad order
```

幸運的是,有兩種方法可以解決這個問題,由 ECMAScript 國際化 API 提供的 [localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)[Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator)

> 這兩種方法都有他們自己的自定義參數設置可以更有效的解決這個問題。
### 使用 `localeCompare()`

```javascript
['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) {
return a.localeCompare(b);
});
// ["árbol", "cosas", "fútbol", "único"]

['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) {
return a.localeCompare(b);
});
// ["Wann", "wäre", "Woche", "wöchentlich"]
```

### 使用 `Intl.Collator()`

```javascript
['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare);
// ["árbol", "cosas", "fútbol", "único"]

['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare);
// ["Wann", "wäre", "Woche", "wöchentlich"]
```

- 對於每一個方法,你可以自定義位置。
- 根據 [Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance),當比對大量的字串時,Intl.Collator 會更加快速。

所以,當你在處理非英文語系的字串陣列時,記得使用這個方法來避免排序出現異常。
40 changes: 40 additions & 0 deletions _posts/zh_TW/2016-01-05-differences-between-undefined-and-null.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
layout: post

title: `undefined` 和 `null` 的差別
tip-number: 05
tip-username: loverajoel
tip-username-profile: https://github.com/loverajoel
tip-tldr: 了解 `undefined` 和 `null` 的差別。

categories:
- zh_TW
---

- `undefined` 意思是變數沒有被宣告,或者是已經宣告了,但是沒有賦予值。
- `null` 意思是賦予「沒有值」的值。
- Javascript 將未賦予值的變數的預設值設為 `undefined`
- Javascript 從來不會將值設定為 `null`。這是讓開發者用來宣告 `var` 是沒有值的。
- `undefined` 不是一個有效的 JSON,而 `null` 是有效的。
- `undefined` 的類型(typeof) 是 `undefined`
- `null` 的類型(typeof)是一個 `object`[為什麼?](http://www.2ality.com/2013/10/typeof-null.html)
- 它們都是資料元素。
- 它們都是 [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)
(`Boolean(undefined) // false`, `Boolean(null) // false`)。
- 你可以判斷一個變數是否為 [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined)

```javascript
typeof variable === "undefined"
```
- 你可以判斷一個變數是否為 [null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null)

```javascript
variable === null
```
- **雙等號**運算符認為它們是相等的,但是**三等號**比較時是不相等的。

```javascript
null == undefined // true

null === undefined // false
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: post

title: 撰寫一個可以接受單一參數和陣列的方法
tip-number: 06
tip-username: mattfxyz
tip-username-profile: https://twitter.com/mattfxyz
tip-tldr: 撰寫你的函式可以處理陣列或單一元素參數,而不是透過分開的方法來處理陣列和單一元素參數。這和 jQuery 一些函式工作原理相似(`css` selector 將會修改所有匹配的)。

categories:
- zh_TW
---

撰寫你的函式可以處理陣列或單一元素參數,而不是透過分開的方法來處理陣列和單一元素參數。這和 jQuery 一些函式工作原理相似(`css` selector 將會修改所有匹配的)。

首先,你只要將任何的東西 concat 到陣列上。`Array.concat` 將會接受陣列或是單一元素。

```javascript
function printUpperCase(words) {
var elements = [].concat(words);
for (var i = 0; i < elements.length; i++) {
console.log(elements[i].toUpperCase());
}
}
```

`printUpperCase` 現在已經可以接收單一文字或是多個文字的陣列當作它的參數了。

```javascript
printUpperCase("cactus");
// => CACTUS
printUpperCase(["cactus", "bear", "potato"]);
// => CACTUS
// BEAR
// POTATO
```
Loading

0 comments on commit 8b53a32

Please sign in to comment.