成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

qieangel2013 / 1590人閱讀

摘要:第一部分請(qǐng)點(diǎn)擊快速掌握面試基礎(chǔ)知識(shí)一關(guān)鍵字如果使用關(guān)鍵字來調(diào)用函數(shù)式很特別的形式。該對(duì)象默認(rèn)包含了指向原構(gòu)造函數(shù)的屬性。接下來通過例子來幫助理解屬性包含了構(gòu)造函數(shù)以及構(gòu)造函數(shù)中在上定義的屬性。也就是說,的回調(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年一來,JavaScript是最流行的編程語言。當(dāng)然,這也在情理之中,畢竟1/3的開發(fā)工作都需要一些JavaScript知識(shí)。因此,如果你希望在成為一個(gè)開發(fā)者,你應(yīng)該學(xué)會(huì)這門語言。

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

new關(guān)鍵字

如果使用new關(guān)鍵字來調(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ì)象。

// 為了更好地理解底層,我們來定義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"并沒有生效!

原型和繼承

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

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

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

接下來通過例子來幫助理解:

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ù)的原型中繼承下來的屬性或函數(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的使用可以說相當(dāng)靈活,為了避免出bug了不知道,不妨接入Fundebug線上實(shí)時(shí)監(jiān)控。

原型鏈

原型鏈?zhǔn)侵笇?duì)象之間通過prototype鏈接起來,形成一個(gè)有向的鏈條。當(dāng)訪問一個(gè)對(duì)象的某個(gè)屬性的時(shí)候,JavaScript引擎會(huì)首先查看該對(duì)象是否包含該屬性。如果沒有,就去查找對(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";

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

/*  通過hasOwnProperty來查看是否擁有該屬性:  */
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
繼承是引用傳值

繼承屬性都是通過引用的形式。我們通過例子來形象理解:

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

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

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

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)沒有輸出,并且事件管理器(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之后并沒有立即執(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://systransis.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è)問題可以改用后面會(huì)介紹方法來解決,通過對(duì)每一個(gè)匿名函數(shù)構(gòu)建獨(dú)立的外部作用域來實(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)查,自年一來,是最流行的編程語言。在一個(gè)函數(shù)體中聲明的變量和函數(shù),周圍的作用域內(nèi)無法訪問。也就是說被大括號(hào)包圍起來的區(qū)域聲明的變量外部將不可訪問。一個(gè)常見的誤解是使用聲明的變量,其值不可更改。 譯者按: 總結(jié)了大量JavaScript基本知識(shí)點(diǎn),很有用! 原文: The Definitive JavaScript Handbook for your next developer ...

    acrazing 評(píng)論0 收藏0
  • 前端開發(fā)-從入門到Offer - 收藏集 - 掘金

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

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

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

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

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

0條評(píng)論

閱讀需要支付1元查看
<