JS文件歸納
在html中引入外部js檔案,並呼叫帶參
js檔案
html檔案
ES6規範引入了新的資料型別Map,Set
Map
是一組鍵值對的結構,具有極快的查詢速度。
- 用JavaScript寫一個Map如下:
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
例如:
初始化Map需要一個二維陣列,或者直接初始化一個空Map。Map具有以下方法:
var m = new Map(); // 空Map
m.set('Adam', 67 ); // 新增新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 刪除key 'Adam'
m.get('Adam'); // undefined
- 注:由於一個key只能對應一個value,所以,多次對一個key放入value,後面的值會把前面的值沖掉(覆蓋)
Set
和Map
類似,也是一組key的集合,但不儲存value。由於key不能重複,所以,在Set中,沒有重複的key。重複元素在Set中自動被過濾
var s = new Set ([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
- 通過
add(key)
方法可以新增元素到Set
中,可以重複新增,但不會有效果; - 通過
delete(key)
方法可以刪除元素;
為了統一集合型別,ES6標準引入了新的iterable型別,Array、Map和Set都屬於iterable型別。
- 具有
iterable型別的集合
可以通過新的for ... of
迴圈來遍歷。 for … of迴圈是ES6引入的新的語法
用for … of迴圈遍歷集合,用法如下:
var a = ['A', 'B', 'C'];
var s = new Set(['A' , 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍歷Array
console.log(x);
}
for (var x of s) { // 遍歷Set
console.log(x);
}
for (var x of m) { // 遍歷Map
console.log(x[0] + '=' + x[1]);
}
- 更好的方式是直接使用iterable內建的
forEach
方法,它接收一個函式,每次迭代就自動回撥該函式。
定義函式兩種方式
方式1:
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
方式2:
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
// 在這種方式下,function (x) { ... }是一個匿名函式,它沒有函式名。
但是,這個匿名函式賦值給了變數abs,所以,通過變數abs就可以呼叫該函式。
上述兩種定義完全等價
,注意第二種方式按照完整語法需要在函式體末尾加一個;,表示賦值語句結束。
JavaScript還有一個免費贈送的關鍵字arguments,它只在函式內部起作用,並且永遠指向當前函式的呼叫者傳入的所有引數。
- 在JavaScript中,用var申明的變數實際上是有作用域的。
- 如果兩個不同的函式各自申明瞭同一個變數,那麼該變數只在各自的函式體內起作用。換句話說,不同函式內部的同名變數互相獨立,互不影響;
- 由於JavaScript的函式可以巢狀,此時,內部函式可以訪問外部函式定義的變數,反過來則不行;
- 如果內部函式和外部函式的變數名重名,JavaScript的函式在查詢變數時從自身函式定義開始,從“內”向“外”查詢。如果內部函式定義了與外部函式重名的變數,則內部函式的變數將“遮蔽”外部函式的變數。
- 不在任何函式內定義的變數就具有
全域性作用域
。實際上,JavaScript預設有一個全域性物件window,全域性作用域的變數實際上被繫結到window的一個屬性(因此,直接訪問全域性變數XXX和訪問window.XXX是完全一樣的);- 由於函式定義有兩種方式,以變數方式var foo = function () {}定義的函式實際上也是一個全域性變數,因此,頂層函式的定義也被視為一個全域性變數,並繫結到window物件;
名字空間
~重點~
- 減少衝突的一個方法是把自己的所有變數和函式全部繫結到一個全域性變數中。例如:
// 唯一的全域性變數MYAPP:
var MYAPP = {};
// 其他變數:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函式:
MYAPP.foo = function () {
return 'foo';
};
繫結到物件上的函式稱為方法,和普通函式也沒啥區別
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
xiaoming.age(); // 25, 正常結果
getAge(); // NaN
拆開寫:
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年呼叫是25,明年呼叫就變成26了
在一個方法內部,this是一個特殊變數,它始終指向當前物件
JavaScript的函式內部如果呼叫了this,那麼這個this到底指向誰?
答案是,視情況而定!如果以物件的方法形式呼叫,比如xiaoming.age(),該函式的this指向被呼叫的物件,也就是xiaoming,這是符合我們預期的。
如果單獨呼叫函式,比如getAge(),此時,該函式的this指向全域性物件,也就是window。
- 用
var that = this;
,你就可以放心地在方法內部定義其他函式,而不是把所有語句都堆到一個方法中。
高階函式
map
函式
var f = function (x) {
return x * x;
};
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var result = [];
for (var i=0; i<arr.length; i++) {
result.push(f(arr[i]));
}
等價於如下:
function pow(x) {
return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce
函式
Array的reduce()
把一個函式作用在這個Array的 [x1, x2, x3...]
上,這個函式必須接收兩個引數,reduce()把結果繼續和序列的下一個元素做累積計算;
其效果就是:
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
例如:要把[1, 3, 5, 7, 9]變換成整數13579,reduce()也能派上用場
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x * 10 + y;
}); // 13579