Ⅰ.this的指向:
【在js中this不是固定不变的,它会随着执行环境的改变而改变。this取什么值,是在执行时确认的,定义时无法确认。】
this的调用大概分为五种场景:
1.浏览器里,在全局范围内的this 指向window对象;
2.在函数中,this永远指向最后调用他的那个对象;
3.构造函数中,this指向new出来的那个新的对象;
4.Call、apply、bind中的this被强绑定在指定的那个对象上;
5.箭头函数中this比较特殊,箭头函数this为父作用域的this,不是调用时的this.
前四种都是调用时确定,也就是动态的,而箭头函数的this指向是静态的,声明的时候就确定了下来;
1.全局下this
//全局下的this指向window
console.log(this);
// var a=100;
// window.a=100;
//this.a=100;
2.函数作用域下this
var name='李四'
function fn(){
var name='张三';
console.log(this.name)
}
fn();
3.构造函数下的this
function C(){
this.a = 37;
}
var o = new C();
console.log(o.a); // logs 37
function C2(){
this.a = 37;
return {a:38};
}
var b = new C2();
console.log(b.a); // logs 38
4.call & apply
function add(c, d){
return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
function tt() {
console.log(this);
}
tt.call(5); // Number {[[PrimitiveValue]]: 5}
tt.call('asd'); // String {0: "a", 1: "s", 2: "d", length: 3, [[PrimitiveValue]]: "asd"}
5.bind 方法 通过bind方法绑定后, 函数将被永远绑定在其第一个参数对象上, 而无论其在什么情况下被调用。
function f(){
return this.a;
}
var g = f.bind({a:"azerty"});
console.log(g()); // azerty
var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, azerty
6.箭头函数下的this
由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值,
- 所以 call() / apply() / bind() 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响。
- 考虑到 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。(可以忽略是否在严格模式下的影响)
因为箭头函数可以捕获其所在上下文的this值 所以
let obj={
a:222,
fn:function(){
setTimeout(()=>{console.log(this.a)});
}
};
obj.fn();//222
Ⅱ.call()、apply()、bind()的区别============================
共同点:都是改变this指向的。
不同点:1.call()、apply() vs bind()
call()和apply()都会改变this的指向,会让函数立即执行。
bind()是只修改this的指向,需加( )才能执行。
2.call() vs apply()
① 共同点:将this指向第一个参数。
② 不同点:在于第二个参数,call第二个参数是一个一个的数据;appy第二个参数是数组。
③应用场景:伪数组借用数组的方法(NodeList/arguments)
function fn(){
console.log(arguments);
//要往arguments集合中追加一个数100
Array.prototype.push.call(arguments,100)
}
fn(3,4,5,6);