call和apply方法的作用与区别:
(1)两者都是改变this的指向;
(2)两者传参的形式不同:
function Person(name,sex){
this.name = name;
this.sex = sex;
}
var obj = { };
Person.call(obj,"hello","boy"); //obj = { name:"hello" ,sex:"boy" }
Person.apply(obj,["hello","boy"]); //obj = { name:"hello" ,sex:"boy" }
/*如果call和apply不传任何参数或参数为null或undefined,那么调用该方法的函数对象中的this默认window;两者第一个参数是指定this的指向,其他参数是相应要传的值,不同的是apply方法的传参必须以数组形式传入*/
(3)call和apply方法实际上并不在函数这个实例对象上,而是在Function的原型对象上
call和apply方法运行机制:
function test(){
console.log("函数被调用了")
}
test() //这种形式相当于test.call()或test.apply(),此时把test看做一个对象,对象test调用方法
call和apply方法总结:
bind方法:
作用是复制函数,改变函数中this的指向,有返回值,不立即执行,需要调用返回值。
call方法的特殊之处:
call方法是内置的方法,我们通过一个函数定义简单了解call的实现原理:
从图上可知,call方法是将其执行主体(函数)中的this指向所传的参数,然后再调用执行主体,即进行了两个步骤。正是因为这个机制才有以下特殊的行为:
function fn1() { console.log(1) }
function fn2() { console.log(2) }
fn1.call( fn2 ) // 1
fn1.call.call( fn2 ) // 2
下图是语句运行的过程,这就是为什么输出结果是2的原因: