this的指向:
1.普通函数内的this指向全局变量
2.构造函数内部this指向新创建出来的对象
3.对象方法内的this指向的是调用该方法的对象
4.箭头函数中的this与定义时所处的上下文绑定,且不能被改变, 箭头函数this指向取决于它外层找到的离它最近的第一个非箭头函数的this。
相同点:
call,apply,bind都是函数原型的方法,都是改变函数调用时内部this的指向,第一个参数都是函数内部this指向的对象
不同点:
call 从第二个参数开始为函数的参数,而且参数是单一传递,不能以参数数组传递;
apply 从第二个参数开始为函数的参数,而且第二个参数为数组,该数组包含函数的所有参数
bind 从第二个参数开始为函数的参数,而且参数是单一传递,不能以参数数组传递,并且返回一个绑定函数内部this指向的函数
例题:
题:封装函数 f,使 f 的 this 指向指定的对象
call()、bind()、apply()的用法,改变this的指向,区别在于
f.call(obj, arg1, arg2...),
f.bind(obj, arg1, arg2,...)(),
f.apply(obj, [arg1, arg2, .])
1. apply
function applyThis(f, oTarget) {
return function() {
return f.apply(oTarget, arguments)
}
}
2. bind
function bindThis(f, oTarget) {
return f.bind(oTarget)
}
3. call
function callThis(f, oTarget) {
return function() {
return f.call(oTarget, ...arguments)
}
}
为什么有匿名函数,是因为apply call 是绑定之后是立即调用的,所以需要匿名函数包装且需要传入原函数的参数argumengts. bind 会创建一个新函数,即函数副本,绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
题:改变函数fn的this指向
//没改变this指向之前 this指向window
function fn(x, y) {
console.log(this) // Object { name: "chen", age: 18 }
console.log(x + '-' + y) // hh-20
console.log(this.name + '-' + this.age) // chen-18
}
var persoon = {
name: 'chen',
age: 18
}
fn.call(persoon, 'hh', 20) // 改变this指向person
题:this的指向
var obj = {
foo: function () { console.log(this.bar) },
bar: 1
};
var foo = obj.foo;
var bar = 2;
obj.foo() // 1
foo() // 2