亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

快速掌握J(rèn)avaScript面試基礎(chǔ)知識(shí)(二)

fyber / 1759人閱讀

摘要:第一部分請(qǐng)點(diǎn)擊快速掌握面試基礎(chǔ)知識(shí)一閉包閉包由一個(gè)函數(shù)以及該函數(shù)定義是所在的環(huán)境組成。當(dāng)匿名函數(shù)執(zhí)行的時(shí)候,的值為。這個(gè)問(wèn)題可以改用后面會(huì)介紹方法來(lái)解決,通過(guò)對(duì)每一個(gè)匿名函數(shù)構(gòu)建獨(dú)立的外部作用域來(lái)實(shí)現(xiàn)。

譯者按: 總結(jié)了大量JavaScript基本知識(shí)點(diǎn),很有用!

原文: The Definitive JavaScript Handbook for your next developer interview

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。

根據(jù)StackOverflow調(diào)查, 自2014年一來(lái),JavaScript是最流行的編程語(yǔ)言。當(dāng)然,這也在情理之中,畢竟1/3的開(kāi)發(fā)工作都需要一些JavaScript知識(shí)。因此,如果你希望在成為一個(gè)開(kāi)發(fā)者,你應(yīng)該學(xué)會(huì)這門語(yǔ)言。

這篇博客的主要目的是將所有面試中常見(jiàn)的概念總結(jié),方便你快速去了解。(鑒于本文內(nèi)容過(guò)長(zhǎng),方便閱讀,將分為三篇博客來(lái)翻譯, 此為第二部分。第一部分請(qǐng)點(diǎn)擊快速掌握J(rèn)avaScript面試基礎(chǔ)知識(shí)(一))

閉包

閉包由一個(gè)函數(shù)以及該函數(shù)定義是所在的環(huán)境組成。我們通過(guò)例子來(lái)形象解釋它。

function sayHi(name){
  var message = `Hi ${name}!`;
  function greeting() {
    console.log(message)
  }
  return greeting
}
var sayHiToJon = sayHi("Jon");
console.log(sayHiToJon)     // ?() { console.log(message) }
console.log(sayHiToJon())   // "Hi Jon!"

請(qǐng)理解var sayHiToJon = sayHi("Jon");這行代碼的執(zhí)行過(guò)程,sayHi函數(shù)執(zhí)行,首先將message的值計(jì)算出來(lái);然后定義了greeting函數(shù),函數(shù)中引用了message變量;最后,返回greeting函數(shù)。
如果按照C/Java語(yǔ)言的思路,sayHiToJon就等價(jià)于greeting函數(shù),那么會(huì)報(bào)錯(cuò):message未定義。但是在JavaScript中不一樣,這里的sayHiToJon函數(shù)等于greeting函數(shù)以及一個(gè)環(huán)境,該環(huán)境中包含了message。因此,當(dāng)我們調(diào)用sayHiToJon函數(shù),可以成功地將message打印出來(lái)。因此,這里的閉包就是greeting函數(shù)和一個(gè)包含message變量的環(huán)境。(備注: 為了便于理解,此段落未按照原文翻譯。)

閉包的一個(gè)優(yōu)勢(shì)在于數(shù)據(jù)隔離。我們同樣用一個(gè)例子來(lái)說(shuō)明:

function SpringfieldSchool() {
  let staff = ["Seymour Skinner", "Edna Krabappel"];
  return {
    getStaff: function() { console.log(staff) },
    addStaff: function(name) { staff.push(name) }
  }
}

let elementary = SpringfieldSchool()
console.log(elementary)        // { getStaff: ?, addStaff: ? }
console.log(staff)             // ReferenceError: staff is not defined
/* Closure allows access to the staff variable */
elementary.getStaff()          // ["Seymour Skinner", "Edna Krabappel"]
elementary.addStaff("Otto Mann")
elementary.getStaff()          // ["Seymour Skinner", "Edna Krabappel", "Otto Mann"]

elementary被創(chuàng)建的時(shí)候,SpringfieldSchool已經(jīng)返回。也就是說(shuō)staff無(wú)法被外部訪問(wèn)。唯一可以訪問(wèn)的方式就是里面的閉包函數(shù)getStaffaddStaff

我們來(lái)看一個(gè)面試題:下面的代碼有什么問(wèn)題,如何修復(fù)?

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log(`The value ${arr[i]} is at index: ${i}`);
  }, (i+1) * 1000);
}

