国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

論普通函數(shù)和箭頭函數(shù)的區(qū)別以及箭頭函數(shù)的注意事項(xiàng)、不適用場(chǎng)景

paulquei / 2579人閱讀

摘要:第二種情況是箭頭函數(shù)的如果指向普通函數(shù)它的繼承于該普通函數(shù)。箭頭函數(shù)的指向全局,使用會(huì)報(bào)未聲明的錯(cuò)誤。

箭頭函數(shù)是ES6的API,相信很多人都知道,因?yàn)槠湔Z法上相對(duì)于普通函數(shù)更簡潔,深受大家的喜愛。就是這種我們?nèi)粘i_發(fā)中一直在使用的API,大部分同學(xué)卻對(duì)它的了解程度還是不夠深...

普通函數(shù)和箭頭函數(shù)的區(qū)別: 箭頭函數(shù)的this指向規(guī)則: 1. 箭頭函數(shù)沒有prototype(原型),所以箭頭函數(shù)本身沒有this
let a = () =>{};
console.log(a.prototype); // undefined
2. 箭頭函數(shù)的this指向在定義的時(shí)候繼承自外層第一個(gè)普通函數(shù)的this。

下面栗子中在一個(gè)函數(shù)中定義箭頭函數(shù),然后在另一個(gè)函數(shù)中執(zhí)行箭頭函數(shù)。

let a,
  barObj = { msg: "bar的this指向" };
fooObj = { msg: "foo的this指向" };
bar.call(barObj); // 將bar的this指向barObj
foo.call(fooObj); // 將foo的this指向fooObj
function foo() {
  a(); // 結(jié)果:{ msg: "bar的this指向" }
}
function bar() {
  a = () => {
    console.log(this, "this指向定義的時(shí)候外層第一個(gè)普通函數(shù)"); // 
  }; // 在bar中定義 this繼承于bar函數(shù)的this指向
}

從上面栗子中可以得出兩點(diǎn)

箭頭函數(shù)的this指向定義時(shí)所在的外層第一個(gè)普通函數(shù),跟使用位置沒有關(guān)系

被繼承的普通函數(shù)的this指向改變,箭頭函數(shù)的this指向會(huì)跟著改變

3. 不能直接修改箭頭函數(shù)的this指向

上個(gè)栗子中的foo函數(shù)修改一下,嘗試直接修改箭頭函數(shù)的this指向。

let fnObj = { msg: "嘗試直接修改箭頭函數(shù)的this指向" };
function foo() {
  a.call(fnObj); // 結(jié)果:{ msg: "bar的this指向" }
}

很明顯,call顯示綁定this指向失敗了,包括aaply、bind都一樣。

它們(call、aaply、bind)會(huì)默認(rèn)忽略第一個(gè)參數(shù),但是可以正常傳參。

然后我又通過隱式綁定來嘗試同樣也失敗了,new 調(diào)用會(huì)報(bào)錯(cuò),這個(gè)稍后再說。

SO,箭頭函數(shù)不能直接修改它的this指向

幸運(yùn)的是,我們可以通過間接的形式來修改箭頭函數(shù)的指向:

去修改被繼承的普通函數(shù)的this指向,然后箭頭函數(shù)的this指向也會(huì)跟著改變,這在上一個(gè)栗子中有演示。

bar.call(barObj); // 將bar普通函數(shù)的this指向barObj 然后內(nèi)部的箭頭函數(shù)也會(huì)指向barObj
4. 箭頭函數(shù)外層沒有普通函數(shù),嚴(yán)格模式和非嚴(yán)格模式下它的this都會(huì)指向window(全局對(duì)象)
唔,這個(gè)問題實(shí)際上是面試官提出來的,當(dāng)時(shí)我認(rèn)為的箭頭函數(shù)規(guī)則就是:箭頭函數(shù)的this指向繼承自外層第一個(gè)普通函數(shù)的this,現(xiàn)在看來真是不嚴(yán)謹(jǐn)(少說一個(gè)定義的時(shí)候),要是面試官問我:定義和執(zhí)行不在同一個(gè)普通函數(shù)中,它又指向哪里,肯定歇菜...

既然箭頭函數(shù)的this指向在定義的時(shí)候繼承自外層第一個(gè)普通函數(shù)的this,那么:

