this代表的是当前行为执行的主体,它实际上在函数被调用时发生的绑定,他指向什么完全取决于函数在哪被绑定
一。关于this
- 函数执行时首先看函数名前面是否有".",有的话,"."前面是谁,this就是谁;没有的话this就是window
function fun() {
console.log('this',this)
}
obj = {fun}
fun(); // this -> window
obj.fun() // this -> obj
function fun2() {
fun()
}
fun2() // this -> window
var test = {
fun2: function () {
console.log('this',this)
fun() // this -> window
}
}
test.fun2() // this -> test
- 自执行函数中this指向window
(function fun() {
console.log('this',this) // window
})()
- 构造函数中,this指向该构造函数的实例
function CreateJsPerson(name,age){
this.name=name;
this.age=age;
this.writeJs=function(){
console.log(this.name);
};
}
var p1=new CreateJsPerson("Bob",48);
p1.writeJs() //Bob this -> p1
- call、apply、bind中的this
// call
var obj={name:"zhang"};
function fn(num1,num2){
console.log(num1,num2,this);
}
fn.call(100,200);//this->100
fn.call(obj,100,200);//this->obj
fn.call();//this->window
fn.call(this);//this->window
fn.call(null);//this->window
fn.call(undefined);//this->window
apply方法和call方法类似,不同之处在于call在传值地时候,是一个一个穿的,而apply传递地是一个参数数组。
- bind
fn.call(obj,1,2);//->改变this,并且执行fn函数
fn.bind(obj,1,2);//->只是改变了fn中的this为obj,并且给fn传递了两个参数值1、2,
但是此时并没有把fn这个函数执行
var test=fn.bind(obj,1,2);
test(); //这样才把fn这个函数执行
call、apply和bind一个显著区别:call、apply会在改变this的时候同时执行该函数,而bind不会执行该函数,只是将参数传递了过去
5. 箭头函数中的this
箭头函数中的this指向定义时所在的对象
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
箭头函数的this绑定定义时所在的作用域(即Timer函数),普通函数的this指向运行时所在的作用域(即全局对象)。所以,3100 毫秒之后,timer.s1被更新了 3 次,而timer.s2一次都没更新。
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log( this.i, this)
},
d() {
console.log( this.i, this)
}
}
obj.b(); // undefined window
obj.c(); // 10 obj
obj.d(); // 10 obj
在执行obj.b()时,this是指向定义时所在的对象,即this其实访问的是父级作用域的this,obj此时在全局环境中,所以this指向window。
严格模式下,this默认指向undefined