call、apply、bind改变this的指向;
fn.call()
当前实例通过原型链查找,直到找到function.prototype上的call方法;
call方法执行时:
1、首先把要操作的函数中的this关键字变为call方法第一个传递的实参;
2、把call方法第二个及以后的实例获取到;
3、把要操作的函数执行,并且把第二以后传递进来的实参传递给函数;
*非严格模式:不传参数时,或第一个参数是null或undefined,this都指向window
*严格模式:第一个参数是谁就是谁,包括null和undefined,如果不传参数this就是undefined
"use strict"
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call(obj,1,2); // this:obj a:1 b:2
fn.call(1,2); // this:1 a:2 b=undefined
fn.call(); // this:undefined a:undefined b:undefined
fn.call(null); // this:null a:undefined b:undefined
fn.call(undefined); // this:undefined a:undefined b:undefined
fn.apply()
与call()基本一致,只是传参为数组;
fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);
fn.bind()
语法和call()一模一样,区别在于立即执行还是等待执行,bind不兼容ie6~8;
fn1.call(obj, 1, 2); // 改变fn中的this,并且把fn立即执行
fn2.bind(obj, 1, 2); // 改变fn中的this,fn并不执行
document.onclick = fn1.call(obj);
绑定的时候立即执行,点击触发时,返回undefined;
document.onclick = fn2.bind(obj)
bind()把fn2的this预处理为obj,但没有执行,点击时才会执行;
关于this
(1)new时,函数内的this是一个全新对象
(2)call、applay和bind用于调用、创建一个函数,this作为参数传入这些方法的对象
(3)当函数作为对象里的方法被调用时,this指向调用该函数的对象
(4)如果不符合以上,指向全局(浏览器指向window、严格模式指向undefined)
(5)如果符合以上多个规则,优先级1高4低
(6)如果函数是ES6的箭头函数,指向context,即他创建时的上下文
var a = {
b() {
name:"b"
console.log(this)
}
}
c = {
name:"c"
}
d = {
name:"d"
}
e = {
name:"e"
}
a.b();//b
// c.b();//not a function
a.b.bind(d)();//d
a.b.bind(d).call(e)//d
只能识别第一次绑定;
本文用于学习和分享,欢迎指正。