1. 程式人生 > 其它 >資料庫的備份和還原

資料庫的備份和還原

一、基本語法

ES6中允許使用箭頭=>來定義箭頭函式,具體語法,我們來看一個簡單的例子:

// 箭頭函式
let fun = (name) => {
// 函式體
return `Hello ${name} !`;
};

// 等同於
let fun = function (name) {
// 函式體
return `Hello ${name} !`;
};

可以看出,定義箭頭函在數語法上要比普通函式簡潔得多。箭頭函式省去了function關鍵字,採用箭頭=>來定義函式。函式的引數放在=>前面的括號中,函式體跟在=>後的花括號中。

關於箭頭函式的引數:

如果箭頭函式沒有引數,直接寫一個空括號即可。

如果箭頭函式的引數只有一個,也可以省去包裹引數的括號。

如果箭頭函式有多個引數,將引數依次用逗號(,)分隔,包裹在括號中即可。

// 沒有引數
let fun1 = () => {
console.log(111);
};

// 只有一個引數,可以省去引數括號
let fun2 = name => {
console.log(`Hello ${name} !`)
};

// 有多個引數
let fun3 = (val1, val2, val3) => {
return [val1, val2, val3];
};

關於箭頭函式的函式體:

如果箭頭函式的函式體只有一句程式碼,就是簡單返回某個變數或者返回一個簡單的JS表示式,可以省去函式體的大括號{ }。

let f = val => val;
// 等同於
let f = function (val) { return val };

let sum = (num1, num2) => num1 + num2;
// 等同於
let sum = function(num1, num2) {
return num1 + num2;
};

如果箭頭函式的函式體只有一句程式碼,就是返回一個物件,可以像下面這樣寫:

// 用小括號包裹要返回的物件,不報錯
let getTempItem = id => ({ id: id, name: "Temp" });

// 但絕不能這樣寫,會報錯。
// 因為物件的大括號會被解釋為函式體的大括號
let getTempItem = id => { id: id, name: "Temp" };

如果箭頭函式的函式體只有一條語句並且不需要返回值(最常見是呼叫一個函式),可以給這條語句前面加一個void關鍵字

let fn = () => void doesNotReturn();

箭頭函式最常見的用處就是簡化回撥函式。

// 例子一
// 正常函式寫法
[1,2,3].map(function (x) {
return x * x;
});

// 箭頭函式寫法
[1,2,3].map(x => x * x);

// 例子二
// 正常函式寫法
var result = [2, 5, 1, 4, 3].sort(function (a, b) {
return a - b;
});

// 箭頭函式寫法
var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);

二、箭頭函式與普通函式的區別

1、語法更加簡潔、清晰

從上面的基本語法示例中可以看出,箭頭函式的定義要比普通函式定義簡潔、清晰得多,很快捷。

2、箭頭函式不會建立自己的this(重要!!深入理解!!)

我們先來看看MDN上對箭頭函式this的解釋。

箭頭函式不會建立自己的this,所以它沒有自己的this,它只會從自己的作用域鏈的上一層繼承this。

箭頭函式沒有自己的this,它會捕獲自己在定義時(注意,是定義時,不是呼叫時)所處的外層執行環境的this,並繼承這個this值。所以,箭頭函式中this的指向在它被定義的時候就已經確定了,之後永遠不會改變。

來看個例子:

var id = 'Global';

function fun1() {
// setTimeout中使用普通函式
setTimeout(function(){
console.log(this.id);
}, 2000);
}

function fun2() {
// setTimeout中使用箭頭函式
setTimeout(() => {
console.log(this.id);
}, 2000)
}

fun1.call({id: 'Obj'}); // 'Global'

fun2.call({id: 'Obj'}); // 'Obj'

上面這個例子,函式fun1中的setTimeout中使用普通函式,2秒後函式執行時,這時函式其實是在全域性作用域執行的,所以this指向Window物件,this.id就指向全域性變數id,所以輸出'Global' 但是函式fun2中的setTimeout中使用的是箭頭函式,這個箭頭函式的this在定義時就確定了,它繼承了它外層fun2的執行環境中的this,而fun2呼叫時thiscall方法改變到了物件{id: 'Obj'}中,所以輸出'Obj'

