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

資訊專欄INFORMATION COLUMN

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

qieangel2013 / 1631人閱讀

摘要:第一部分請(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 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ì)這門(mén)語(yǔ)言。

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

new關(guān)鍵字

如果使用new關(guān)鍵字來(lái)調(diào)用函數(shù)式很特別的形式。我們把那些用new調(diào)用的函數(shù)叫做構(gòu)造函數(shù)(constructor function)。

使用了new的函數(shù)到底做了什么事情呢?

創(chuàng)建一個(gè)新的對(duì)象

將對(duì)象的prototype設(shè)置為構(gòu)造函數(shù)的prototype

執(zhí)行構(gòu)造函數(shù),this執(zhí)行新構(gòu)造的對(duì)象

返回該對(duì)象。如果構(gòu)造函數(shù)返回對(duì)象,那么返回該構(gòu)造對(duì)象。

// 為了更好地理解底層,我們來(lái)定義new關(guān)鍵字
function myNew(constructor, ...arguments) {
  var obj = {}
  Object.setPrototypeOf(obj, constructor.prototype);
  return constructor.apply(obj, arguments) || obj
}

使用new和不使用的區(qū)別在哪里呢?

function Bird() {
  this.wings = 2;
}
/* 普通的函數(shù)調(diào)用 */
let fakeBird = Bird();
console.log(fakeBird);    // undefined
/* 使用new調(diào)用 */
let realBird= new Bird();
console.log(realBird)     // { wings: 2 }

為了便于對(duì)比理解,譯者額外增加了測(cè)試了一種情況:

function MBird(){
  this.wings =2; 
  return "hello";
}

let realMBrid = new MBird();
console.log(realMBird) // { wings: 2 }

你會(huì)發(fā)現(xiàn),這一句return "hello"并沒(méi)有生效!

原型和繼承

原型(Prototype)是JavaScript中最容易搞混的概念,其中一個(gè)原因是prototype可以用在兩個(gè)不同的情形下。

原型關(guān)系
每一個(gè)對(duì)象都有一個(gè)prototype對(duì)象,里面包含了所有它的原型的屬性。
.__proto__是一個(gè)不正規(guī)的機(jī)制(ES6中提供),用來(lái)獲取一個(gè)對(duì)象的prototype。你可以理解為它指向?qū)ο蟮?b>parent。
所有普通的對(duì)象都繼承.constructor屬性,它指向該對(duì)象的構(gòu)造函數(shù)。當(dāng)一個(gè)對(duì)象通過(guò)構(gòu)造函數(shù)實(shí)現(xiàn)的時(shí)候,__proto__屬性指向構(gòu)造函數(shù)的構(gòu)造函數(shù)的.prototypeObject.getPrototypeOf()是ES5的標(biāo)準(zhǔn)函數(shù),用來(lái)獲取一個(gè)對(duì)象的原型。

原型屬性
每一個(gè)函數(shù)都有一個(gè).prototype屬性,它包含了所有可以被繼承的屬性。該對(duì)象默認(rèn)包含了指向原構(gòu)造函數(shù)的.constructor屬性。每一個(gè)使用構(gòu)造函數(shù)創(chuàng)建的對(duì)象都有一個(gè)構(gòu)造函數(shù)屬性。

接下來(lái)通過(guò)例子來(lái)幫助理解:

function Dog(breed, name){
  this.breed = breed,
  this.name = name
}
Dog.prototype.describe = function() {
  console.log(`${this.name} is a ${this.breed}`)
}
const rusty = new Dog("Beagle", "Rusty");

/* .prototype 屬性包含了構(gòu)造函數(shù)以及構(gòu)造函數(shù)中在prototype上定義的屬性。*/
console.log(Dog.prototype)  // { describe: ? , constructor: ? }

/* 使用Dog構(gòu)造函數(shù)構(gòu)造的對(duì)象 */
console.log(rusty)   //  { breed: "Beagle", name: "Rusty" }
/* 從構(gòu)造函數(shù)的原型中繼承下來(lái)的屬性或函數(shù) */
console.log(rusty.describe())   // "Rusty is a Beagle"
/* .__proto__ 屬性指向構(gòu)造函數(shù)的.prototype屬性 */
console.log(rusty.__proto__)    // { describe: ? , constructor: ? }
/* .constructor 屬性指向構(gòu)造函數(shù) */
console.log(rusty.constructor)  // ? Dog(breed, name) { ... }

JavaScript的使用可以說(shuō)相當(dāng)靈活,為了避免出bug了不知道,不妨接入Fundebug線上實(shí)時(shí)監(jiān)控

