午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

箭頭函數(shù)

 wenxuefeng360 2022-11-05 發(fā)布于四川

箭頭函數(shù)表達(dá)式的語法比函數(shù)表達(dá)式更簡(jiǎn)潔,并且沒有自己的this,arguments,supernew.target。箭頭函數(shù)表達(dá)式更適用于那些本來需要匿名函數(shù)的地方,并且它不能用作構(gòu)造函數(shù)。

嘗試一下

語法

基礎(chǔ)語法

(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
//相當(dāng)于:(param1, param2, …, paramN) =>{ return expression; }

// 當(dāng)只有一個(gè)參數(shù)時(shí),圓括號(hào)是可選的:
(singleParam) => { statements }
singleParam => { statements }

// 沒有參數(shù)的函數(shù)應(yīng)該寫成一對(duì)圓括號(hào)。
() => { statements }

高級(jí)語法

//加括號(hào)的函數(shù)體返回對(duì)象字面量表達(dá)式:
params => ({foo: bar})

//支持剩余參數(shù)和默認(rèn)參數(shù)
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
statements }

//同樣支持參數(shù)列表解構(gòu)
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  // 6

描述

參考 "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

引入箭頭函數(shù)有兩個(gè)方面的作用:更簡(jiǎn)短的函數(shù)并且不綁定this。

更短的函數(shù)

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

elements.map(function(element) {
  return element.length;
}); // 返回?cái)?shù)組:[8, 6, 7, 9]

// 上面的普通函數(shù)可以改寫成如下的箭頭函數(shù)
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 當(dāng)箭頭函數(shù)只有一個(gè)參數(shù)時(shí),可以省略參數(shù)的圓括號(hào)
elements.map(element => {
 return element.length;
}); // [8, 6, 7, 9]

// 當(dāng)箭頭函數(shù)的函數(shù)體只有一個(gè) `return` 語句時(shí),可以省略 `return` 關(guān)鍵字和方法體的花括號(hào)
elements.map(element => element.length); // [8, 6, 7, 9]

// 在這個(gè)例子中,因?yàn)槲覀冎恍枰?`length` 屬性,所以可以使用參數(shù)解構(gòu)
// 需要注意的是字符串 `"length"` 是我們想要獲得的屬性的名稱,而 `lengthFooBArX` 則只是個(gè)變量名,
// 可以替換成任意合法的變量名
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

沒有單獨(dú)的this

在箭頭函數(shù)出現(xiàn)之前,每一個(gè)新函數(shù)根據(jù)它是被如何調(diào)用的來定義這個(gè)函數(shù)的 this 值:

  • 如果該函數(shù)是一個(gè)構(gòu)造函數(shù),this 指針指向一個(gè)新的對(duì)象
  • 在嚴(yán)格模式下的函數(shù)調(diào)用下,this 指向undefined
  • 如果該函數(shù)是一個(gè)對(duì)象的方法,則它的 this 指針指向這個(gè)對(duì)象
  • 等等

This被證明是令人厭煩的面向?qū)ο箫L(fēng)格的編程。

function Person() {
  // Person() 構(gòu)造函數(shù)定義 `this`作為它自己的實(shí)例。
  this.age = 0;

  setInterval(function growUp() {
    // 在非嚴(yán)格模式,growUp() 函數(shù)定義 `this`作為全局對(duì)象,
    // 與在 Person() 構(gòu)造函數(shù)中定義的 `this`并不相同。
    this.age++;
  }, 1000);
}

var p = new Person();

在 ECMAScript 3/5 中,通過將this值分配給封閉的變量,可以解決this問題。

function Person() {
  var that = this;
  that.age = 0;

  setInterval(function growUp() {
    // 回調(diào)引用的是`that`變量,其值是預(yù)期的對(duì)象。
    that.age++;
  }, 1000);
}

或者,可以創(chuàng)建綁定函數(shù),以便將預(yù)先分配的this值傳遞到綁定的目標(biāo)函數(shù)(上述示例中的growUp()函數(shù))。

箭頭函數(shù)不會(huì)創(chuàng)建自己的this,它只會(huì)從自己的作用域鏈的上一層繼承 this。因此,在下面的代碼中,傳遞給setInterval的函數(shù)內(nèi)的this與封閉函數(shù)中的this值相同:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 正確地指向 p 實(shí)例
  }, 1000);
}

