call、apply、bind 道理、区分及原生js模仿。

Function的prototype原型上存放着 Function实例 的一些共有要领。
A.Function的原型不像其他类(Array、Object…)的原型一样是个对象,Fuction的原型是一个空函数,是能够实行的,只不过返回undefined,Function.prototype();然则这并不影响它作为一个对象具有本身的属性要领
B.Function这个类,同时也是Function的一个实例,所以它也具有__proto__属性,这个属性指向它本身的原型

1.call要领。每一个函数都能够挪用call要领,来转变当前这个函数实行的this关键字,而且支撑传入参数;我们用原生js模仿call要领,来越发深入相识它。
a.第一个参数为挪用call要领的函数中的this指向
b.第二个及今后的参数为给挪用call要领的函数传入的参数
c.实行这个函数,call要领返回的效果就是 挪用他的函数返回的效果
d.将this指向烧毁。

Function.prototype.mycall = function(context){
    context = context || window;
    context.fn = this;
    var arr = [];
    for(var i = 1;i<arguments.length;i++){
        arr.push('arguments['+i+']');
    }
    var result = eval('context.fn('+arr.toString()+')');
    delete context.fn;
    return result;
}
var obj = {name:'qiaoshi'};
var a = {sex:1}
function say(n){
    console.log(this,n);
}
say.mycall(obj,a)

2.apply和call要领相似,作用都是转变当前函数实行的this指向,而且将函数实行。
唯一差别就是 call要领给当前函数传参是一个一个传。而apply是以数组体式格局传入参数

Function.prototype.myApply =function(context,arr){
context = Object(context) || window;
context.fn = this;
var result;
if(!arr){
    result= context.fn();
}else{
    var args = [];
    for(var i=0;i<arr.length;i++){
        args.push('arr['+i+']');
    }
    result = eval('context.fn('+args.toString()+')')
}
delete context.fn;
return result;
}

var q = {name:'chuchu'};
var arg1 = 1;
var arg2= [123]
function eat(n,m){
    console.log(this,n,m);
}
eat.myApply(q,[arg1,arg2])

3.bind要领,是转变当前挪用bind要领的函数this指向,然则不会马上实行当前函数,而是返回一个新的函数。而且支撑给新的函数传入参数实行,从而动身之前挪用bind要领的函数实行,而且参数透传进去。bind要领是高阶函数的一种。

Function.prototype.myBind = function(){
var context = arguments[0];
var self = this;
return function (){
    self.myApply(context,arguments)
}
};
var j = {name:1};
var k = [123]
function drink (k){
    console.log(this.name,k);
}
var fn = drink.myBind(j);
fn(k);

完成原生 call、apply、bind要领的重点:
1.转变this指向:函数实行,点.前面是谁,this就是谁的道理转变this指向
2.参数透传:经由过程eval将字符串转变成js语法 去实行。
3.bind要领返回一个函数,返回的函数实行,会举行作用域查找context对象;而且经由过程原型链查找挪用apply要领

call、apply、bind雷同和区分
雷同:都能转变函数实行的this指向
差别:callapply 是马上实行 bind是不实行

call传参是一个一个传入,apply是数组情势传入

    原文作者:乔实
    原文地址: https://segmentfault.com/a/1190000013900784
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