# JavaScript 基本特性, 變數

## 直譯式語言的特性

* 沒先編譯. 一行一行逐行執行.
* 逐行直行時的特例: Function Hoisting, Function Declartion會被提升到當前scope的最頂端. 參考[JavaScript Function Definitions](http://www.w3schools.com/js/js_function_definition.asp)

## 除法

在`c`程式語言裡面, `2/3=0`, `3/2=1`. 在多數語言也是如此.

在`JavaScript`程式語言裡, `3/2=1.5`, 若要取整數部份則需要用到`Math.floor(3/2);//=1;`

## Exception & Crash & Assert

其他語言會crash但JavaScript不會的case:

1. `var test_array=[1,2]`, 其大小是`2`, 但access到超出範圍, e.g. `var k = test_array[100]`.&#x20;
2. 除以`0`

JavaScript exception常見case:使用到未宣告的物件

其他語言有的有兩種, 三種, JavaScript只有Exception

* Exception可以try-catch, 參考<http://www.w3schools.com/js/js_errors.asp>
* 可以自己製造Exception, 事先做一個如果真的發生時的提醒, 來debug.(上面link有提到)
* 通常發生Exception如果沒有catch住，程式也會掛掉，不過Browser如果是在本地端發生exception (比如說按一個button執行JavaScropt code時，下一次按button還是會去執行那段code.

## 記憶體管理

自動回收. 沒有人指到這物件就會被回收掉.

## JavaScript 裡的變數自動轉型

\[<https://msdn.microsoft.com/zh-tw/library/67defydd(v=vs.94).aspx](https://msdn.microsoft.com/zh-tw/library/67defydd(v=vs.94).aspx>)

在 JavaScript 中，您可以針對不同型別的值執行運算，而不會發生例外狀況。 JavaScript 解譯器會將其中一種資料型別隱含轉換 (或「強制型轉」(Coerce)) 成其他資料型別，然後再執行運算。 字串、數字和布林值的強制型轉規則如下：

1. 如果您合併使用數字和字串，數字會強制型轉為字串。
2. 如果您合併使用布林值和字串，布林值會強制型轉為字串。
3. 如果您合併使用數字和布林值，布林值會強制型轉為數字。

## 變數的宣告跟定義

1. 其他語言function有時也有分宣告declaration 跟定義definition, 但JS主要是變數比較有在分.
2. 沒有宣告 跟沒有定義是不同的
   1. `var x; console.log("x:",x);` , print "undefined", no exception
   2. `console.log("y:",y);` , 沒有先宣告但直接使用時, exception如下,`exception: Uncaught ReferenceError: y is not defined`, 字有包含not defined但其實這case是連宣告也沒有.

## 變數的copy, 以及 Call by value vs Call by reference

變數基本上有兩種. 一種是純值的value type, 一種是object/function的reference.(事實上function本質上也是個物件<https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function>)

一個function傳進去的變數叫做argument, function宣告及在內部使用的叫做parameter, 例子: <http://stackoverflow.com/questions/1788923/parameter-vs-argument>.

呼叫一個function時傳進去的變數跟function paramter的關係其實就是 **copy變數**: `var x= something; var y=x` 一樣. 以下例子.

```javascript
// copy value
var x = 5;
var y = x;
y = x;
y = 6;
console.log("x:", x); // 5
console.log("y:", y); // 6

// copy reference:
var x = {name:"google"};
var y = x;
y.name = "tesla";
console.log("x:", x); // name: "tesla"
console.log("y:", y); // name: "tesla"

// call by reference
function testChange(z){
  z.name = "microsoft";
}

testChange(x);
console.log("x:", x); // name: "microsoft"
```

## 物件變數傳進去function裡的注意事項

```javascript
function test1(obj){

  // 等於右邊建了個新的物件, 指給obj. 不管原本testObj是什麼值(就算不是null),  
  // 之後obj也都不會改變到testObj  
  obj = {name:"123"};
}

// 常見的assign(等於copy等於"=")整個物件變數的方法之一
function test2(obj){

  // obj = null, outside testObj = null;  
  obj = {name:"123"};
  return obj;
}

var testObj = null;
test1(testObj);
console.log(testObj); // still null

testObj = test2(); //不傳參數進去沒關係, JS的function可以接受參數個數不match.
console.log(testObj); // {name:"123"};
```

## 常見的改變物件變數其property的方法

```javascript
function test2(obj){
  obj.name = "abc"
}
var testObj = {}; //若是null, 傳進去裡面執行obj.name會有exception
test2(testObj);
console.log(testObj); // {name:"abc"}
```

## 字串 String

為JavaScript內建基本型別(primitive type)之一(C裡面沒有, C內建是char),` `` ` 跟 "" 都可以用來表示字串. 且JS裡字串為`value type`.

### substring

<http://www.w3schools.com/jsref/jsref_substring.asp>

```javascript
var str = "Hello world!";
var res = str.substring(1, 4); //(start, end), not includes end
// output: ell
```

## 變數檢查, ==, ===, typeof 檢查型別

`===` 這個operator 會同時會比較值跟type, `==` 只會比較值而已.

常見的初始值有下面幾種, 以下幾種的`===`都各不相等

1. `0`
2. `false`
3. `"0"`
4. `""` , `這前4個用 == 大部份都是true, 只有3&4的==不會等於true`
5. `null` ,`var x= null;常用來表示x是reference type但還未得到值`
6. `undefined` ,`var x;`, 宣告但沒有定義
7. `[]`
8. `{}`

```javascript
// empty array case
var a =[];
var b =0;
if(a==b){
  //will hit here
}
```

**檢查是那一種type**

```javascript
var d = "test";
console.log(typeof d); //string
if (typeof d == "string"){
  //will hit here
}

// 可用下面方法來run有值時的logic. 有時沒值是因為還留在初始化的狀態.
if(x){
  // 可以用這方式來檢查是否為 0,false,"0","",null, undefind,
  // 都不是才會進來.
}

// 但有個特殊case, 如果x這個變數沒有宣告過, 直接用會exception.可用下面方法

if (typeof x != 'undefined'){
  //如果只是未宣告, 則一定不會進來這邊.
}
```


---

# 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://lifeoverflow.gitbook.io/learning-javascript/javascript-es5-jiao-xue/javascript-ji-ben-te-xing-bian-shu.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.
