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

資訊專欄INFORMATION COLUMN

this總結(jié)【2】—— call/apply和bind

wudengzan / 1485人閱讀

摘要:和概覽我們要將歸為一類,多帶帶歸為一類三者的共同點(diǎn)是都可以指定和都是綁定在的原型上的,所以的實(shí)例都可以調(diào)用這三個(gè)方法至于為什么,看完這篇文章你就懂了如果你不懂什么是實(shí)例的話,請(qǐng)移步深入淺出面向?qū)ο蠛驮透拍钇钊霚\出面向?qū)ο蠛驮透拍钇谝粋€(gè)

1.call/apply和bind概覽

我們要將call/apply歸為一類,bind多帶帶歸為一類

三者的共同點(diǎn)是都可以指定this

call/apply和bind都是綁定在Function的原型上的,所以Function的實(shí)例都可以調(diào)用這三個(gè)方法

Function.prototype.call(this,arg1,arg2)
Function.prototype.apply(this,[arg1,arg2])
Function.prototype.bind(this,arg1,arg2)

至于為什么,看完這篇文章你就懂了:)

如果你不懂什么是實(shí)例的話,請(qǐng)移步深入淺出面向?qū)ο蠛驮汀靖拍钇?】、深入淺出面向?qū)ο蠛驮汀靖拍钇?】
2. call / apply —— 第一個(gè)參數(shù)是this(上下文) 2.1 作用和返回值
作用

調(diào)用函數(shù)

改變?cè)摵瘮?shù)this值

操作參數(shù)

返回值
返回值是你調(diào)用的方法的返回值,若該方法沒有返回值,則返回undefined。
    window.a = 1

    function print(b, c) {
        console.log(this.a, b, c)
    }

    print(2, 3) // 1 2 3

    print.call({a: -1}, -2, -3) // -1 -2 -3
    print.apply({a: 0}, [-2, -3]) // 0 -2 -3

call()方法的作用和 apply() 方法是一樣的,只有一個(gè)區(qū)別
call()方法接受的是若干個(gè)參數(shù)
apply()方法接受的是一個(gè)包含若干個(gè)參數(shù)的數(shù)組

2.2 apply傳遞數(shù)組的應(yīng)用
    // 例子一
    // Math.max()不接收數(shù)組的傳遞,我們可以使用apply方法
    let answer = Math.max.apply(null, [2, 4, 3])
    console.log(answer) // 4

    // 注意下面三個(gè)等價(jià)
    Math.max.apply(null, [2, 4, 3])
    Math.max.call(null, 2, 4, 3)
    Math.max(2, 4, 3)
    // 例子二
    // 合并兩個(gè)數(shù)組
    let arr1 = ["parsnip", "potato"]
    let arr2 = ["celery", "beetroot"]
    // 將第二個(gè)數(shù)組融合進(jìn)第一個(gè)數(shù)組
    // 相當(dāng)于 arr1.push("celery", "beetroot");
    Array.prototype.push.apply(arr1, arr2)
    // 注意?。?!this的意思是誰調(diào)用了push這個(gè)方法
    // 所以當(dāng) this = arr1 后
    // 就成了 arr1 調(diào)用了 push方法
    // 所以上述表達(dá)式等價(jià)于 arr1.push("celery", "beetroot") 

    console.log(arr1)
    // ["parsnip", "potato", "celery", "beetroot"]

例子二中非常值得注意的就是arr2數(shù)組被拆開了,成了一個(gè)一個(gè)的參數(shù)

所以,apply經(jīng)常性的作用之一就是將數(shù)組元素迭代為函數(shù)參數(shù)
    // 例子三
    Math.max.apply(null, [2, 4, 3]) // 完美運(yùn)行
    arr1.push.apply(null, arr2) // 報(bào)錯(cuò) Uncaught TypeError: Array.prototype.push called on null or undefined

    // 說明
    Math = {
        max: function (values) {
            // 沒用到this值
        }
    }
    Array.prototype.push = function (items) {
        // this -> 調(diào)用push方法的數(shù)組本身
        // this為null的話,就是向null里push
        // Array.prototype.push called on null or undefined
    }
    // 下面三個(gè)值是完全等價(jià)的,因?yàn)閠his值已經(jīng)是arr1
    Array.prototype.push.apply(arr1, arr2)
    arr1.push.apply(arr1, arr2)
    arr2.push.apply(arr1, arr2)