再來看另一個例子:

var id = 'GLOBAL';
var obj = {
id: 'OBJ',
a: function(){
console.log(this.id);
},
b: () => {
console.log(this.id);
}
};

obj.a(); // 'OBJ'
obj.b(); // 'GLOBAL'

上面這個例子,物件obj的方法a使用普通函式定義的,普通函式作為物件的方法呼叫時,this指向它所屬的物件。所以,this.id就是obj.id,所以輸出'OBJ' 但是方法b是使用箭頭函式定義的,箭頭函式中的this實際是繼承的它定義時所處的全域性執行環境中的this,所以指向Window物件,所以輸出'GLOBAL'。(這裡要注意,定義物件的大括號{}是無法形成一個單獨的執行環境的,它依舊是處於全域性執行環境中!!

3、箭頭函式繼承而來的this指向永遠不變(重要!!深入理解!!)

上面的例子,就完全可以說明箭頭函式繼承而來的this指向永遠不變。物件obj的方法b是使用箭頭函式定義的,這個函式中的this永遠指向它定義時所處的全域性執行環境中的this,即便這個函式是作為物件obj的方法呼叫,this依舊指向Window物件。

4、.call()/.apply()/.bind()無法改變箭頭函式中this的指向

.call()/.apply()/.bind()方法可以用來動態修改函式執行時this的指向,但由於箭頭函式的this定義時就已經確定且永遠不會改變。所以使用這些方法永遠也改變不了箭頭函式this的指向,雖然這麼做程式碼不會報錯。

var id = 'Global';
// 箭頭函式定義在全域性作用域
let fun1 = () => {
console.log(this.id)
};

fun1(); // 'Global'
// this的指向不會改變,永遠指向Window物件
fun1.call({id: 'Obj'}); // 'Global'
fun1.apply({id: 'Obj'}); // 'Global'
fun1.bind({id: 'Obj'})(); // 'Global'

5、箭頭函式不能作為建構函式使用

我們先了解一下建構函式的new都做了些什麼?簡單來說,分為四步:

① JS內部首先會先生成一個物件;

② 再把函式中的this指向該物件;

③ 然後執行建構函式中的語句;

④ 最終返回該物件例項。

但是!!因為箭頭函式沒有自己的this,它的this其實是繼承了外層執行環境中的this,且this指向永遠不會隨在哪裡呼叫、被誰呼叫而改變,所以箭頭函式不能作為建構函式使用,或者說建構函式不能定義成箭頭函式,否則用new呼叫時會報錯!

let Fun = (name, age) => {
this.name = name;
this.age = age;
};

// 報錯
let p = new Fun('cao', 24);

6、箭頭函式沒有自己的arguments

箭頭函式沒有自己的arguments物件。在箭頭函式中訪問arguments實際上獲得的是外層區域性(函式)執行環境中的值。

// 例子一
let fun = (val) => {
console.log(val); // 111
// 下面一行會報錯
// Uncaught ReferenceError: arguments is not defined
// 因為外層全域性環境沒有arguments物件
console.log(arguments);
};
fun(111);

// 例子二
function outer(val1, val2) {
let argOut = arguments;
console.log(argOut); // ①
let fun = () => {
let argIn = arguments;
console.log(argIn); // ②
console.log(argOut === argIn); // ③
};
fun();
}
outer(111, 222);

上面例子二,①②③處的輸出結果如下:

很明顯,普通函式outer內部的箭頭函式fun中的arguments物件,其實是沿作用域鏈向上訪問的外層outer函式的arguments物件。

可以在箭頭函式中使用rest引數代替arguments物件,來訪問箭頭函式的引數列表!!

7、箭頭函式沒有原型prototype

let sayHi = () => {
console.log('Hello World !')
};
console.log(sayHi.prototype); // undefined

8、箭頭函式不能用作Generator函式,不能使用yeild關鍵字