call、apply、bind 原理、区别及原生js模拟。

本文深入解析JavaScript中的Function原型上的核心方法:call、apply与bind。详细介绍这些方法如何改变函数执行时的this指向,并探讨它们之间的异同。同时,提供原生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是数组形式传入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值