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

資訊專欄INFORMATION COLUMN

call、bind的模擬實現(xiàn)

mmy123456 / 788人閱讀

摘要:大致就是這樣所以可以模擬實現(xiàn)和。這些參數(shù)作為的第二個參數(shù)跟在后面,之后它們會被插入到目標(biāo)函數(shù)的參數(shù)列表的開始位置,傳遞給綁定函數(shù)的參數(shù)會跟在它們的后面。

一個前端知識點匯總

綜合了學(xué)習(xí)過程中的知識點,比如this、閉包、BFC、ES6等,如果大佬們覺得還可以的話,求個star啦!

call和apply

每個函數(shù)都包含兩個非繼承而來的方法:apply()和call()

用途相同,都是在特定的作用域中調(diào)用函數(shù)

接收參數(shù)方面不同,apply接收兩個參數(shù),一個是函數(shù)運行時的作用域(this),另一個是參數(shù)數(shù)組;call方法第一個參數(shù)與apply方法相同,但傳遞給函數(shù)的參數(shù)必須列舉出來。

call()方法調(diào)用一個函數(shù),其具有一個指定的this值和分別提供的參數(shù):

fun.call(thisArg, arg1, arg2, ...)

apply()方法調(diào)用一個函數(shù),其具有一個指定的this值,以及作為一個數(shù)組(或類似數(shù)組的對象)提供的參數(shù):

fun.apply(thisArg, [argsArray])

舉個栗子???:

var one = {
    name: "one",
    sayName: function(age) {
        console.log(`Hello, I"m ${this.name}, and I"m ${age} years old`)
    }
}
var day = {
    name: "day"
}
one.sayName.call(day, 20) // Hello, I"m day, and I"m 20 years old
one.sayName.apply(day, [20]) // Hello, I"m day, and I"m 20 years old

fn.call(o)的原理就是先通過o.m = fn將fn作為o的某個臨時屬性m存儲,然后執(zhí)行m,執(zhí)行完畢后將m屬性刪除。

大致就是這樣:

day.fn = one.sayName
day.fn()
delete day.fn

所以可以模擬實現(xiàn)apply和call。

首先來看apply的模擬:

第一版
Function.prototype.applyOne = function() {
    var context = arguments[0]
    var args = arguments[1]
    context.fn = this
    eval(context.fn(args.join(","))) // args.join(",")返回的是string,所以需要進(jìn)行一下特殊處理)
    delete context.fn
}

one.sayName.applyOne(day, [20]) // Hello, I"m day, and I"m 20 years old
第二版

要注意到的是,若this傳入的是null,或者不傳入,則會默認(rèn)是全局環(huán)境,并且apply是有返回值的。

Function.prototype.applyTwo = function() {
    var context = arguments[0] || window
    var args = arguments[1]
    context.fn = this

    if (args == void 0) {
        return context.fn()
    } 
    var result = eval(context.fn(args.join(","))) // args.join(",")返回的是string,所以需要進(jìn)行一下特殊處理
    delete context.fn
    return result
}

var name = "oneday"

var one = {
    name: "one",
    sayName: function(age) {
        console.log(`Hello, I"m ${this.name}, and I"m ${age} years old`)
    }
}
var day = {
    name: "day"
}
one.sayName.applyTwo(null, [20]) // Hello, I"m oneday, and I"m 20 years old

emmmm...有一個問題就是萬一context里面本來就有fn屬性怎么辦呢...對于es6而言,可以將fn設(shè)置為一個獨特的Symbol值,如下:

var fn1 = Symbol("aaa")
var fn2 = Symbol("aaa")
fn1 == fn2 // false

但是畢竟symbol是es6的特性啊,所以在es5中可以使用產(chǎn)生隨機數(shù)的方法,例如:

var fn1 = "o" + Math.random()
var fn2 = "o" + Math.random()

接下來就是apply:

Function.prototype.callOne = function() {
    var context = [].shift.applyTwo(arguments)
    var args = [].slice.applyTwo(arguments) // 將剩下的參數(shù)作為數(shù)組傳入啊
    return this.applyTwo(context, args)
}