2.3 小測(cè)試
    function xx() {
        console.log(this)
    }
    xx.call("1") // ??
    xx() // ??
如果答案和你想的不一樣,請(qǐng)移步this總結(jié)【1】—— this概覽
3.bind
fun.bind(thisArg[, arg1[, arg2[, ...]]])
3.1作用

改變this

返回一個(gè)新函數(shù)

3.2 綁定函數(shù)、目標(biāo)函數(shù)

實(shí)例使用bind()方法后會(huì)返回一個(gè)新的函數(shù)【綁定函數(shù)】
原函數(shù)為【目標(biāo)函數(shù)】

我個(gè)人更喜歡用新函數(shù)原函數(shù)來區(qū)分,因?yàn)樾旅~越多,理解上的困難越大

那么新函數(shù)被調(diào)用時(shí)會(huì)發(fā)生什么呢?
下面一句話務(wù)必記住
其實(shí)就是把原函數(shù)call/apply一下,并指定你傳遞的this

    function xx() {
        console.log(this)
    }

    let foo = xx.bind({"name":"jason"})
    // foo —— 新函數(shù)【綁定函數(shù)】
    // xx —— 原函數(shù)【目標(biāo)函數(shù)】

    foo()

    // 新函數(shù)調(diào)用時(shí)對(duì)原函數(shù)的操作
    
    // 下面是偽代碼
    // function foo(){
    //     xx.call({"name":"jason"})
    // }

    // 1.給xx(原函數(shù))指定this 2.調(diào)用xx(原函數(shù))
    // 一定要注意這兩步是在新函數(shù)被調(diào)用時(shí)才發(fā)生,不調(diào)用不發(fā)生
    // 你也可以總結(jié)為一句話,給原函數(shù) call/apply 了一下
3.3 bind()傳參和新函數(shù)【綁定函數(shù)】傳參

bind(this,arg1)會(huì)將arg1插入到原函數(shù)【目標(biāo)函數(shù)】的參數(shù)列表的開始位置

傳遞給新函數(shù)【綁定函數(shù)】的參數(shù)會(huì)跟在它們的后面

    function list() {
        // 原函數(shù)【目標(biāo)函數(shù)】
        return Array.prototype.slice.call(arguments);
    }

    let listTest = list(1, 2, 3); // [1, 2, 3]

    // 新函數(shù)【綁定函數(shù)】
    let leadingThirtysevenList = list.bind(undefined, 37);

    let list1 = leadingThirtysevenList(); // [37]
    let list2 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
3.3 原生實(shí)現(xiàn)一個(gè)bind,使用 this + call/apply【重點(diǎn)】
思考過程
    // 實(shí)現(xiàn)bind其實(shí)就是實(shí)現(xiàn)bind的特點(diǎn)
    // 1.bind的第一個(gè)參數(shù)是this
    // 2.bind可以return一個(gè)新函數(shù),這個(gè)新函數(shù)可以調(diào)用原函數(shù)并且可以指定其this,還可以接受參數(shù)
    // 3.bind返回的新函數(shù)傳遞的參數(shù)要在bind傳遞的參數(shù)的后面
代碼
    Function.prototype._bind = function () {
        // 聲明bind接受的參數(shù)【除去this】為bindArgs
        // 因?yàn)榈谝粋€(gè)參數(shù)是this,需要去掉
        let bindArgs = Array.prototype.slice.call(arguments, 1)
        let bindThis = arguments[1]
        // 聲明原函數(shù)【目標(biāo)函數(shù)】為targetObj
        let targetObj = this
        return function () {
            // return出來的的函數(shù)接受的參數(shù)為newArgs
            // 要在return出來的新函數(shù)里把bindArgs和newArgs合并,使用數(shù)組的concat方法
            let newArgs = Array.prototype.slice.call(arguments)
            return targetObj.apply(bindThis, bindArgs.concat(newArgs))
        }
    }