當(dāng)箭頭函數(shù)外層沒有普通函數(shù),它的this會(huì)指向哪里

這里跟我之前寫的this綁定規(guī)則不太一樣(不懂的可以點(diǎn)進(jìn)去看一下),普通函數(shù)的默認(rèn)綁定規(guī)則是:

在非嚴(yán)格模式下,默認(rèn)綁定的this指向全局對(duì)象,嚴(yán)格模式下this指向undefined

如果箭頭函數(shù)外層沒有普通函數(shù)繼承,它this指向的規(guī)則

經(jīng)過測(cè)試,箭頭函數(shù)在全局作用域下,嚴(yán)格模式和非嚴(yán)格模式下它的this都會(huì)指向window(全局對(duì)象)

Tip:測(cè)試的時(shí)候發(fā)現(xiàn)嚴(yán)格模式在中途聲明無效,必須在全局/函數(shù)的開頭聲明才會(huì)生效

a = 1;
"use strict"; // 嚴(yán)格模式無效 必須在一開始就聲明嚴(yán)格模式
b = 2; // 不報(bào)錯(cuò)
箭頭函數(shù)的 箭頭函數(shù)的arguments 箭頭函數(shù)的this指向全局,使用arguments會(huì)報(bào)未聲明的錯(cuò)誤

如果箭頭函數(shù)的this指向window(全局對(duì)象)使用arguments會(huì)報(bào)錯(cuò),未聲明arguments

let b = () => {
  console.log(arguments);
};
b(1, 2, 3, 4); // Uncaught ReferenceError: arguments is not defined

PS:如果你聲明了一個(gè)全局變量為arguments,那就不會(huì)報(bào)錯(cuò)了,但是你為什么要這么做呢?

箭頭函數(shù)的this指向普通函數(shù)時(shí),它的argumens繼承于該普通函數(shù)

上面是第一種情況:箭頭函數(shù)的this指向全局對(duì)象,會(huì)報(bào)arguments未聲明的錯(cuò)誤。

第二種情況是:箭頭函數(shù)的this如果指向普通函數(shù),它的argumens繼承于該普通函數(shù)。

function bar() {
  console.log(arguments); // ["外層第二個(gè)普通函數(shù)的參數(shù)"]
  bb("外層第一個(gè)普通函數(shù)的參數(shù)");
  function bb() {
    console.log(arguments); // ["外層第一個(gè)普通函數(shù)的參數(shù)"]
    let a = () => {
      console.log(arguments, "arguments繼承this指向的那個(gè)普通函數(shù)"); // ["外層第一個(gè)普通函數(shù)的參數(shù)"]
    };
    a("箭頭函數(shù)的參數(shù)"); // this指向bb
  }
}
bar("外層第二個(gè)普通函數(shù)的參數(shù)");

那么應(yīng)該如何來獲取箭頭函數(shù)不定數(shù)量的參數(shù)呢?答案是:ES6的rest參數(shù)(...擴(kuò)展符)

rest參數(shù)獲取函數(shù)的多余參數(shù)

這是ES6的API,用于獲取函數(shù)不定數(shù)量的參數(shù)數(shù)組,這個(gè)API是用來替代arguments的,API用法如下:

let a = (first, ...abc) => {
  console.log(first, abc); // 1 [2, 3, 4]
};
a(1, 2, 3, 4);

上面的栗子展示了,獲取函數(shù)除第一個(gè)確定的參數(shù),以及用一個(gè)變量接收其他剩余參數(shù)的示例。

也可以直接接收函數(shù)的所有參數(shù),rest參數(shù)的用法相對(duì)于arguments的優(yōu)點(diǎn):

箭頭函數(shù)和普通函數(shù)都可以使用。

更加靈活,接收參數(shù)的數(shù)量完全自定義。

可讀性更好

參數(shù)都是在函數(shù)括號(hào)中定義的,不會(huì)突然出現(xiàn)一個(gè)arguments,以前剛見到的時(shí)候,真的好奇怪了!

rest是一個(gè)真正的數(shù)組,可以使用數(shù)組的API。

因?yàn)?b>arguments是一個(gè)類數(shù)組的對(duì)象,有些人以為它是真正的數(shù)組,所以會(huì)出現(xiàn)以下場(chǎng)景:

arguments.push(0); // arguments.push is not a function