原型鏈

原型鏈?zhǔn)侵笇?duì)象之間通過(guò)prototype鏈接起來(lái),形成一個(gè)有向的鏈條。當(dāng)訪問(wèn)一個(gè)對(duì)象的某個(gè)屬性的時(shí)候,JavaScript引擎會(huì)首先查看該對(duì)象是否包含該屬性。如果沒(méi)有,就去查找對(duì)象的prototype中是否包含。以此類推,直到找到該屬性或則找到最后一個(gè)對(duì)象。最后一個(gè)對(duì)象的prototype默認(rèn)為null。

擁有 vs 繼承

一個(gè)對(duì)象有兩種屬性,分別是它自身定義的和繼承的。

function Car() { }
Car.prototype.wheels = 4;
Car.prototype.airbags = 1;

var myCar = new Car();
myCar.color = "black";

/*  原型鏈中的屬性也可以通過(guò)in來(lái)查看:  */
console.log("airbags" in myCar)  // true
console.log(myCar.wheels)        // 4
console.log(myCar.year)          // undefined

/*  通過(guò)hasOwnProperty來(lái)查看是否擁有該屬性:  */
console.log(myCar.hasOwnProperty("airbags"))  // false — Inherited
console.log(myCar.hasOwnProperty("color"))    // true

Object.create(obj) 創(chuàng)建一個(gè)新的對(duì)象,prototype指向obj。

var dog = { legs: 4 };
var myDog = Object.create(dog);

console.log(myDog.hasOwnProperty("legs"))  // false
console.log(myDog.legs)                    // 4
console.log(myDog.__proto__ === dog)       // true
繼承是引用傳值

繼承屬性都是通過(guò)引用的形式。我們通過(guò)例子來(lái)形象理解:

var objProt = { text: "original" };
var objAttachedToProt = Object.create(objProt);
console.log(objAttachedToProt.text)   // original

// 我們更改objProt的text屬性,objAttachedToProt的text屬性同樣更改了
objProt.text = "prototype property changed";
console.log(objAttachedToProt.text)   // prototype property changed

// 但是如果我們講一個(gè)新的對(duì)象賦值給objProt,那么objAttachedToProt的text屬性不受影響
objProt = { text: "replacing property" };
console.log(objAttachedToProt.text)   // prototype property changed
經(jīng)典繼承 vs 原型繼承

Eric Elliott的文章有非常詳細(xì)的介紹:Master the JavaScript Interview: What’s the Difference Between Class & Prototypal Inheritance?
作者認(rèn)為原型繼承是優(yōu)于經(jīng)典的繼承的,并提供了一個(gè)視頻介紹:https://www.youtube.com/watch...

異步JavaScript

JavaScript是一個(gè)單線程程序語(yǔ)言,也就是說(shuō)JavaScript引擎一次只能執(zhí)行某一段代碼。它導(dǎo)致的問(wèn)題就是:如果有一段代碼需要耗費(fèi)很長(zhǎng)的時(shí)間執(zhí)行,其它的操作就被卡住了。JavaScript使用Call Stack來(lái)記錄函數(shù)的調(diào)用。一個(gè)Call Stack可以看成是一摞書(shū)。最后一本書(shū)放在最上面,也最先被移走。最先放的書(shū)在最底層,最后被移走。

為了避免復(fù)雜代碼占用CPU太長(zhǎng)時(shí)間,一個(gè)解法就是定義異步回調(diào)函數(shù)。我們自己來(lái)定義一個(gè)異步函數(shù)看看:

function greetingAsync(name, callback){
  let greeting = "hello, " + name ;
  setTimeout(_ => callback(greeting),0);
}

greetingAsync("fundebug", console.log);
console.log("start greeting");

我們?cè)?b>greetingAsync中構(gòu)造了greeting語(yǔ)句,然后通過(guò)setTimeout定義了異步,callback函數(shù),是為了讓用戶自己去定義greeting的具體方式。為方便起見(jiàn),我們時(shí)候直接使用console.log
上面代碼執(zhí)行首先會(huì)打印start greeting,然后才是hello, fundebug。也就是說(shuō),greetingAsync的回調(diào)函數(shù)后執(zhí)行。在網(wǎng)站開(kāi)發(fā)中,和服務(wù)器交互的時(shí)候需要不斷地發(fā)送各種請(qǐng)求,而一個(gè)頁(yè)面可能有幾十個(gè)請(qǐng)求。如果我們一個(gè)一個(gè)按照順序來(lái)請(qǐng)求并等待結(jié)果,串行的執(zhí)行會(huì)使得網(wǎng)頁(yè)加載很慢。通過(guò)異步的方式,我們可以先發(fā)請(qǐng)求,然后在回調(diào)中處理請(qǐng)求結(jié)果,高效低并發(fā)處理。

