成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

前端教學(xué)講義:閉包、高階函數(shù)、原型鏈

meislzhua / 3536人閱讀

摘要:上一章前端教學(xué)講義基礎(chǔ)閉包高階函數(shù)閉包是一種打通兩個(gè)作用域的能力,在和中都有類(lèi)似的功能,中的閉包和他們沒(méi)有太大的差別。在中任何函數(shù)都可以當(dāng)作構(gòu)造函數(shù)并搭配關(guān)鍵詞使用。再將作為運(yùn)行構(gòu)造函數(shù)。

上一章:前端教學(xué)講義:JS基礎(chǔ)

閉包、高階函數(shù)

閉包是一種打通兩個(gè)作用域的能力,在 Java 和 OC 中都有類(lèi)似的功能,JS 中的閉包和他們沒(méi)有太大的差別。

不過(guò)因?yàn)?JS 的函數(shù)是一等公民,所以使用起來(lái)會(huì)更加靈活。

在數(shù)學(xué)和計(jì)算機(jī)科學(xué)中,高階函數(shù)是至少滿足下列一個(gè)條件的函數(shù):

接受一個(gè)或多個(gè)函數(shù)作為輸入

輸出一個(gè)函數(shù)

下面的例子就是個(gè)典型的高階函數(shù)

const multiple = function(a, b) {
    return a * b;
}

const plus = function(a, b) {
    return a + b;
}

const express = function(operator, a, b) {
    return operator(a)(b);
}

[
    [plus, 1, 2],
    [multiple, 3, 4],
].map(function(formula) {
  return express.apply(null, formula)
});
 
// [3, 12]
call,apply,bind

在 JS 中經(jīng)常會(huì)遇到 this 指向錯(cuò)亂的問(wèn)題:

var obj = {
    value: 1234,
    log: function() {
      console.log(this.value)
    }
}
var log = obj.log;
log(); // 這個(gè)函數(shù)執(zhí)行的時(shí)候沒(méi)有上下文,this 會(huì)默認(rèn)為 window 或者 global
 
// undefined

JS 提供了兩個(gè)方法,call 和 apply,能夠指定一個(gè)函數(shù)執(zhí)行時(shí)候的上下文

log.call(obj);
 
// 1234
 
log.apply(obj);
 
// 1234

call 和 apply 同時(shí)還可以指定傳給函數(shù)的參數(shù)是什么,他們的區(qū)別就是后面的傳參數(shù)形式不一樣;

function fn(arg1, arg2){}
 
fn.call(obj, arg1, arg2)
fn.apply(obj, [arg1, arg2]) // apply 是將參數(shù)當(dāng)作數(shù)組傳入

bind 函數(shù)通過(guò)閉包的形式,來(lái)強(qiáng)制的將某個(gè)上下文綁定到函數(shù)上:

log = bind(log, obj); // 返回一個(gè)新函數(shù),此函數(shù)的 this 強(qiáng)制被綁定為 obj
log()
 
1234

bind 的實(shí)現(xiàn)大概如下(省略傳參的功能):

function bind(fn, ctx) {
  return function() {
    return fn.apply(ctx);
  }
}

和上面舉例有點(diǎn)區(qū)別的是 JS 提供的 bind 方法是 Function 類(lèi)的一個(gè)方法,調(diào)用方法如下:

function log() {}
 
log = log.bind(obj)
原型鏈

JS 的原型鏈(prototype chain)是為了實(shí)現(xiàn)面向?qū)ο蠖嬖诘?,?dāng)訪問(wèn)一個(gè)對(duì)象的方法的時(shí)候,首先會(huì)遍歷對(duì)象本身,是否存在這個(gè)鍵,然后在查找父類(lèi)是否有這個(gè)鍵,再一直追溯到頂層。

「父類(lèi)」中包含的方法和屬性,都存放在對(duì)象的 「__proto__」對(duì)象上(在舊的 JS 規(guī)范中,「__proto__」是隱藏屬性,但是 ES6 將它標(biāo)準(zhǔn)化并暴露出來(lái)了)。