emmmm...第一個參數(shù)就是arguments的第一個(一般是this,或者沒有),后面的參數(shù)就作為數(shù)組形式傳入。

bind方法

bind方法創(chuàng)建一個新的函數(shù),當(dāng)被調(diào)用時,this值是傳遞給bind的第一個參數(shù),它的參數(shù)是bind其他的參數(shù)和其原本的參數(shù),返回的是由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝。

fun.bind(thisArg[, arg1[, arg2[, ...]]])

實例:

var name = "2333"
function Person(name) {
    this.name = name
    this.sayName = function() {
        setTimeout(function() {
            console.log(`Hello, I"m ${this.name}`)
        }, 1000)
    }
}

var oneday = new Person("1111")
oneday.sayName() // Hello, I"m 2333

但是下面這樣就是1111~

this.sayName = function() {
    setTimeout(function() {
        console.log(`Hello, I"m ${this.name}`)
    }.bind(this), 1000)
}

var oneday = new Person("1111")
oneday.sayName() // Hello, I"m 1111

而且還有偏函數(shù)(Partial Functions),在mdn中是這么說的:

bind()的另一個最簡單的用法是使一個函數(shù)擁有預(yù)設(shè)的初始參數(shù)。這些參數(shù)作為bind()的第二個參數(shù)跟在this后面,之后它們會被插入到目標(biāo)函數(shù)的參數(shù)列表的開始位置,傳遞給綁定函數(shù)的參數(shù)會跟在它們的后面。

emmmm...對呀?jīng)]看懂,于是就看例子啊...

function list() {
    return Array.prototype.slice.call(arguments)
}

var list1 = list(1, 2, 3) // [1, 2, 3]

// 所以listFun是擁有預(yù)設(shè)參數(shù)(5, 6)的,作為預(yù)設(shè)參數(shù)跟在第一個參數(shù)this后面
var listFun = list.bind(undefined, 5, 6)

// 后面?zhèn)魅氲膮?shù)會跟在預(yù)設(shè)參數(shù)的后面
var list2 = listFun(7) // [5, 6, 7]
var list3 = listFun(8, 9) // [5, 6, 8, 9]

bind的模擬實現(xiàn):

第一版
Function.prototype.bindOne = function() {
    var me = this // 緩存this
    var argArray = Array.prototype.slice.call(arguments, 1)
    return function() {
        return me.apply(arguments[0], argArray)
    }
}

但是上述的沒有實現(xiàn)繼續(xù)傳參可以添加到原參數(shù)后的功能...所以有了第二版

第二版
Function.prototype.bindTwo = function() {
    var context = arguments[0]
    var me = this
    var argArray = Array.prototype.slice.call(arguments, 1)
    return function() {
        var innerArgs = Array.prototype.slice.call(arguments)
        var finalArgs = argArray.concat(innerArgs)
        return me.apply(context, finalArgs)
    }
}

bind返回的函數(shù)如果作為構(gòu)造函數(shù),這個構(gòu)造函數(shù)搭配new關(guān)鍵字出現(xiàn)的話,bind綁定的this需要被忽略,但是參數(shù)還要繼續(xù)傳入。意思就是bind的綁定比new的優(yōu)先級要低。而且要在函數(shù)體內(nèi)判斷調(diào)用bind方法的一定要是一個函數(shù)。

復(fù)習(xí)一下new的作用:

創(chuàng)建一個新對象

新對象繼承了該函數(shù)的原型(因此this就指向了這個新對象)

為這個新對象添加屬性和方法并返回這個新對象