上面的代碼輸出的結(jié)果全部都一樣:"The value undefined is at index: 4"。因?yàn)樗性?b>setTimeout中定義的匿名函數(shù)都引用了同一個(gè)外部變量i。當(dāng)匿名函數(shù)執(zhí)行的時(shí)候,i的值為4。

這個(gè)問(wèn)題可以改用IIFE(后面會(huì)介紹)方法來(lái)解決,通過(guò)對(duì)每一個(gè)匿名函數(shù)構(gòu)建獨(dú)立的外部作用域來(lái)實(shí)現(xiàn)。

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(`The value ${arr[j]} is at index: ${j}`);
    }, j * 1000);
  })(i)
}

當(dāng)然,還有一個(gè)方法,使用let來(lái)聲明i。

const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log(`The value ${arr[i]} is at index: ${i}`);
  }, (i) * 1000);
}
立即調(diào)用的函數(shù)表達(dá)式(Immediate Invoked Function Expression)(IIFE)

一個(gè)IIFE是一個(gè)函數(shù)表達(dá)式在定義之后立即被調(diào)用。常用在你想對(duì)一個(gè)新聲明的變量創(chuàng)建一個(gè)隔離的作用域。
它的格式為: (function(){....})()。前面的大括號(hào)用于告訴編譯器這里不僅僅是函數(shù)定義,后面的大括號(hào)用于執(zhí)行該函數(shù)。

var result = [];
for (var i=0; i < 5; i++) {
  result.push( function() { return i } );
}
console.log( result[1]() ); // 5
console.log( result[3]() ); // 5
result = [];
for (var i=0; i < 5; i++) {
  (function () {
    var j = i; // copy current value of i
    result.push( function() { return j } );
  })();
}
console.log( result[1]() ); // 1
console.log( result[3]() ); // 3

使用IIFE可以:

為函數(shù)綁定私有數(shù)據(jù)

創(chuàng)建一個(gè)新的環(huán)境

避免污染全局命名空間

環(huán)境(Context)

我們往往容易將環(huán)境(Context)和作用域(Scope)搞混,我來(lái)簡(jiǎn)單解釋一下:

環(huán)境(Context): 由函數(shù)如何被調(diào)用而決定,往往指this

作用域(Scope): 可訪問(wèn)的變量。

函數(shù)調(diào)用:call, apply, bind

這三個(gè)方法都是為了將this綁定到函數(shù),區(qū)別在于調(diào)用的方式。

.call()會(huì)立即執(zhí)行函數(shù),你需要把參數(shù)按順序傳入;

.apply()會(huì)立即執(zhí)行函數(shù),你需要把所有的參數(shù)組合為一個(gè)數(shù)組傳入;

.call().apply()幾乎相同。哪個(gè)傳入?yún)?shù)方便,你就選擇哪個(gè)。

const Snow = {surename: "Snow"}
const char = {
  surename: "Stark",
  knows: function(arg, name) {
    console.log(`You know ${arg}, ${name} ${this.surename}`);
  }
}
char.knows("something", "Bran");              // You know something, Bran Stark
char.knows.call(Snow, "nothing", "Jon");      // You know nothing, Jon Snow
char.knows.apply(Snow, ["nothing", "Jon"]);   // You know nothing, Jon Snow

注意:如果你將數(shù)組傳入call函數(shù),它會(huì)認(rèn)為只有一個(gè)參數(shù)。

ES6允許使用新的操作符將數(shù)組變換為一個(gè)序列。

char.knows.call(Snow, ...["nothing", "Jon"]);  // You know nothing, Jon Snow

.bind()返回一個(gè)新的函數(shù),以及相應(yīng)的環(huán)境和參數(shù)。如果你想該函數(shù)稍后調(diào)用,那么推薦使用bind
.bind()函數(shù)的優(yōu)點(diǎn)在于它可以記錄一個(gè)執(zhí)行環(huán)境,對(duì)于異步調(diào)用和事件驅(qū)動(dòng)的編程很有用。

.bind()傳參數(shù)的方式和call相同。

const Snow = {surename: "Snow"}
const char = {
  surename: "Stark",
  knows: function(arg, name) {
    console.log(`You know ${arg}, ${name} ${this.surename}`);}
  }
const whoKnowsNothing = char.knows.bind(Snow, "nothing");
whoKnowsNothing("Jon");  // You know nothing, Jon Snow
this關(guān)鍵字

