JavaScript學習筆記00

sstd521發表於2016-09-23

JavaScript 是一種弱型別的語言。

型別

enter image description here

  • JavaScript 中的變數是沒有型別,值有才型別,變數持有值的型別,型別定義了值的行為特徵。
  • 對變數執行typeof操作時,得到的是該變數持有的值的型別。
  • typeof運算子總會返回一個字串。
typeof typeof 42; // "string"

typeof 42 首先返回一個字串 "number",然後typeof "number",返回 "string"

在作用域中宣告但還沒有賦值的變數為undefined,是值的一種,沒有在作用域中宣告過的變數為undeclared,兩個不可混為一談。

陣列與字串

對陣列宣告後即可向其加入值,無需預先指定陣列大小。

var arr = [ ];
arr.length; // 0
a[0] = 1;
a[1] = "2";
a[2] = [3];
a.length; // 3

陣列不僅可以通過數字下標作為索引,也可以用包含字串鍵值和屬性,但這些不計入陣列長度內。

var arr = [ ];

a[0] = "2";
a[1] = 20;
arr.length; // 
a["apple"] = 1;
a.length; // 2
a["apple"] = 1;
a.apple = 1;

如果字串鍵值可以被強制型別轉換為十進位制數字的話,依舊會被當做數字索引來處理。

var arr = [ ];
a["13"] = 22;
a.lenth; // 14

不建議在陣列中加入字串作為下標,建議使用數字下標。 JavaScript 中的字串是不可變的,而陣列可變。字串不可變是指字串的成員函式不會改變其原始值,而是建立並返回一個新的字串。

字串反轉:

var chars = "ufo";
var reverseChars = chars.split("").reverse().join("")//ofu

chars.split("")將字串轉換為字元陣列,.reverse()將陣列中的字元逆序排序,.join("")將陣列中的字元拼接回字串

數字

JavaScript 中只有一種數值型別:number(數字),包括十進位制的小數和沒有小數的整數。

數字語法

數字前面的0和小數點後最後面的0可以省略,但不建議這樣寫。

var num = .42;
var num = 42.;

tofixed(..),可以指定小數部分顯示的位數,輸出結果為字串形式。 toprecision(..),用來指定有效位數。

var num = 13.1341;
num.tofixed(3); // "13.134"
num.toprecision(4); // "13.13"
(42).tofixed(3); // "42.000"
42..tofixed(3); // "42.000"  罕見
0.42.tofixed(3); // "0.420" 罕見
42.tofixed(3); // 語法錯誤,相當於(42)tofixed(3);
42 .tofixed(3); // "42.000"  不推薦

進位制,從ES6開始採用嚴格模式(strict mode),為了程式碼的易讀性,建議使用小寫的0b、0o、0x代表二進位制、八進位制和十六進位制。

整數檢測

檢測一個數是否為整數

Number.isInteger(42.0); // true

檢測一個數是否為安全的整數(最大值為 Number.MAX_SAFE_NTEGER == Math.pow(2,53)-1 )

Number.isSafeInteger(Math.pow(2,53)-1); // true

特殊數值

不是值的值
  • undefined 資料型別只有一個的值,即 undefined,表示沒有值、從未賦值,通過void 運算子即可得到該值。

  • null 型別也只有一個值,即 null,表示空值,目前沒有值。

兩者常用來表示"空值"或"不是值"的值。

特殊的數字
  • 不是數字的數字NaN(not a number),也可理解為"無效數值"、"壞數值"。NaN 是一個特殊值,它和自身不相等,是唯一一個非自反值(即x===x不成立),而NaN != NaNtrue。“不是數字的數字”仍然是數字型別。

如果需要判斷一個值是否是NaN,建議使用Number.isNaN(..)

if(!Number.isNaN){
Number.isNaN = function(n) {
return n !== n;
};
}
var a = 2 / "foo";
var b = "foo";
Number.isNaN( a ); // true
  • 無窮數,相對於 InfinityNumber.MAX_ VALUE + Math.pow(2, 969)Number.MAX_VALUE 更為接近,因此它被“向下取整”( round down);而 Number.MAX_VALUE + Math.pow(2, 970)Infinity 更為接近,所以它被“向上取整”( round up)。
var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity
  • 零值,加法和減法運算不會得到負零( negative zero)。根據規範,對負零進行字串化會返回 "0",將其從字串轉換為數字,得到的結果是準確的。-0==0-0===0,都為true,ES6 中新加入了一個工具方法 Object.is(..) 來判斷兩個值是否絕對相等。
var a = 0 / -3; // -0
var b = 2/"foo" ; // NaN
// 但是規範定義的返回結果是這樣!
a.toString(); // "0"
a + ""; // "0"
String( a ); // "0"
JSON.stringify( a ); // "0"

+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0

Object.is( b, NaN ); // true
Object.is( a, -0 ); // true
Object.is( a, 0 ); // false

值和引用

簡單值(即標量基本型別值, scalar primitive) 總是通過值複製的方式來賦值 / 傳遞,包括 nullundefined、字串、數字、布林和 ES6 中的 symbol

複合值( compound value)——物件(包括陣列和封裝物件)和函式,則總是通過引用複製的方式來賦值 / 傳遞。

引用指向的是值本身而非變數,所以一個引用無法更改另一個引用的指向。我們無法自行決定用值複製還是引用複製,一切都由值的型別來決定。

Arr.slice() 不帶引數會返回當前陣列的一個淺複本( shallow copy)。由於傳遞給函式的是指向該複本的引用,所以 foo(Arr.slice(..)) 中的操作不會影響 Arr 指向的陣列。

var a = [1,2,3];
var b = a;
a; // [1,2,3]
b; // [1,2,3]
// 然後
b = [4,5,6];
a; // [1,2,3]
b; // [4,5,6]

標量基本型別值是不可更改的(字串和布林也是如此)。如果一個數字物件的標 量基本型別值是 2,那麼該值就不能更改,除非建立一個包含新值的數字物件。

function foo(x) {
x = x + 1;
x; // 3
}
var a = 2;
var b = new Number( a ); // Object(a)也一樣
foo( b );
console.log( b ); // 是2,不是3

function foo(wrapper) {
wrapper.a = 42;
}
var obj = {
a: 2
};
foo( obj );
obj.a; // 42

相關文章