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

資訊專欄INFORMATION COLUMN

JS手寫(xiě)bind之處理new的情況詳解

3403771864 / 500人閱讀

  你有遇見(jiàn)過(guò)給bind返回的函數(shù)做new操作的場(chǎng)景,本篇主要講述的就是實(shí)現(xiàn)一下兼容new操作的bind寫(xiě)法,順便學(xué)習(xí)一下new操作符,為大家提供下參考。

  大家可以去看下關(guān)于 JS 中 bind 方法的實(shí)現(xiàn)的文章,并給出了實(shí)現(xiàn):

  Function.prototype.myBind = function(thisArg, ...prefixArgs) {
  const fn = this;
  return function(...args) {
  return fn.call(thisArg, ...prefixArgs, ...args);
  }
  }

  但沒(méi)有處理通過(guò) new 創(chuàng)建實(shí)例的情況。

  我們沒(méi)考慮過(guò)給 bind 返回的函數(shù)做 new 操作的場(chǎng)景,主要就是這種情況極少遇見(jiàn)。

  但有時(shí)還是會(huì)出現(xiàn),在實(shí)現(xiàn)一下兼容 new 操作的 bind 寫(xiě)法,順便學(xué)習(xí)一下 new 操作符。

  這里我推薦先看下前一篇文章:《前端面試題:手寫(xiě) bind》。

  new

  我們先學(xué)習(xí)一下 new 操作符。

  new 用于通過(guò)函數(shù)來(lái)創(chuàng)建一個(gè)對(duì)象實(shí)例,在很多語(yǔ)言中都能看到。

  JS 的函數(shù),除了可以是普通函數(shù),比如:

  function sum(a, b) {
  return a + b;
  }

  還可以是構(gòu)造函數(shù),只需要在構(gòu)造時(shí)在它前面加一個(gè) new:

  function Person(name, age) {
  this.name = name;
  this.age = age;
  }
  const person = new Person('前端西瓜哥', 100)
  // Person {name: '前端西瓜哥', age: 100}

  new 創(chuàng)建一個(gè)新對(duì)象,做了下面幾件事:

  創(chuàng)建一個(gè)空對(duì)象{};

  空對(duì)象的原型屬性__proto__指向構(gòu)造函數(shù)的原型對(duì)象Person.prototype;

  函數(shù)中的 this 設(shè)置為這個(gè)空對(duì)象;

  如果該函數(shù)不返回一個(gè)對(duì)象,就返回這個(gè) this,否則返回這個(gè)對(duì)象。

  判斷函數(shù)是否通過(guò) new 被調(diào)用

  怎么判斷一個(gè)函數(shù)正在被 new 操作符調(diào)用?

  答案是使用 instanceof 判斷 this 是否為當(dāng)前函數(shù)的實(shí)例,即this instanceof Fn為 true,表示在通過(guò) new 構(gòu)建實(shí)例。

  先看下實(shí)例:

  function Person() {
  if (this instanceof Person) {
  console.log('通過(guò) new 構(gòu)建實(shí)例');
  } else {
  console.log('普通調(diào)用')
  }
  }
  Person() // 輸出:普通調(diào)用
  new Person() // 輸出:通過(guò) new 構(gòu)建實(shí)例

  在 Vuejs 的源碼,你會(huì)看到下面代碼,這里也用到了這個(gè)技巧。

  function Vue(options) {
  if (__DEV__ && !(this instanceof Vue)) {
  warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
  }

  你在開(kāi)發(fā)環(huán)境如果不通過(guò) new 來(lái)使用 Vue 對(duì)象,會(huì)在控制臺(tái)提示你要通過(guò) new 來(lái)調(diào)用 Vue。

  new 和 bind

  如果我們 new 的是 Function.prototype.bind 返回的新函數(shù),會(huì)發(fā)生什么事情?

  function Person(name, age) {
  this.name = name;
  this.age = age;
  }
  const BoundPerson = Person.bind(null, '前端西瓜哥');
  const boundPerson = new BoundPerson(100);
  // Person {name: '前端西瓜哥', age: 100}
  boundPerson.__proto__ === Person.prototype
  // true

  結(jié)果等價(jià)于直接去 new 原始函數(shù)。

  不同的是,仍舊可以進(jìn)行參數(shù)的預(yù)置。可以看到,構(gòu)造函數(shù)的第一個(gè)參數(shù),在調(diào)用 bind 的時(shí)候就提前設(shè)置為 '前端西瓜哥'。

  實(shí)現(xiàn)完整的 bind

  完整實(shí)現(xiàn)如下:

  Function.prototype.myBind = function(thisArg, ...prefixArgs) {
  const fn = this;
  const boundFn = function(...args) {
  // 通過(guò) new 使用當(dāng)前函數(shù)
  if (this instanceof boundFn) {
  return new fn(...prefixArgs, ...args);
  }
  // 普通的方法調(diào)用當(dāng)前函數(shù)
  return fn.call(thisArg, ...prefixArgs, ...args);
  }
  boundFn.prototype = fn.prototype;
  return boundFn;
  }

  這里我通過(guò)this instanceof boundFn來(lái)判斷是否用了 new,如果是,就直接 new 原始函數(shù)然后返回,記得帶上 bind 預(yù)置好的參數(shù)。

  和原本一樣(參照《前端面試題:手寫(xiě) bind》)。

  boundFn.prototype = fn.prototype;這個(gè)可寫(xiě)可不寫(xiě),只是讓 bind 返回的新函數(shù)的 prototype 指向原函數(shù)的 prototype。

  如果是原生 bind 返回的函數(shù),它是沒(méi)有 protoype 屬性的,可以認(rèn)為它是一種特別的函數(shù),而我們實(shí)現(xiàn)的 bind 返回的卻是一個(gè)普通函數(shù),所以并不能完全模擬的。

  如果你追求完美的實(shí)現(xiàn),可以研讀一下Function.prototype.bind的標(biāo)準(zhǔn):

  然后再看看知名的core.js庫(kù)中對(duì) bind 的實(shí)現(xiàn):

  其中核心實(shí)現(xiàn)為:

  // `Function.prototype.bind` method implementation
  // https://tc39.es/ecma262/#sec-function.prototype.bind
  module.exports = Function.bind || function bind(that /* , ...args */) {
  var F = aCallable(this);
  var Prototype = F.prototype;
  var partArgs = arraySlice(arguments, 1);
  var boundFunction = function bound(/* args... */) {
  var args = concat(partArgs, arraySlice(arguments));
  return this instanceof boundFunction ? construct(F, args.length, args) : F.apply(that, args);
  };
  if (isObject(Prototype)) boundFunction.prototype = Prototype;
  return boundFunction;
  };

  這里有更多的細(xì)節(jié):

  這里判斷了 this 是否為函數(shù)類(lèi)型,不是函數(shù)會(huì)報(bào)錯(cuò);

  F.prototype 需要是一個(gè)對(duì)象或函數(shù),才能賦值給新函數(shù);

  使用了普通函數(shù)和 arguments,這是為了兼容 ES5。

  結(jié)尾

  手寫(xiě) bind,需要我們學(xué)習(xí)更多知識(shí):

  bind 的詳盡用法:包括改變 this、預(yù)置參數(shù)、new 的表現(xiàn);

  閉包的使用:保存一些私有變量;

  通過(guò)原型鏈的方式(this instanceof boundFn)判斷是否通過(guò) new 調(diào)用當(dāng)前函數(shù);

  使用 call 在執(zhí)行時(shí)改變函數(shù)的 this 指向。

  以上就是全部?jī)?nèi)容,歡迎大家繼續(xù)關(guān)注后續(xù)更多精彩內(nèi)容。

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

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