要理解JavaScript中this關(guān)鍵字,特別是它指向誰(shuí),有時(shí)候相當(dāng)?shù)貜?fù)雜。this的值通常由函數(shù)的執(zhí)行環(huán)境決定。簡(jiǎn)單的說(shuō),執(zhí)行環(huán)境指函數(shù)如何被調(diào)用的。this像是一個(gè)占位符(placeholder),它指向當(dāng)方法被調(diào)用時(shí),調(diào)用對(duì)應(yīng)的方法的對(duì)象。

下面有序地列出了判斷this指向的規(guī)則。如果第一條匹配,那么就不用去檢查第二條了。

new綁定 - 當(dāng)使用new關(guān)鍵字調(diào)用函數(shù)的時(shí)候,this指向新構(gòu)建的對(duì)象。

function Person(name, age) {
  this.name = name;
  this.age =age;
  console.log(this);
}
const Rachel = new Person("Rachel", 30);   // { age: 30, name: "Rachel" }

顯示綁定(Explicit binding) - 當(dāng)使用call或則apply的時(shí)候,我們顯示的傳入一個(gè)對(duì)象參數(shù),該參數(shù)會(huì)綁定到this。 注意:.bind()函數(shù)不一樣。用bind定義一個(gè)新的函數(shù),但是依然綁定到原來(lái)的對(duì)象。

function fn() {
  console.log(this);
}
var agent = {id: "007"};
fn.call(agent);    // { id: "007" }
fn.apply(agent);   // { id: "007" }
var boundFn = fn.bind(agent);
boundFn();         // { id: "007" }

隱式綁定 - 當(dāng)一個(gè)函數(shù)在某個(gè)環(huán)境下調(diào)用(在某個(gè)對(duì)象里),this指向該對(duì)象。也就是說(shuō)該函數(shù)是對(duì)象的一個(gè)方法。

var building = {
  floors: 5,
  printThis: function() {
    console.log(this);
  }
}
building.printThis();  // { floors: 5, printThis: function() {…} }

默認(rèn)綁定 - 如果上面所有的規(guī)則都不滿足,那么this指向全局對(duì)象(在瀏覽器中,就是window對(duì)象)。當(dāng)函數(shù)沒(méi)有綁定到某個(gè)對(duì)象,而多帶帶定義的時(shí)候,該函數(shù)默認(rèn)綁定到全局對(duì)象。

function printWindow() {
  console.log(this)
}
printWindow();  // window object

注意:下面的情況中,inner函數(shù)中的this指向全局。

function Dinosaur(name) {
  this.name = name;
  var self = this;
  inner();
  function inner() {
    alert(this);        // window object — the function has overwritten the "this" context
    console.log(self);  // {name: "Dino"} — referencing the stored value from the outer context
  }
}
var myDinosaur = new Dinosaur("Dino");

詞法(Lexical) this - 當(dāng)是使用=>來(lái)定義函數(shù)時(shí),this指向定義該函數(shù)時(shí)候外層的this。 備注:大概是和定義的詞法(=>)有關(guān),把它稱作Lexical this

function Cat(name) {
  this.name = name;
  console.log(this);   // { name: "Garfield" }
  ( () => console.log(this) )();   // { name: "Garfield" }
}
var myCat = new Cat("Garfield");
嚴(yán)格(Strict)模式

如果你使用了"use strict"指令,那么JavaScript代碼會(huì)在嚴(yán)格模式下執(zhí)行。在嚴(yán)格模式下,對(duì)于詞法分析和錯(cuò)誤處理都有特定的規(guī)則。在這里我列出它的一些優(yōu)點(diǎn):

使得Debug更容易:以前會(huì)被忽略的錯(cuò)誤現(xiàn)在會(huì)顯示報(bào)錯(cuò),比如賦值給一個(gè)不可寫的全局變量或則屬性;

避免不小心聲明了全局變量:賦值給一個(gè)未定義的變量會(huì)報(bào)錯(cuò);

避免無(wú)效使用delete:嘗試去刪除變量、函數(shù)或則不可刪除的屬性會(huì)拋出錯(cuò)誤;

避免重復(fù)的屬性名和參數(shù)值:對(duì)象上重復(fù)的屬性和函數(shù)參數(shù)會(huì)拋出錯(cuò)誤(在ES6中不再是這樣);

使得eval()更加安全:在eval()中定義的變量和函數(shù)在外部作用域不可見(jiàn);