如上,如果我們需要使用數(shù)組的API,需要使用擴(kuò)展符/Array.from來將它轉(zhuǎn)換成真正的數(shù)組:

arguments = [...arguments]; 或者 :arguments = Array.from(arguments);

rest參數(shù)有兩點(diǎn)需要注意

rest必須是函數(shù)的最后一位參數(shù):

let a = (first, ...rest, three) => {
  console.log(first, rest,three); // 報(bào)錯(cuò):Rest parameter must be last formal parameter
};
a(1, 2, 3, 4);

函數(shù)的length屬性,不包括 rest 參數(shù)

(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1

擴(kuò)展運(yùn)算符還可以用于數(shù)組,這里是阮一峰老師的文檔

PS:感覺這里寫多了,但比較喜歡把一個(gè)知識(shí)點(diǎn)講清楚...

使用new調(diào)用箭頭函數(shù)會(huì)報(bào)錯(cuò)

無論箭頭函數(shù)的thsi指向哪里,使用new調(diào)用箭頭函數(shù)都會(huì)報(bào)錯(cuò),因?yàn)榧^函數(shù)沒有constructor

let a = () => {};
let b = new  a(); // a is not a constructor
箭頭函數(shù)不支持new.target

new.target是ES6新引入的屬性,普通函數(shù)如果通過new調(diào)用,new.target會(huì)返回該函數(shù)的引用。

此屬性主要:用于確定構(gòu)造函數(shù)是否為new調(diào)用的。

箭頭函數(shù)的this指向全局對(duì)象,在箭頭函數(shù)中使用箭頭函數(shù)會(huì)報(bào)錯(cuò)

let a = () => {
  console.log(new.target); // 報(bào)錯(cuò):new.target 不允許在這里使用
};
a();

箭頭函數(shù)的this指向普通函數(shù),它的new.target就是指向該普通函數(shù)的引用。

new bb();
function bb() {
  let a = () => {
    console.log(new.target); // 指向函數(shù)bb:function bb(){...}
  };
  a();
}

更多關(guān)于new.target可以看一下阮一峰老師關(guān)于這部分的解釋。

箭頭函數(shù)不支持重命名函數(shù)參數(shù),普通函數(shù)的函數(shù)參數(shù)支持重命名

如下示例,普通函數(shù)的函數(shù)參數(shù)支持重命名,后面出現(xiàn)的會(huì)覆蓋前面的,箭頭函數(shù)會(huì)拋出錯(cuò)誤:

function func1(a, a) {
  console.log(a, arguments); // 2 [1,2]
}

var func2 = (a,a) => {
  console.log(a); // 報(bào)錯(cuò):在此上下文中不允許重復(fù)參數(shù)名稱
};
func1(1, 2); func2(1, 2);
箭頭函數(shù)相對(duì)于普通函數(shù)語法更簡潔優(yōu)雅:

講道理,語法上的不同,也屬與它們兩個(gè)的區(qū)別!

箭頭函數(shù)都是匿名函數(shù),并且都不用寫function

只有一個(gè)參數(shù)的時(shí)候可以省略括號(hào):

var f = a => a; // 傳入a 返回a

函數(shù)只有一條語句時(shí)可以省略{}return

var f = (a,b,c) => a; // 傳入a,b,c 返回a

簡化回調(diào)函數(shù),讓你的回調(diào)函數(shù)更優(yōu)雅:

[1,2,3].map(function (x) {
  return x * x;
}); // 普通函數(shù)寫法 
[1,2,3].map(x => x * x); // 箭頭函數(shù)只需要一行
箭頭函數(shù)的注意事項(xiàng)及不適用場(chǎng)景 箭頭函數(shù)的注意事項(xiàng)

一條語句返回對(duì)象字面量,需要加括號(hào),或者直接寫成多條語句的return形式,

否則像func中演示的一樣,花括號(hào)會(huì)被解析為多條語句的花括號(hào),不能正確解析

var func1 = () => { foo: 1 }; // 想返回一個(gè)對(duì)象,花括號(hào)被當(dāng)成多條語句來解析,執(zhí)行后返回undefined
var func2 = () => ({foo: 1}); // 用圓括號(hào)是正確的寫法
var func2 = () => {
  return {
    foo: 1 // 更推薦直接當(dāng)成多條語句的形式來寫,可讀性高
  };
};

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