下面通過(guò)一個(gè)例子來(lái)描述整個(gè)執(zhí)行過(guò)程:

const first = function () {
  console.log("First message")
}
const second = function () {
  console.log("Second message")
}
const third = function() {
  console.log("Third message")
}

first();
setTimeout(second, 0);
third();

// 輸出:
  // First message
  // Third message
  // Second message

初始狀態(tài)下,瀏覽器控制臺(tái)沒(méi)有輸出,并且事件管理器(Event Manager)是空的;

first()被添加到調(diào)用棧

console.log("First message")加到調(diào)用棧

console.log("First message")執(zhí)行并輸出“First message”到控制臺(tái)

console.log("First message")從調(diào)用棧中移除

first()從調(diào)用棧中移除

setTimeout(second, 0)加到調(diào)用棧

setTimeout(second, 0)執(zhí)行,0ms之后,second()被加到回調(diào)隊(duì)列

setTimeout(second, 0)從調(diào)用棧中移除

third()加到調(diào)用棧

console.log("Third message")加到調(diào)用棧

console.log("Third message")執(zhí)行并輸出“Third message”到控制臺(tái)

console.log("Third message")從調(diào)用棧中移除

third()從調(diào)用棧中移除

Event Loop 將second()從回調(diào)隊(duì)列移到調(diào)用棧

console.log("Second message")加到調(diào)用棧

console.log("Second message")Second message”到控制臺(tái)

console.log("Second message")從調(diào)用棧中移除

Second()從調(diào)用棧中移除

特別注意的是:second()函數(shù)在0ms之后并沒(méi)有立即執(zhí)行,你傳入到setTimeout()函數(shù)的時(shí)間和second()延遲執(zhí)行的時(shí)間并不一定直接相關(guān)。事件管理器等到setTimeout()設(shè)置的時(shí)間到期才會(huì)將其加入回調(diào)隊(duì)列,而回調(diào)隊(duì)列中它執(zhí)行的時(shí)間和它在隊(duì)列中的位置已經(jīng)它前面的函數(shù)的執(zhí)行時(shí)間有關(guān)。

更多

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

快速掌握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/107434.html

相關(guān)文章

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

    摘要:第一部分請(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 develope...

    fyber 評(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
  • 前端開(kāi)發(fā)-從入門(mén)到Offer - 收藏集 - 掘金

    摘要:一些知識(shí)點(diǎn)有哪些方法方法前端從入門(mén)菜鳥(niǎo)到實(shí)踐老司機(jī)所需要的資料與指南合集前端掘金前端從入門(mén)菜鳥(niǎo)到實(shí)踐老司機(jī)所需要的資料與指南合集歸屬于筆者的前端入門(mén)與最佳實(shí)踐。 工欲善其事必先利其器-前端實(shí)習(xí)簡(jiǎn)歷篇 - 掘金 有幸認(rèn)識(shí)很多在大廠工作的學(xué)長(zhǎng),在春招正式開(kāi)始前為我提供很多內(nèi)部推薦的機(jī)會(huì),非常感謝他們對(duì)我的幫助?,F(xiàn)在就要去北京了,對(duì)第一份正式的實(shí)習(xí)工作也充滿期待,也希望把自己遇到的一些問(wèn)題和...

    sf_wangchong 評(píng)論0 收藏0
  • Tools - 收藏集 - 掘金

    摘要:個(gè)高級(jí)多線程面試題及回答后端掘金在任何面試當(dāng)中多線程和并發(fā)方面的問(wèn)題都是必不可少的一部分。默認(rèn)為提供了年杭州面試經(jīng)歷掘金想換個(gè)環(huán)境試試覺(jué)得做的不是自己想要的。源碼網(wǎng)站安居客項(xiàng)目架構(gòu)演進(jìn)掘金本文已授權(quán)微信公眾號(hào)獨(dú)家發(fā)布。 15 個(gè)高級(jí) Java 多線程面試題及回答 - 后端 - 掘金在任何Java面試當(dāng)中多線程和并發(fā)方面的問(wèn)題都是必不可少的一部分。如果你想獲得任何股票投資銀行的前臺(tái)資訊職...

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

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

0條評(píng)論

閱讀需要支付1元查看
<