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

資訊專欄INFORMATION COLUMN

詳解call bind apply - 區(qū)別/使用場景/es6實(shí)現(xiàn)/es3實(shí)現(xiàn)

Alex / 3110人閱讀

摘要:的區(qū)別接收數(shù)組一連串參數(shù)返回一個函數(shù)的使用場景將類數(shù)組含有屬性的對象轉(zhuǎn)化為數(shù)組類數(shù)組例如通過獲取的元素含有屬性的對象具有屬性,并且可以通過下標(biāo)來訪問其中的元素,但是沒有中的等方法。

call,apply,bind的區(qū)別

apply接收數(shù)組 func.apply(obj, [arus])

call一連串參數(shù) func.call(obj, param1, param2....)

bind返回一個函數(shù) func.bind(obj,param...)(parms...)

call,apply,bind的使用場景

將類數(shù)組/含有l(wèi)ength屬性的對象轉(zhuǎn)化為數(shù)組

類數(shù)組:(例如通過document.getElementsByTagName獲取的元素、含有l(wèi)ength屬性的對象)具有l(wèi)ength屬性,并且可以通過0、1、2…下標(biāo)來訪問其中的元素,但是沒有Array中的push、pop等方法。

注意:但是這個不適用于IE6~8,會報錯,只能使用循環(huán)來解決

// 類數(shù)組
let trueArr = Array.prototype.slice.call(arrayLike)
// 含有l(wèi)ength屬性的對象
let obj4 = {
    0: 1,
    1: "thomas",
    2: 13,
    length: 3 // 一定要有l(wèi)ength屬性
};
console.log(Array.prototype.slice.call(obj4)); // [1, "thomas", 13]

求數(shù)組中的最大和最小值

注意:邊界問題,臨界值大概在 [ 參數(shù)個數(shù)限制在65536]

let arr = [1,2,3,89,46]
let max = Math.max.apply(null,arr)//89
let min = Math.min.apply(null,arr)//1

數(shù)組追加

數(shù)組方法contact比較:contact返回新數(shù)組,不修改原數(shù)組

let arr1 = [1,2,3]
let arr2 = [4,5,6]
let total = [].push.apply(arr1, arr2) //6

利用call和apply做繼承

function Person(name,age){
    // 這里的this都指向?qū)嵗?    this.name = name
    this.age = age
    this.sayAge = function(){
        console.log(this.age)
    }
}
function Female(){
    Person.apply(this,arguments)//將父元素所有方法在這里執(zhí)行一遍就繼承了
}
let dot = new Female("Dot",2)

判斷變量類型

function isArray(obj){
    return Object.prototype.toString.call(obj) == "[object Array]"
}
isArray([]) // true
isArray("dot") // false

其他:使用 log 代理 console.log

function log(){
  console.log.apply(console, arguments);
}
// 當(dāng)然也有更方便的 let log = console.log()

bind 實(shí)現(xiàn)

特點(diǎn):

返回一個函數(shù)

可以傳入?yún)?shù)(使用bind時和bind新生成的函數(shù)都可以傳參)

當(dāng) bind 返回的函數(shù)作為構(gòu)造函數(shù)的時候,bind 時指定的 this 值會失效,但傳入的參數(shù)依然生效

var bindFoo = bar.bind(foo, "daisy");
var obj = new bindFoo("18");

注意:bind這個方法在IE6~8下不兼容

// 使用apply和call來實(shí)現(xiàn)this指向問題
Function.prototype.bind2 = function (context) {
    if (typeof this !== "function") {
      throw new Error("what is trying to be bound is not callable");
    }
    var self = this;
   // 獲得bind的參數(shù)從第二個參數(shù)到最后一個參數(shù)
    var args = Array.prototype.slice.call(arguments, 1);
    var fNOP = function () {};
    var fBound = function () {
        // 指bind返回的函數(shù)傳入的參數(shù)
        var bindArgs = Array.prototype.slice.call(arguments);
       // 當(dāng)作為構(gòu)造函數(shù)時,this 指向?qū)嵗?,此時結(jié)果為 true,將綁定函數(shù)的 this 指向該實(shí)例,可以讓實(shí)例獲得來自綁定函數(shù)的值
        // 以上面的是 demo 為例,如果改成 `this instanceof fBound ? null : context`,實(shí)例只是一個空對象,將 null 改成 this ,實(shí)例會具有 habit 屬性
        // 當(dāng)作為普通函數(shù)時,this 指向 window,此時結(jié)果為 false,將綁定函數(shù)的 this 指向 context
        // new bind返回的函數(shù),this失效,但傳入的參數(shù)生效
        return self.apply(this instanceof fNOP ? this : context,                                args.concat(bindArgs));
    }
    
    // fBound.prototype = this.prototype;
    // 保證繼承,原型鏈,讓 fBound 構(gòu)造的實(shí)例能夠繼承綁定函數(shù)的原型中的值,下面兩行代碼等同于Object.creater()  fbound.prototype = Object.create(this.prototype);
    // 我們直接修改 fBound.prototype 的時候,也會直接修改綁定函數(shù)的 prototype。這個時候,我們可以通過一個空函數(shù)來進(jìn)行中轉(zhuǎn)
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}

// es6實(shí)現(xiàn)
Function.prototype.bind = function(context) {
    if(typeof this !== "function"){
       throw new TypeError("not a function");
    }
    let self = this;
    let args = [...arguments].slice(1);
    function Fn() {};
    Fn.prototype = this.prototype;
    let bound = function() {
        let res = [...args, ...arguments]; //bind傳遞的參數(shù)和函數(shù)調(diào)用時傳遞的參數(shù)拼接
        context = this instanceof Fn ? this : context || this;
        return self.apply(context, res);
    }
    //原型鏈
    bound.prototype = new Fn();
    return bound;
}
call 實(shí)現(xiàn)

實(shí)現(xiàn)思路

將函數(shù)設(shè)為對象的屬性 foo.fn = bar

執(zhí)行該函數(shù) foo.fn()

刪除該函數(shù) delete foo.fn

注意的點(diǎn)

接受不定長參數(shù) - Arguments 對象中取值,第二個到最后一個參數(shù),然后放到一個數(shù)組里

this 參數(shù)可以傳 null,當(dāng)為 null 的時候,視為指向 window

函數(shù)是可以有返回值的!

難點(diǎn)解析 - 接受不定長參數(shù)

var args = [];
// 為了拼出一個參數(shù)字符串,arguments類數(shù)組,不能使用
for(var i = 1, len = arguments.length; i < len; i++) {
      // args: ["arguments[1]", "arguments[2]", .....]
    args.push("arguments[" + i + "]");
}
// 1. context.fn(args.join(",")) es6語法實(shí)現(xiàn)es3的call方法不合適
// 2. 這里 args 會自動調(diào)用 Array.toString() 這個方法
// 3. eval作用:看成是                
閱讀需要支付1元查看
<