[toc]
## 算數表達式
1. **+運算符**
- 如果其中一個操作數是對象,則對象會遵循原始值的轉化規則轉換為原始值:日期對象通過toString()方法進行轉換,其他方法通過valueOf()方法進行轉換(如果valueOf返回一個原始值的話),大多數對象都不具備可用的valueof方法,因此它們會通過toString()方法來轉換
- 在對象進行原始值轉換后,如果一個操作數是字符串,那么另一個也會轉換成字符換進行字符串拼接
- 否則,兩個都轉換成數字(或者NaN)然后進行加法操作
2. **一元運算符**
遞增++運算符的返回值依賴于它相對于操作數的位置。當++在操作數之前則為**前增量**,在操作數之后為**后增量**。前增量返回計算后的值,**后增量則對操作數進行增量計算,但是返回的是未增量的值**。
```javascript
var a = 1,
b = ++a, //b=2
c = a++; //c=1
```
**++a并不等于a = a + 1, ++a只進行數字的累加**
```javascript
var a = '1',
b = '1';
++a; //2
b = b + 1; //'11'
```
## **eval**
eval()只有一個參數。如果傳入的參數不是字符串,它直接返回這個參數。如果參數是字符串,則會把字符串當做javascript代碼進行編譯,如果編譯失敗,則報出一個語法錯誤(SyntaxError)的異常。
如果編譯成功,則開始執行這段代碼,并返回字符串中最后一個表達式或者語句的值,如果沒有值則最終返回undefined。如果字符串拋出一個異常,這個異常則會把調用傳遞給eval()
**關于eval()最重要的是,它調用了使用了eval的變量作用域環境**
傳給eval()的字符串必須要在語法上講得通,比如eval('return;')是沒有意義的。
```javascript
var a = function(arg){
eval(arg)
};
a('return; ')
//會拋出語法錯誤
```
在es3中,eval是無法定義別名的,而在es5中,又放開了這個限制
當直接調用eval()時,執行的代碼在eval所處的上下文作用域中運行。
當使用別名調用eval()時,則是在全局作用域下執行。
```javascript
var geval = eval,
a = 'global',
b = 'global',
x = function(){
var a = 'local';
eval('a += " changed"');
return a
},
y = function(){
var b = 'local';
geval('b += " changed"');
return b;
};
console.log(x(), a); //更改局部變量, "local changed", "global"
console.log(y(), b); //更改全局變量, "local", "global changed"
```
**嚴格模式下的eval**
在嚴格模式下,eval執行的代碼不能在局部作用域中定義新的函數或變量,此外嚴格模式將“eval”列為保留字!