“安全”的消除JavaScript中this的轉(zhuǎn)換:如果this是null或則undefined不在轉(zhuǎn)換到全局對(duì)象。也就是說(shuō)在瀏覽器中使用this去指向全局對(duì)象不再可行。

對(duì)于在嚴(yán)格(strict)模式和測(cè)試階段都沒(méi)有發(fā)現(xiàn)的bug,不妨接入線上實(shí)時(shí)監(jiān)控插件Fundebug。

快速掌握J(rèn)avaScript面試基礎(chǔ)知識(shí)(一) -->

版權(quán)聲明:
轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:
https://blog.fundebug.com/201...

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/107436.html

相關(guān)文章

  • 快速掌握JavaScript面試基礎(chǔ)知識(shí)(三)

    摘要:第一部分請(qǐng)點(diǎn)擊快速掌握面試基礎(chǔ)知識(shí)一關(guān)鍵字如果使用關(guān)鍵字來(lái)調(diào)用函數(shù)式很特別的形式。該對(duì)象默認(rèn)包含了指向原構(gòu)造函數(shù)的屬性。接下來(lái)通過(guò)例子來(lái)幫助理解屬性包含了構(gòu)造函數(shù)以及構(gòu)造函數(shù)中在上定義的屬性。也就是說(shuō),的回調(diào)函數(shù)后執(zhí)行。 譯者按: 總結(jié)了大量JavaScript基本知識(shí)點(diǎn),很有用! 原文: The Definitive JavaScript Handbook for your next...

    qieangel2013 評(píng)論0 收藏0
  • 快速掌握JavaScript面試基礎(chǔ)知識(shí)(一)

    摘要:根據(jù)調(diào)查,自年一來(lái),是最流行的編程語(yǔ)言。在一個(gè)函數(shù)體中聲明的變量和函數(shù),周圍的作用域內(nèi)無(wú)法訪問(wèn)。也就是說(shuō)被大括號(hào)包圍起來(lái)的區(qū)域聲明的變量外部將不可訪問(wèn)。一個(gè)常見(jiàn)的誤解是使用聲明的變量,其值不可更改。 譯者按: 總結(jié)了大量JavaScript基本知識(shí)點(diǎn),很有用! 原文: The Definitive JavaScript Handbook for your next developer ...

    acrazing 評(píng)論0 收藏0
  • 前端經(jīng)典文章

    摘要:上周末看這篇文章時(shí),偶有靈光,所以,分享出來(lái)給大家一起看看前端面試四月二十家前端面試題分享請(qǐng)各位讀者添加一下作者的微信公眾號(hào),以后有新的文章,將在微信公眾號(hào)直接推送給各位,非常感謝。 前端切圖神器 avocode 有了這個(gè)神器,切圖再也腰不酸,腿不疼了。 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果讀完本文還不懂,...

    lowett 評(píng)論0 收藏0
  • 前端相關(guān)大雜燴

    摘要:希望幫助更多的前端愛(ài)好者學(xué)習(xí)。前端開(kāi)發(fā)者指南作者科迪林黎,由前端大師傾情贊助。翻譯最佳實(shí)踐譯者張捷滬江前端開(kāi)發(fā)工程師當(dāng)你問(wèn)起有關(guān)與時(shí),老司機(jī)們首先就會(huì)告訴你其實(shí)是個(gè)沒(méi)有網(wǎng)絡(luò)請(qǐng)求功能的庫(kù)。 前端基礎(chǔ)面試題(JS部分) 前端基礎(chǔ)面試題(JS部分) 學(xué)習(xí) React.js 比你想象的要簡(jiǎn)單 原文地址:Learning React.js is easier than you think 原文作...

    fuyi501 評(píng)論0 收藏0
  • H5學(xué)習(xí)

    摘要:為此決定自研一個(gè)富文本編輯器。本文,主要介紹如何實(shí)現(xiàn)富文本編輯器,和解決一些不同瀏覽器和設(shè)備之間的。 對(duì)ES6Generator函數(shù)的理解 Generator 函數(shù)是 ES6 提供的一種異步編程解決方案,語(yǔ)法行為與傳統(tǒng)函數(shù)完全不同。 JavaScript 設(shè)計(jì)模式 ② 巧用工廠模式和創(chuàng)建者模式 我為什么把他們兩個(gè)放在一起講?我覺(jué)得這兩個(gè)設(shè)計(jì)模式有相似之處,有時(shí)候會(huì)一個(gè)設(shè)計(jì)模式不能滿...

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

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

0條評(píng)論

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