4. 既然都是指定this,為什么已經(jīng)有call/apply,又要有bind呢? 4.1 你從未關(guān)注過函數(shù)的返回值
你在控制臺(tái)輸入console.log(1)為什么一個(gè)是1,一個(gè)是undefined?

1是執(zhí)行console.log()方法的輸出值,undefined是這個(gè)方法的返回值
所以,你要知道所有的函數(shù)都有返回值,一定要去關(guān)注一下函數(shù)的返回值
4.2 call/apply 與 bind 的返回值
xxx.call()/xxx.apply() 的返回值是由xxx本身的返回值決定的
xxx.bind() 的返回值是一個(gè)函數(shù)

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

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

相關(guān)文章

  • 根據(jù)一道題引發(fā)的call、apply、bind方法總結(jié)

    摘要:首先介紹一下和的定義和的作用是改變函數(shù)運(yùn)行時(shí)的上下文環(huán)境改變的指向?qū)⒔壎ǖ交蛘哒f調(diào)用了里面的方法。方法返回的是修改過后的函數(shù)追夢(mèng)子追夢(mèng)子執(zhí)行成功 這是一道今天遇到的面試題 showImg(https://segmentfault.com/img/bV8lco?w=330&h=222); 因?yàn)閟etTimeout屬于匿名函數(shù),this指向window,所以this.id = 1但還是先總...

    ormsf 評(píng)論0 收藏0
  • ES5 call,apply,bind方法總結(jié)(包括理解this的指向問題)

    總結(jié)call,apply,bind方法的理解使用和區(qū)別。 call,apply,bind這三個(gè)方法在JavaScript中是用來改變函數(shù)調(diào)用的this指向。那么改變函數(shù)this指向有什么用呢?我們先來看一段代碼 var a= { name:harden, fn:function () { console.log(this.name); } } var b =...

    nanchen2251 評(píng)論0 收藏0
  • 前端基礎(chǔ)知識(shí)總結(jié)

    摘要:關(guān)于前端中是個(gè)老生常談的問題,總是說不清道不明,看這里。的大致用法,相信接觸過前端的同學(xué)都知道,無非以下種。先想一下,兩次執(zhí)行后結(jié)果是什么。輸出總結(jié)被誰調(diào)用指向誰,沒有被調(diào)用的情況下,瀏覽器默認(rèn)為。由于箭頭函數(shù)中的,總是指向父級(jí)作用域。 關(guān)于this 前端中this是個(gè)老生常談的問題,總是說不清道不明,看這里。this只能用在函數(shù)里面,相信全世界的人都知道。this就是函數(shù)在被執(zhí)行的時(shí)...

    MageekChiu 評(píng)論0 收藏0
  • 前端基礎(chǔ):call,apply,bind的的理解

    摘要:和區(qū)別其實(shí)他們的作用是一樣的,只是傳遞的參數(shù)不一樣而已。接受個(gè)參數(shù),第一個(gè)參數(shù)指定了函數(shù)體內(nèi)對(duì)象的指向,第二個(gè)參數(shù)為數(shù)組或者一個(gè)類數(shù)組??磦€(gè)栗子一個(gè)有意思的事在中,多次是無效的。而則會(huì)立即執(zhí)行函數(shù)。 背景 前兩天在做小程序的需求的時(shí)候用到bind的時(shí)候才想起自己對(duì)這三的東西的了解比較淺薄,這個(gè)時(shí)候用的時(shí)候就有點(diǎn)怕。時(shí)候還是要好好學(xué)習(xí)下,理解下怎么玩。 正文 先說call 和 apply...

    netmou 評(píng)論0 收藏0
  • javascript關(guān)于this 以及this的顯示設(shè)置(apply、call、bind)

    摘要:如果連續(xù)呢結(jié)果會(huì)是什么結(jié)果還是第一個(gè)原因是,在中,多次是無效的。更深層次的原因,的實(shí)現(xiàn),相當(dāng)于使用函數(shù)在內(nèi)部包了一個(gè),第二次相當(dāng)于再包住第一次故第二次以后的是無法生效的。 this 1.其實(shí)js中的this沒那么難理解,當(dāng)找不到this時(shí)記住一句話:誰調(diào)我,我就指誰!new 誰指誰 function text1(){ console.log(this); //指wind...

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

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

0條評(píng)論

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