var c = {
  somekey: 1,
}
var b = {
  __proto__: c,
}
var a = {
__proto__: b
}
a.somekey
 
// 1

當(dāng)訪問(wèn) 「a.somekey」 的時(shí)候,會(huì)沿著原型鏈一直向上查找,相當(dāng)于做了如下計(jì)算:

function getValue(obj, key) {
  while (obj) {
    if (key in obj) {
      return obj[key]
    }
    if (obj.__proto__) {
      obj = obj.__proto__;
    } else {
      return undefined;
    }
  }
}
 
getValue(a, "somekey")
類(lèi)

在最早期的 JS 版本中是沒(méi)有類(lèi)的,后來(lái)加入了原型鏈和 new 關(guān)鍵詞才實(shí)現(xiàn)了類(lèi)。

function SubClass(value) {
    this.value = value;
}
 
SubClass.prototype = {
    log: function() {
        console.log(this.value);
    }
}

var sub = new SubClass(1234);
sub.log();
 
// 1234

在 JS 中任何函數(shù)都可以當(dāng)作構(gòu)造函數(shù)并搭配 new 關(guān)鍵詞使用。

new 關(guān)鍵詞的作用就是新建一個(gè)空對(duì)象 a,然后把構(gòu)造函數(shù)上的 prototype 值掛載到 a.__proto__ 上。

再將 a 作為 context 運(yùn)行構(gòu)造函數(shù)。

如果我們將 new 作為一個(gè)函數(shù),它就是這樣:

function new(class, ...params) {
  var instance = {};
  instance.__proto__ = class.prototype;
  var result = class.apply(instance, params);
  if (typeof result !== "undefined") {
    return result;
  }
  return instance;
}
 
var sub = new(SubClass, 1234);

從上面的代碼可以看出,在構(gòu)造函數(shù)中,可以指定 new 關(guān)鍵詞返回的類(lèi)型,也就是說(shuō) new A() 返回的結(jié)果不一定就是 A 的實(shí)例,這要看 A 的構(gòu)造函數(shù)內(nèi)部是如何實(shí)現(xiàn)的。

function A() {
    return 1234;
}
var a = new A();
console.log(a)
 
// 1234

JS 用原型鏈的方式,曲線的實(shí)現(xiàn)了類(lèi)的行為和寫(xiě)法,所以在 JS 中,「類(lèi)」就是構(gòu)造函數(shù)。

instanceof

如何判斷一個(gè)對(duì)象是否是一個(gè)類(lèi)的實(shí)例呢?

JS 實(shí)現(xiàn)的方法很粗糙,就是判斷實(shí)例的原型鏈上是否存在類(lèi)的原型。

function A() {
}
var a = new A();
a instanceof A
 
true

我們甚至可以讓任意一個(gè)類(lèi)成為實(shí)例的父類(lèi)

function C() {}
function A() {}
var a = new A();
C.prototype = A.prototype;
a instanceof A
// true
 
a instanceof C
// true

我們甚至也可以讓一個(gè)父類(lèi)不是實(shí)例的父類(lèi)

function A() {}
var a = new A();
A.prototype = {}; // 對(duì)原型重新賦值
a instanceof A
 
false

總之就是很神奇

ES6 中對(duì)類(lèi)的改進(jìn)

在 ES6 中新增了 class 關(guān)鍵詞,使得聲明一個(gè)類(lèi)更加簡(jiǎn)單,但只是寫(xiě)法上有改變,運(yùn)行機(jī)制還是一樣。

class A {
    constructor(value) {
        this.value = value;
    }
    log() {
        console.log(this.value);
    }
}
var a = new A(1234);
a.log();
 
// 1234

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

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

