1. 程式人生 > >20181203——阮一峰Js淺略閱讀查缺補漏 基本語法 資料型別 數值 字串 物件 陣列

20181203——阮一峰Js淺略閱讀查缺補漏 基本語法 資料型別 數值 字串 物件 陣列

語句
JavaScript 程式的執行單位為行(line),也就是一行一行地執行。一般情況下,每一行就是一個語句。
語句(statement)是為了完成某種任務而進行的操作,比如下面就是一行賦值語句。

var a =1+3

1 + 3叫做表示式(expression),指一個為了得到返回值的計算式。語句和表示式的區別在於,前者主要為了進行某種操作,一般情況下不需要返回值;後者則是為了得到返回值,一定會返回一個值。

變數
變數是對“值”的具名引用。變數就是為“值”起名,然後引用這個名字,就等同於引用這個值。變數的名字就是變數名。
JavaScript 是一種動態型別語言,也就是說,變數的型別沒有限制,變數可以隨時更改型別。

var a = 1;
a = 'hello';

上面程式碼中,變數a起先被賦值為一個數值,後來又被重新賦值為一個字串。第二次賦值的時候,因為變數a已經存在,所以不需要使用var命令。

如果使用var重新宣告一個已經存在的變數,是無效的。

var x = 1;
var x;
x // 1

變數提升
JavaScript 引擎的工作方式是,先解析程式碼,獲取所有被宣告的變數,然後再一行一行地執行。這造成的結果,就是所有的變數的宣告語句,都會被提升到程式碼的頭部,這就叫做變數提升(hoisting)。

識別符號
第一個字元,可以是任意 Unicode 字母(包括英文字母和其他語言的字母),以及美元符號($)和下劃線(_)。
第二個字元及後面的字元,除了 Unicode 字母、美元符號和下劃線,還可以用數字0-9

條件語句
三元運算子 ?:
迴圈語句
break 語句和 continue 語句

資料型別
JavaScript 語言的每一個值,都屬於某一種資料型別。JavaScript 的資料型別,共有六種。(ES6 又新增了第七種 Symbol 型別的值,本教程不涉及。)
數值(number):整數和小數(比如1和3.14)
字串(string):文字(比如Hello World)。
布林值(boolean):表示真偽的兩個特殊值,即true(真)和false(假)
undefined:表示“未定義”或不存在,即由於目前沒有定義,所以此處暫時沒有任何值
null:表示空值,即此處的值為空。
物件(object):各種值組成的集合。

typeof 運算子
上面程式碼中,空陣列([])的型別也是object,這表示在 JavaScript 內部,陣列本質上只是一種特殊的物件。這裡順便提一下,instanceof運算子可以區分陣列和物件。instanceof運算子的詳細解釋,請見《面向物件程式設計》一章。

null 和 undefined

// 變數聲明瞭,但沒有賦值
var i;
i // undefined

// 呼叫函式時,應該提供的引數沒有提供,該引數等於 undefined
function f(x) {
  return x;
}
f() // undefined

// 物件沒有賦值的屬性
var  o = new Object();
o.p // undefined

// 函式沒有返回值時,預設返回 undefined
function f() {}
f() // undefined

物件
物件(object)是 JavaScript 語言的核心概念,也是最重要的資料型別。

什麼是物件?簡單說,物件就是一組“鍵值對”(key-value)的集合,是一種無序的複合資料集合。

物件的每一個鍵名又稱為“屬性”(property),它的“鍵值”可以是任何資料型別。如果一個屬性的值為函式,通常把這個屬性稱為“方法”,它可以像函式那樣呼叫。

var obj = {
  p: function (x) {
    return 2 * x;
  }
};

obj.p(1) // 2

上面程式碼中,物件obj的屬性p,就指向一個函式。

如果屬性的值還是一個物件,就形成了鏈式引用。

var o1 = {};
var o2 = { bar: 'hello' };

o1.foo = o2;
o1.foo.bar // "hello"

物件的引用
如果不同的變數名指向同一個物件,那麼它們都是這個物件的引用,也就是說指向同一個記憶體地址。修改其中一個變數,會影響到其他所有變數。

var o1 = {};
var o2 = o1;

o1.a = 1;
o2.a // 1

o2.b = 2;
o1.b // 2