var func = ()
           => 1;  // 報(bào)錯(cuò): Unexpected token =>

箭頭函數(shù)的解析順序相對(duì)靠前

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

let a = false || function() {}; // ok
let b = false || () => {}; // Malformed arrow function parameter list
let c = false || (() => {}); // ok
箭頭函數(shù)不適用場(chǎng)景:

圍繞兩點(diǎn):箭頭函數(shù)的this意外指向和代碼的可讀性。

定義字面量方法,this的意外指向。

因?yàn)榧^函數(shù)的簡潔

const obj = {
  array: [1, 2, 3],
  sum: () => {
    // 根據(jù)上文學(xué)到的:外層沒有普通函數(shù)this會(huì)指向全局對(duì)象
    return this.array.push("全局對(duì)象下沒有array,這里會(huì)報(bào)錯(cuò)"); // 找不到push方法
  }
};
obj.sum();

上述栗子使用普通函數(shù)或者ES6中的方法簡寫的來定義方法,就沒有問題了:

// 這兩種寫法是等價(jià)的
sum() {
  return this.array.push("this指向obj");
}
sum: function() {
  return this.array.push("this指向obj");
}

還有一種情況是給普通函數(shù)的原型定義方法的時(shí)候,通常會(huì)在普通函數(shù)的外部進(jìn)行定義,比如說繼承/添加方法的時(shí)候。

這時(shí)候因?yàn)闆]有在普通函數(shù)的內(nèi)部進(jìn)行定義,所以this會(huì)指向其他普通函數(shù),或者全局對(duì)象上,導(dǎo)致bug!

回調(diào)函數(shù)的動(dòng)態(tài)this

下文是一個(gè)修改dom文本的操作,因?yàn)閠his指向錯(cuò)誤,導(dǎo)致修改失敗:

const button = document.getElementById("myButton");
button.addEventListener("click", () => {
    this.innerHTML = "Clicked button"; // this又指向了全局
});

相信你也知道了,改成普通函數(shù)就成了。

考慮代碼的可讀性,使用普通函數(shù)

函數(shù)體復(fù)雜:

具體表現(xiàn)就是箭頭函數(shù)中使用多個(gè)三元運(yùn)算符號(hào),就是不換行,非要在一行內(nèi)寫完,非常惡心!

行數(shù)較多

函數(shù)內(nèi)部有大量操作

文章內(nèi)容小結(jié): 普通函數(shù)和箭頭函數(shù)的區(qū)別:

箭頭函數(shù)沒有prototype(原型),所以箭頭函數(shù)本身沒有this

箭頭函數(shù)的this在定義的時(shí)候繼承自外層第一個(gè)普通函數(shù)的this。

如果箭頭函數(shù)外層沒有普通函數(shù),嚴(yán)格模式和非嚴(yán)格模式下它的this都會(huì)指向window(全局對(duì)象)

箭頭函數(shù)本身的this指向不能改變,但可以修改它要繼承的對(duì)象的this。

箭頭函數(shù)的this指向全局,使用arguments會(huì)報(bào)未聲明的錯(cuò)誤。

箭頭函數(shù)的this指向普通函數(shù)時(shí),它的argumens繼承于該普通函數(shù)

使用new調(diào)用箭頭函數(shù)會(huì)報(bào)錯(cuò),因?yàn)榧^函數(shù)沒有constructor

箭頭函數(shù)不支持new.target

箭頭函數(shù)不支持重命名函數(shù)參數(shù),普通函數(shù)的函數(shù)參數(shù)支持重命名

箭頭函數(shù)相對(duì)于普通函數(shù)語法更簡潔優(yōu)雅

箭頭函數(shù)的注意事項(xiàng)及不適用場(chǎng)景

箭頭函數(shù)的注意事項(xiàng)

箭頭函數(shù)一條語句返回對(duì)象字面量,需要加括號(hào)

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

箭頭函數(shù)的解析順序相對(duì)||靠前

不適用場(chǎng)景:箭頭函數(shù)的this意外指向和代碼的可讀性。

結(jié)語

嘔心瀝血,可以說是很全了,反正第一次問到我的時(shí)候只能想到箭頭函數(shù)的this是繼承而來的,以及語法上的簡潔性,其他的我都不知道,希望這篇文章能夠幫助各位同學(xué)學(xué)到知識(shí)。