相關(guān)文章

  • 2019春招前端實(shí)習(xí)面經(jīng)總結(jié)

    摘要:春招前端實(shí)習(xí)面試記錄從就開(kāi)始漸漸的進(jìn)行復(fù)習(xí),月末開(kāi)始面試,到現(xiàn)在四月中旬基本宣告結(jié)束。上海愛(ài)樂(lè)奇一面盒模型除之外的面向?qū)ο笳Z(yǔ)言繼承因?yàn)槭且曨l面試,只記得這么多,只感覺(jué)考察的面很廣,前端后端移動(dòng)端都問(wèn)了,某方面也有深度。 春招前端實(shí)習(xí)面試記錄(2019.3 ~ 2019.5) 從2019.1就開(kāi)始漸漸的進(jìn)行復(fù)習(xí),2月末開(kāi)始面試,到現(xiàn)在四月中旬基本宣告結(jié)束。在3月和4月經(jīng)歷了無(wú)數(shù)次失敗,沮...

    atinosun 評(píng)論0 收藏0
  • JS筆記

    摘要:從最開(kāi)始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。異步編程入門(mén)的全稱(chēng)是前端經(jīng)典面試題從輸入到頁(yè)面加載發(fā)生了什么這是一篇開(kāi)發(fā)的科普類(lèi)文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門(mén)教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

    rottengeek 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式

    摘要:可能因?yàn)橄热霝橹?,在編程之中,往往不由自主地以的邏輯編程思路設(shè)計(jì)模式進(jìn)行開(kāi)發(fā)。這是原型模式很重要的一條原則。關(guān)于閉包與內(nèi)存泄露的問(wèn)題,請(qǐng)移步原型模式閉包與高階函數(shù)應(yīng)該可以說(shuō)是設(shè)計(jì)模式的基礎(chǔ)要領(lǐng)吧。在下一章,再分享一下的幾種常用設(shè)計(jì)模式。 前 在學(xué)習(xí)使用Javascript之前,我的程序猿生涯里面僅有接觸的編程語(yǔ)言是C#跟Java——忽略當(dāng)年在大學(xué)補(bǔ)考了N次的C與VB。 從靜態(tài)編程語(yǔ)言,...

    keke 評(píng)論0 收藏0
  • ?前端教學(xué)講義:JS基礎(chǔ)

    講義內(nèi)容:JS 誕生的背景、基本類(lèi)型、運(yùn)算符 以下內(nèi)容只涉及 ES5 標(biāo)準(zhǔn),ES6 增加的新內(nèi)容可以在網(wǎng)上查找到。 JS 誕生的背景 上世紀(jì) 90 年代網(wǎng)景公司開(kāi)發(fā)的瀏覽器獨(dú)步天下 一個(gè)叫做 Brendan Eich 的工程師受命于開(kāi)發(fā)一款腳本語(yǔ)言,來(lái)增強(qiáng)瀏覽器的功能。 這名工程師花費(fèi)了 10 天時(shí)間設(shè)計(jì)出了第一個(gè)版本,名叫 LiveScript。 后來(lái)因?yàn)楫?dāng)時(shí) Java 正紅,公司將其改名為 J...

    walterrwu 評(píng)論0 收藏0
  • 【進(jìn)階 6-1 期】JavaScript 高階函數(shù)淺析

    摘要:引言本期開(kāi)始介紹中的高階函數(shù),在中,函數(shù)是一種特殊類(lèi)型的對(duì)象,它們是。簡(jiǎn)單來(lái)說(shuō),高階函數(shù)是一個(gè)接收函數(shù)作為參數(shù)傳遞或者將函數(shù)作為返回值輸出的函數(shù)。我們來(lái)看看使用它們與不使用高階函數(shù)的方案對(duì)比。引言 本期開(kāi)始介紹 JavaScript 中的高階函數(shù),在 JavaScript 中,函數(shù)是一種特殊類(lèi)型的對(duì)象,它們是 Function objects。那什么是高階函數(shù)呢?本節(jié)將通過(guò)高階函數(shù)的定義來(lái)展...

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

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

0條評(píng)論

閱讀需要支付1元查看
<