上面程式碼中,o1和o2指向同一個物件,因此為其中任何一個變數新增屬性,另一個變數都可以讀寫該屬性。

此時,如果取消某一個變數對於原物件的引用,不會影響到另一個變數。

var o1 = {};
var o2 = o1;

o1 = 1;
o2 // {}

上面程式碼中,o1和o2指向同一個物件,然後o1的值變為1,這時不會對o2產生影響,o2還是指向原來的那個物件。

但是,這種引用只侷限於物件,如果兩個變數指向同一個原始型別的值。那麼,變數這時都是值的拷貝。

var x = 1;
var y = x;

x = 2;
y // 1

讀取屬性

var obj = {
  p: 'Hello World'
};

obj.p // "Hello World"
obj['p'] // "Hello World"

上面程式碼分別採用點運算子和方括號運算子,讀取屬性p。

請注意,如果使用方括號運算子,鍵名必須放在引號裡面,否則會被當作變數處理。

var foo = 'bar';

var obj = {
  foo: 1,
  bar: 2
};

obj.foo  // 1
obj[foo]  // 2

上面程式碼中,物件obj的數字鍵0.7,加不加引號都可以,因為會被自動轉為字串。

注意,數值鍵名不能使用點運算子(因為會被當成小數點),只能使用方括號運算子。

var obj = {
  123: 'hello world'
};

obj.123 // 報錯
obj[123] // "hello world"

屬性的賦值

var obj = {};

obj.foo = 'Hello';
obj['bar'] = 'World';

上面程式碼中,分別使用點運算子和方括號運算子,對屬性賦值。

JavaScript 允許屬性的“後繫結”,也就是說,你可以在任意時刻新增屬性,沒必要在定義物件的時候,就定義好屬性。

var obj = { p: 1 };

// 等價於

var obj = {};
obj.p = 1;

檢視所有屬性
檢視一個物件本身的所有屬性,可以使用Object.keys方法。

var obj = {
  key1: 1,
  key2: 2
};

Object.keys(obj);
// ['key1', 'key2']

delete 命令

var obj = { p: 1 };
Object.keys(obj) // ["p"]

delete obj.p // true
obj.p // undefined
Object.keys(obj) // []

for…in 迴圈

var obj = {a: 1, b: 2, c: 3};

for (var i in obj) {
  console.log(obj[i]);
}
// 1
// 2
// 3

with 語句

with (物件) {
  語句;
}
var obj = {
  p1: 1,
  p2: 2,
};
with (obj) {
  p1 = 4;
  p2 = 5;
}
// 等同於
obj.p1 = 4;
obj.p2 = 5;

// 例二
with (document.links[0]){
  console.log(href);
  console.log(title);
  console.log(style);
}
// 等同於
console.log(document.links[0].href);
console.log(document.links[0].title);
console.log(document.links[0].style);

注意,如果with區塊內部有變數的賦值操作,必須是當前物件已經存在的屬性,否則會創造一個當前作用域的全域性變數。

var obj = {};
with (obj) {
  p1 = 4;
  p2 = 5;
}

obj.p1 // undefined
p1 // 4

陣列
任何型別的資料,都可以放入陣列。

var arr = [
  {a: 1},
  [1, 2, 3],
  function() {return true;}
];

arr[0] // Object {a: 1}
arr[1] // [1, 2, 3]
arr[2] // function (){return true;}

值得注意的是,由於陣列本質上是一種物件,所以可以為陣列新增屬性,但是這不影響length屬性的值。

var a = [];

a['p'] = 'abc';
a.length // 0

a[2.1] = 'abc';
a.length // 0

上面程式碼將陣列的鍵分別設為字串和小數,結果都不影響length屬性。因為,length屬性的值就是等於最大的數字鍵加1,而這個陣列沒有整數鍵,所以length屬性保持為0。


函式的宣告
(1)function 命令

function命令宣告的程式碼區塊,就是一個函式。function命令後面是函式名,函式名後面是一對圓括號,裡面是傳入函式的引數。函式體放在大括號裡面。

function print(s) {
  console.log(s);
}

上面的程式碼命名了一個print函式,以後使用print()這種形式,就可以呼叫相應的程式碼。這叫做函式的宣告(Function Declaration)。
(2)函式表示式
除了用function命令宣告函式,還可以採用變數賦值的寫法。

var print = function(s) {
  console.log(s);
};