# 3.7 字串(String)

在 `javascript/practice` 資料夾下，建立 `string.html` 來練習。

字串：只要是被雙引號或單引號括起來的，都是字串格式。例：`"abc"`、`"1"`、`'中文'`。

## 基本型式

除了宣告之外，也可以用 length 取得字串長度。

```javascript
var my_str = "這是字串 english";

console.log(my_str);        // 這是字串 english
console.log(my_str.length); // 12
```

## 字元跳脫(Escape)

字串裡，還要用到雙引號或單引號，以下這是允許的。例：

```javascript
var my_str = "這是字串 'english'";
console.log(my_str); // 這是字串 'english'

var my_str2 = '這是字串 "english"';
console.log(my_str2); // 這是字串 "english"
```

但這個呢？

```javascript
var my_str = "這是字串 "english"";
```

在 console 中會看到語法錯誤：`Uncaught SyntaxError: Unexpected identifier`。

但如果真的希望那些符號能夠跳脫原來的功用形式，視為一般文字來看待，那我們就可以使用跳脫字元的符號( **`\`** )，來將後面緊接著的字元視為一般文字。

例 1：

```javascript
var my_str = "這是字串 \"english\"";
console.log(my_str); // 這是字串 "english"
```

例 2：將 **`\`** 視為一般文字：

```javascript
var my_str = "這是字串 \\ english";
console.log(my_str); // 這是字串 \ english
```

## 字串相關操作

### indexOf()

回傳**第一個**遇到指定字串的位置，位置是從 0  開始，然後如果找不到，就回傳 `-1`：

```javascript
var my_str = "這是字串 english, 這另個 english";
var pos1 = my_str.indexOf("english");
var pos2 = my_str.indexOf("這");
var pos3 = my_str.indexOf("測試");

console.log(pos1); // 5
console.log(pos2); // 0
console.log(pos3); // -1
```

### lastIndexOf()

回傳**最後一個**遇到指定字串的位置，位置是從 0  開始，然後如果找不到，就回傳 `-1`：

```javascript
var my_str = "這是字串 english, 這另個 english";
var pos1 = my_str.lastIndexOf("english");
var pos2 = my_str.lastIndexOf("這");
var pos3 = my_str.lastIndexOf("測試");

console.log(pos1); // 18
console.log(pos2); // 14
console.log(pos3); // -1
```

### slice()

將一個字串，取得部份字串然後回傳，然後並不會影響原字串。另可帶的參數有以下兩個：

* 第 1 個參數：取的部份字串，位置從何處開始。
* 第 2 個參數：取得部份字串，取到何處結束。(但不包含最後一個)

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.slice(4, 10);

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Banana
```

也可以只帶第 1 個參數就好，那就會直接取到最後：

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.slice(4); // 只帶第1個參數

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Banana, Kiwi
```

可以帶負值，規則是從字串的最後面從 -1 開始算：

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.slice(-12, -6);

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Banana
```

### substring()

與 `slice()` 相同，差別在於 `substring()` 不能帶負值。例：

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.substring(4, 10);

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Banana
```

同樣地，只帶第一個參數：

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.substring(4); // 只帶第1個參數

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Banana, Kiwi
```

### substr()

與 `slice()` 相同，差別在於 `substr()` 的第 2 個參數，指的是**要取幾個字元**，例：

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.substr(4, 6);

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Banana
```

只帶第 1 個參數，同樣就是直接取到最後一個字元：

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.substr(4); // 只帶第1個參數

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Banana, Kiwi
```

可帶入負值，從最後一個是 `-1` 開始數：

```javascript
var my_str = "蘋果, Banana, Kiwi";
var part_string = my_str.substr(-4, 4);

console.log("原字串：" + my_str); // 原字串：蘋果, Banana, Kiwi
console.log("部份字串：" + part_string); // 部份字串：Kiwi
```

### replace()

在某個字串中，找到「部份字串」，然後用「另一個字串」來「取代」。\
不會影響原來的字串，而是會回傳新的字串。\
只會取代第一個找到的，而且大小寫是視為不同的。例：

```javascript
var my_str = "蘋果, Banana, Kiwi, Banana";
var new_string = my_str.replace("Banana", "watermelon");

console.log(my_str); // 蘋果, Banana, Kiwi, Banana
console.log(new_string); // 蘋果, watermelon, Kiwi, Banana
```

如果是以下(將第1個參數的 "Banana" 改成 "banana")，不會有任何取代發生，因為找不到 "banana"：

```javascript
var my_str = "蘋果, Banana, Kiwi, Banana";
var new_string = my_str.replace("banana", "watermelon");

console.log(my_str); // 蘋果, Banana, Kiwi, Banana
console.log(new_string); // 蘋果, Banana, Kiwi, Banana
```

如何忽略大小寫：

改成用一種正式表達式的寫法，將 `"banana"` 改成 `/banana/i`，i 是 ignore (忽略)的意思。例：

```javascript
var my_str = "蘋果, Banana, Kiwi, Banana";
var new_string = my_str.replace(/banana/i, "watermelon");

console.log(my_str); // 蘋果, Banana, Kiwi, Banana
console.log(new_string); // 蘋果, watermelon, Kiwi, Banana
```

如何指定全部都要取代：

一樣用正式表達式的寫法，將 `"banana"` 改成 `/banana/g`，g 是 global (全域)的意思。例(以下同時使用 **`i`** 和 **`g`**)：

```javascript
var my_str = "蘋果, Banana, Kiwi, Banana";
var new_string = my_str.replace(/banana/ig, "watermelon");

console.log(my_str); // 蘋果, Banana, Kiwi, Banana
console.log(new_string); // 蘋果, watermelon, Kiwi, watermelon
```

### toUpperCase()

小寫英文字變成大寫，不會影響到原字串，會回傳新字串。例：

```javascript
var text1 = "Hello World!";
var text2 = text1.toUpperCase();

console.log(text1); // Hello World!
console.log(text2); // HELLO WORLD!
```

### toLowerCase()

大寫英文字變成小寫，不會影響到原字串，會回傳新字串。例：

```javascript
var text1 = "Hello World!";
var text2 = text1.toLowerCase();

console.log(text1); // Hello World!
console.log(text2); // hello world!
```

### concat()

將多個字串做串接。同樣地，原字串並不會被影響，而是回傳新字串。

`concat()` 其實可以用 `+` 號會更方便。例：

```javascript
var text1 = "Hello";
var text2 = "World";

var text3 = text1 + " " + text2; // 此方式較為常見
var text4 = text1.concat(" ", text2);

console.log(text3); // Hello World
console.log(text4); // Hello World
```

### trim()

如果字串的左右兩側有空格的話，就移除。例：

```javascript
var text1 = "     這是文字     ";
var text2 = text1.trim(); // 將左右的空格移除

console.log(text1); //      這是文字     
console.log(text2); // 這是文字
```

### charAt()

回傳指定位置的文字，位置是從 0 開始。也不會影響原字串。例：

```javascript
var str = "測試 HELLO WORLD";

console.log(str.charAt(1)); // 試
console.log(str.charAt(3)); // H
console.log(str); // 測試 HELLO WORLD
```

## 透過 split() 將字串轉陣列

後面我們會再認識到什麼是陣列。例：

```javascript
var tags = "a,b,c,d,e";

var arr1 = tags.split("");
var arr2 = tags.split(",");

console.log(arr1); // ["a", ",", "b", ",", "c", ",", "d", ",", "e"]
console.log(arr2); // ["a", "b", "c", "d", "e"]
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.webmix.cc/javascript/ji-chu/3.7-zi-chuan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