var p = new Person();

與嚴(yán)格模式的關(guān)系

鑒于 this 是詞法層面上的,嚴(yán)格模式中與 this 相關(guān)的規(guī)則都將被忽略。

var f = () => { 'use strict'; return this; };
f() === window; // 或者 global

嚴(yán)格模式的其他規(guī)則依然不變。

通過 call 或 apply 調(diào)用

由于 箭頭函數(shù)沒有自己的 this 指針,通過 call() apply() 方法調(diào)用一個(gè)函數(shù)時(shí),只能傳遞參數(shù)(不能綁定 this---譯者注),他們的第一個(gè)參數(shù)會(huì)被忽略。(這種現(xiàn)象對(duì)于 bind 方法同樣成立 --- 譯者注)

var adder = {
  base : 1,

  add : function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base : 2
    };

    return f.call(b, a);
  }
};

console.log(adder.add(1));         // 輸出 2
console.log(adder.addThruCall(1)); // 仍然輸出 2

不綁定arguments

箭頭函數(shù)不綁定Arguments 對(duì)象。因此,在本示例中,arguments只是引用了封閉作用域內(nèi)的 arguments:

var arguments = [1, 2, 3];
var arr = () => arguments[0];

arr(); // 1

function foo(n) {
  var f = () => arguments[0] + n; // 隱式綁定 foo 函數(shù)的 arguments 對(duì)象。arguments[0] 是 n,即傳給 foo 函數(shù)的第一個(gè)參數(shù)
  return f();
}

foo(1); // 2
foo(2); // 4
foo(3); // 6
foo(3,2);//6

在大多數(shù)情況下,使用剩余參數(shù)是相較使用arguments對(duì)象的更好選擇。

function foo(arg) {
  var f = (...args) => args[0];
  return f(arg);
}
foo(1); // 1

function foo(arg1,arg2) {
    var f = (...args) => args[1];
    return f(arg1,arg2);
}
foo(1,2);  //2

使用箭頭函數(shù)作為方法

如上所述,箭頭函數(shù)表達(dá)式對(duì)非方法函數(shù)是最合適的。讓我們看看當(dāng)我們?cè)囍阉鼈冏鳛榉椒〞r(shí)發(fā)生了什么。

'use strict';
var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b();
// undefined, Window{...}
obj.c();
// 10, Object {...}

箭頭函數(shù)沒有定義 this 綁定。另一個(gè)涉及Object.defineProperty()的示例:

'use strict';
var obj = {
  a: 10
};

Object.defineProperty(obj, "b", {
  get: () => {
    console.log(this.a, typeof this.a, this);
    return this.a+10;
   // 代表全局對(duì)象 'Window', 因此 'this.a' 返回 'undefined'
  }
});

obj.b; // undefined   "undefined"   Window {postMessage: ?, blur: ?, focus: ?, close: ?, frames: Window, …}

使用 new 操作符

箭頭函數(shù)不能用作構(gòu)造器,和 new一起用會(huì)拋出錯(cuò)誤。

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

使用prototype屬性

箭頭函數(shù)沒有prototype屬性。

var Foo = () => {};
console.log(Foo.prototype); // undefined

使用 yield 關(guān)鍵字

yield 關(guān)鍵字通常不能在箭頭函數(shù)中使用(除非是嵌套在允許使用的函數(shù)內(nèi))。因此,箭頭函數(shù)不能用作函數(shù)生成器。

函數(shù)體

箭頭函數(shù)可以有一個(gè)“簡(jiǎn)寫體”或常見的“塊體”。

在一個(gè)簡(jiǎn)寫體中,只需要一個(gè)表達(dá)式,并附加一個(gè)隱式的返回值。在塊體中,必須使用明確的return語句。

var func = x => x * x;
// 簡(jiǎn)寫函數(shù) 省略 return

var func = (x, y) => { return x + y; };
//常規(guī)編寫 明確的返回值

返回對(duì)象字面量

記住用params => {object:literal}這種簡(jiǎn)單的語法返回對(duì)象字面量是行不通的。

var func = () => { foo: 1 };
// Calling func() returns undefined!

var func = () => { foo: function() {} };
// SyntaxError: function statement requires a name