var obj = {}
obj.__proto__ = Base.prototype
Base.call(obj)
第三版
Function.prototype.bindThree = function() {
    if (typeof this !== "function") {
        throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable")
    }

    // context指要把this綁定到的目標(biāo)函數(shù)
    var context = arguments[0]

    // 這里的this指向調(diào)用bind的函數(shù)
    var me = this
    var argArray = Array.prototype.slice.call(arguments, 1)

    var F = function() {}
    F.prototype = this.prototype
    var bound = function() {
        var innerArgs = Array.prototype.slice.call(arguments)
        var finalArgs = argArray.concat(innerArgs)

        // 如果調(diào)用bind的函數(shù)是F的實例,那么this就還是指向調(diào)用bind的函數(shù),如果不是F的實例,那么this就進(jìn)行改變
        return me.apply(this instanceof F ? this : context, finalArgs)
    }
    bound.prototype = new F()
    return bound
}
參考:

不用call和apply方法模擬實現(xiàn)ES5的bind方法

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

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

相關(guān)文章

  • JavaScript深入之bind模擬實現(xiàn)

    摘要:也就是說當(dāng)返回的函數(shù)作為構(gòu)造函數(shù)的時候,時指定的值會失效,但傳入的參數(shù)依然生效。構(gòu)造函數(shù)效果的優(yōu)化實現(xiàn)但是在這個寫法中,我們直接將,我們直接修改的時候,也會直接修改函數(shù)的。 JavaScript深入系列第十一篇,通過bind函數(shù)的模擬實現(xiàn),帶大家真正了解bind的特性 bind 一句話介紹 bind: bind() 方法會創(chuàng)建一個新函數(shù)。當(dāng)這個新函數(shù)被調(diào)用時,bind() 的第一個參數(shù)...

    FingerLiu 評論0 收藏0
  • JavaScript進(jìn)階之模擬call,apply和bind

    摘要:模擬和模擬一樣,現(xiàn)摘抄下面的代碼添加一個返回值對象然后我們定義一個函數(shù),如果執(zhí)行下面的代碼能夠返回和函數(shù)一樣的值,就達(dá)到我們的目的。 原文:https://zhehuaxuan.github.io/... 作者:zhehuaxuan 目的 本文主要用于理解和掌握call,apply和bind的使用和原理,本文適用于對它們的用法不是很熟悉,或者想搞清楚它們原理的童鞋。 好,那我們開始...

    CoderBear 評論0 收藏0
  • 【進(jìn)階3-4期】深度解析bind原理、使用場景及模擬實現(xiàn)

    摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器,提供的值被忽略,同時調(diào)用時的參數(shù)被提供給模擬函數(shù)。 bind() bind() 方法會創(chuàng)建一個新函數(shù),當(dāng)這個新函數(shù)被調(diào)用時,它的 this 值是傳遞給 bind() 的第一個參數(shù),傳入bind方法的第二個以及以后的參數(shù)加上綁定函數(shù)運行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。bind返回的綁定函數(shù)也能使用 n...

    guyan0319 評論0 收藏0
  • 面試官問:能否模擬實現(xiàn)JSbind方法

    摘要:點擊那么面試官可能會問是否想過到底做了什么,怎么模擬實現(xiàn)呢。另外前不久寫過一篇文章面試官問能否模擬實現(xiàn)的操作符。所以相當(dāng)于調(diào)用時,的返回值函數(shù)內(nèi)部要模擬實現(xiàn)實現(xiàn)的操作。文章中的例子和測試代碼放在中模擬實現(xiàn)。 前言 用過React的同學(xué)都知道,經(jīng)常會使用bind來綁定this。 import React, { Component } from react; class TodoItem ...

    Julylovin 評論0 收藏0
  • JavaScript專題之模擬實現(xiàn)bind

    摘要:但是三作為構(gòu)造函數(shù)時函數(shù)其實還有一個非常重要的特點返回的函數(shù)如果作為構(gòu)造函數(shù),搭配關(guān)鍵字出現(xiàn)的話,我們的綁定就需要被忽略。其次,當(dāng)返回的函數(shù)作為構(gòu)造函數(shù)時,之前綁定的會失效。 本文共 1100 字,讀完只需 4 分鐘 概述 前一篇文章我們嘗試模擬實現(xiàn)了 call 和 apply 方法,其實 bind 函數(shù)也可以用來改變 this 的指向。bind 和 call和 apply 兩者的區(qū)別...

    劉明 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<