PS:目前找工作中,求大佬們內(nèi)推,中高級(jí)前端,偏JS,Vue,上海楊浦。

博客、前端積累文檔、公眾號(hào)、GitHub、wx:OBkoro1、郵箱:obkoro1@foxmail.com

以上2019.03.22

參考資料:

MDN 箭頭函數(shù)

阮一峰-ES6入門

什么時(shí)候你不能使用箭頭函數(shù)?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/102838.html

相關(guān)文章

  • 「前端面試題系列5」ES6 中箭頭函數(shù)用法

    摘要:在這里,如果用箭頭函數(shù),可以這樣改寫箭頭函數(shù)并沒有自己的,所以事件處理函數(shù)的調(diào)用者并不受影響。比如,在需要?jiǎng)討B(tài)上下文的場(chǎng)景中,使用箭頭函數(shù)需要格外地小心,這些場(chǎng)景包括對(duì)象的方法原型方法事件的回調(diào)構(gòu)造函數(shù)。 showImg(https://segmentfault.com/img/bVboce6?w=1304&h=734); 前言 年味兒漸散,收拾下心情,繼續(xù)敲代碼吧。 對(duì)于即將到來金三...

    betacat 評(píng)論0 收藏0
  • 箭頭函數(shù)let、const聲明小總結(jié)

    摘要:無關(guān)緊要的開頭最近因?yàn)橐恍┦聝恨o了剛剛找到的工作,處在待業(yè)狀態(tài),去稍微的面了幾家公司,有大有小,有好有壞,發(fā)現(xiàn)大家問起來的一些的問題跟我想的不一樣,下來再去研究發(fā)現(xiàn)我說的還是有些缺陷,雖然意思是對(duì)的,但是表達(dá)的很奇怪,怪不得面試官會(huì)誤會(huì),參 /*===無關(guān)緊要的開頭start===*/最近因?yàn)橐恍┦聝恨o了剛剛找到的工作,處在待業(yè)狀態(tài),去稍微的面了幾家公司,有大有小,有好有壞,發(fā)現(xiàn)大家問...

    2i18ns 評(píng)論0 收藏0
  • 普通函數(shù)箭頭函數(shù)

    摘要:普通函數(shù)和箭頭函數(shù)寫在前面函數(shù)是里的一等公民。在客戶端,在元素上綁定事件監(jiān)聽函數(shù)是非常普遍的行為,在事件被觸發(fā)時(shí),回調(diào)函數(shù)中的指向該可當(dāng)我們使用箭頭函數(shù)時(shí)因?yàn)檫@個(gè)回調(diào)的箭頭函數(shù)是在全局上下文中被定義的,所以他的是。 普通函數(shù)和箭頭函數(shù) 寫在前面 函數(shù)(Function)是 JavaScript 里的‘一等公民’。是由稱為函數(shù)體的一系列語句組成。可以當(dāng)做入?yún)ⅲ鰠ⅲǚ祷刂担┦褂谩:蛯?duì)象一...

    王晗 評(píng)論0 收藏0
  • 什么時(shí)候你能使用箭頭函數(shù)

    摘要:顯然,箭頭函數(shù)是不能用來做構(gòu)造函數(shù),實(shí)際上會(huì)禁止你這么做,如果你這么做了,它就會(huì)拋出異常。換句話說,箭頭構(gòu)造函數(shù)的執(zhí)行并沒有任何意義,并且是有歧義的。 showImg(https://segmentfault.com/img/remote/1460000009180813); 共 2670 字,讀完需 5 分鐘。編譯自 Dmitri Pavlutin 的文章,對(duì)原文內(nèi)容做了精簡和代碼風(fēng)...

    guyan0319 評(píng)論0 收藏0
  • js中箭頭函數(shù)普通函數(shù)區(qū)別

    摘要:不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用命令,否則會(huì)拋出一個(gè)錯(cuò)誤。正是因?yàn)樗鼪]有,所以也就不能用作構(gòu)造函數(shù)。總結(jié)箭頭函數(shù)的永遠(yuǎn)指向其上下文的,任何方法都改變不了其指向,如普通函數(shù)的指向調(diào)用它的那個(gè)對(duì)象 一、前言 首先看下直觀的區(qū)別 // 箭頭函數(shù) let fun = () => { console.log(lalalala); } ...

    TerryCai 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<