這是因?yàn)榛ɡㄌ?hào)({} )里面的代碼被解析為一系列語句(即 foo 被認(rèn)為是一個(gè)標(biāo)簽,而非對(duì)象字面量的組成部分)。

所以,記得用圓括號(hào)把對(duì)象字面量包起來:

var func = () => ({foo: 1});

換行

箭頭函數(shù)在參數(shù)和箭頭之間不能換行。

var func = ()
           => 1;
// SyntaxError: expected expression, got '=>'

但是,可以通過在'=>’之后換行,或者用'( )’、'{ }'來實(shí)現(xiàn)換行,如下:

var func = (a, b, c) =>
  1;

var func = (a, b, c) => (
  1
);

var func = (a, b, c) => {
  return 1
};

var func = (
  a,
  b,
  c
) => 1;

// 不會(huì)有語法錯(cuò)誤

解析順序

雖然箭頭函數(shù)中的箭頭不是運(yùn)算符,但箭頭函數(shù)具有與常規(guī)函數(shù)不同的特殊運(yùn)算符優(yōu)先級(jí)解析規(guī)則。

let callback;

callback = callback || function() {}; // ok

callback = callback || () => {};
// SyntaxError: invalid arrow-function arguments

callback = callback || (() => {});    // ok

更多示例

// 空的箭頭函數(shù)返回 undefined
let empty = () => {};

(() => 'foobar')();
// Returns "foobar"
// (這是一個(gè)立即執(zhí)行函數(shù)表達(dá)式,可參閱 'IIFE'術(shù)語表)


var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

// Easy array filtering, mapping, ...

var arr = [5, 6, 13, 0, 1, 18, 23];

var sum = arr.reduce((a, b) => a + b);
// 66

var even = arr.filter(v => v % 2 == 0);
// [6, 0, 18]

var double = arr.map(v => v * 2);
// [10, 12, 26, 0, 2, 36, 46]

// 更簡(jiǎn)明的 promise 鏈
promise.then(a => {
  // ...
}).then(b => {
  // ...
});

// 無參數(shù)箭頭函數(shù)在視覺上容易分析
setTimeout( () => {
  console.log('I happen sooner');
  setTimeout( () => {
    // deeper code
    console.log('I happen later');
  }, 1);
}, 1);

箭頭函數(shù)也可以使用條件(三元)運(yùn)算符:

var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

箭頭函數(shù)內(nèi)定義的變量及其作用域

// 常規(guī)寫法
var greeting = () => {let now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
greeting();          //"Good day."
console.log(now);    // ReferenceError: now is not defined 標(biāo)準(zhǔn)的 let 作用域

// 參數(shù)括號(hào)內(nèi)定義的變量是局部變量(默認(rèn)參數(shù))
var greeting = (now=new Date()) => "Good" + (now.getHours() > 17 ? " evening." : " day.");
greeting();          //"Good day."
console.log(now);    // ReferenceError: now is not defined

// 對(duì)比:函數(shù)體內(nèi){}不使用 var 定義的變量是全局變量
var greeting = () => {now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
greeting();           //"Good day."
console.log(now);     // Fri Dec 22 2017 10:01:00 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間)

// 對(duì)比:函數(shù)體內(nèi){} 用 var 定義的變量是局部變量
var greeting = () => {var now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
greeting(); //"Good day."
console.log(now);    // ReferenceError: now is not defined

箭頭函數(shù)也可以使用閉包:

// 標(biāo)準(zhǔn)的閉包函數(shù)
function A(){
      var i=0;
      return function b(){
              return (++i);
      };
};

var v=A();
v();    //1
v();    //2


//箭頭函數(shù)體的閉包(i=0 是默認(rèn)參數(shù))
var Add = (i=0) => {return (() => (++i) )};
var v = Add();
v();           //1
v();           //2

//因?yàn)閮H有一個(gè)返回,return 及括號(hào)()也可以省略
var Add = (i=0)=> ()=> (++i);

箭頭函數(shù)遞歸

var fact = (x) => ( x==0 ?  1 : x*fact(x-1) );
fact(5);       // 120

規(guī)范

Specification
ECMAScript Language Specification
# sec-arrow-function-definitions

瀏覽器兼容性

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
Deno
Node.js
Arrow functions
Trailing comma in parameters

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Partial support
Partial support
No support
No support
See implementation notes.
User must explicitly enable this feature.

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多