相關(guān)文章

  • 22道JavaScript高頻手寫(xiě)面試題

    JavaScript筆試部分 點(diǎn)擊關(guān)注本公眾號(hào)獲取文檔最新更新,并可以領(lǐng)取配套于本指南的 《前端面試手冊(cè)》 以及最標(biāo)準(zhǔn)的簡(jiǎn)歷模板. 實(shí)現(xiàn)防抖函數(shù)(debounce) 防抖函數(shù)原理:在事件被觸發(fā)n秒后再執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計(jì)時(shí)。 那么與節(jié)流函數(shù)的區(qū)別直接看這個(gè)動(dòng)畫(huà)實(shí)現(xiàn)即可。 showImg(https://segmentfault.com/img/remote/146000002...

    Alan 評(píng)論0 收藏0
  • 「中高級(jí)前端面試」JavaScript手寫(xiě)代碼無(wú)敵秘籍

    摘要:第一種直接調(diào)用避免在不必要的情況下使用,是一個(gè)危險(xiǎn)的函數(shù),他執(zhí)行的代碼擁有著執(zhí)行者的權(quán)利。來(lái)自于此外,實(shí)現(xiàn)需要考慮實(shí)例化后對(duì)原型鏈的影響。函數(shù)柯里化的主要作用和特點(diǎn)就是參數(shù)復(fù)用提前返回和延遲執(zhí)行。手寫(xiě)路徑導(dǎo)航 實(shí)現(xiàn)一個(gè)new操作符 實(shí)現(xiàn)一個(gè)JSON.stringify 實(shí)現(xiàn)一個(gè)JSON.parse 實(shí)現(xiàn)一個(gè)call或 apply 實(shí)現(xiàn)一個(gè)Function.bind 實(shí)現(xiàn)一個(gè)繼承 實(shí)現(xiàn)一個(gè)J...

    Zhuxy 評(píng)論0 收藏0
  • 面試題里那些各種手寫(xiě)

    摘要:最近準(zhǔn)備初級(jí)前端面試,發(fā)現(xiàn)有很多手寫(xiě)實(shí)現(xiàn)什么的,例如什么手寫(xiě)實(shí)現(xiàn),。后面以這道題為引線面試官可能會(huì)追問(wèn)什么是執(zhí)行上下文的判斷,的區(qū)別手寫(xiě)一個(gè)函數(shù)實(shí)現(xiàn)斐波那契數(shù)列首先拷一個(gè)阮神在他教程里的一個(gè)寫(xiě)法。 最近準(zhǔn)備初級(jí)前端面試,發(fā)現(xiàn)有很多手寫(xiě)實(shí)現(xiàn)什么的,例如什么手寫(xiě)實(shí)現(xiàn)bind,promise。手寫(xiě)ajax,手寫(xiě)一些算法。翻閱了很多書(shū)籍和博客。 這里做一個(gè)總結(jié)改進(jìn),算是對(duì)我后面大概為期一個(gè)月找...

    wh469012917 評(píng)論0 收藏0
  • 2019-我前端面試題

    摘要:先說(shuō)下我面試情況,我一共面試了家公司。篇在我面試的眾多公司里,只有同城的面問(wèn)到相關(guān)問(wèn)題,其他公司壓根沒(méi)問(wèn)。我自己回答的是自己開(kāi)發(fā)組件面臨的問(wèn)題。完全不用擔(dān)心對(duì)方到時(shí)候打電話核對(duì)的問(wèn)題。 2019的5月9號(hào),離發(fā)工資還有1天的時(shí)候,我的領(lǐng)導(dǎo)親切把我叫到辦公室跟我說(shuō):阿郭,我們公司要倒閉了,錢(qián)是沒(méi)有的啦,為了不耽誤你,你趕緊出去找工作吧。聽(tīng)到這話,我虎軀一震,這已經(jīng)是第2個(gè)月沒(méi)工資了。 公...

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

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

0條評(píng)論

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