你不知道的JavaScript-函数中的this

当我们在一个函数中写this的时候,我们是希望做什么?或者说,我们首先把函数中的this当成了什么?

this指向某个对象,那函数中的this指向谁?指向函数本身吗?

这里我们要分两种情况来看

函数有两种形态,一种是函数对象,一种是指向一段代码块

function a() {
// console.log(this.cc);
this.cc=1;
}

 var cc=3;
 a()//3
console.log(a.cc);//undifined


可以看到,当函数作为一个对象的时候,里面的this其实是并不会为这个函数增加一个属性,因此,我们不能断言,this指向函数本身。

this既不是指向对象函数本身也不指向函数的词法作用域。
this是在运行时进行绑定的,并不是在编写的时候绑定的,他的上下文取决于函数的调用时的各种条件,this的绑定跟函数声明的位置没有任何的关系,只取决于函数的调用方法。
当一个函数被调用的时候,会创建一个活动记录(有的时候也称为执行上下文),这个记录会包含函数在那里被调用(调用栈)函数的调用方法,传入的参数等信息。this就是记录的其中一个属性。

我们通过寻找函数调用的位置来判断函数在执行的过程中会如何绑定this

(摘自你不知道的JavaScript 上卷)

那么怎么判断this指向哪里呢?

如果要判断一个运行中的函数的this绑定,就需要找到这个函数的直接调用位置。找到以后根据一下的规则来进行判断。
1、由new调用?绑定到新创建的对象上
2、显示(call,apply,bind)绑定到指定的对象
3、有上下文调用?绑定到那个上下文对象
4、默认,在严格模式下绑定到undefined,否则绑定到全局对象
有些调用可能在无意中使用了默认的绑定规则,call(null),如果想更加安全的忽略this绑定可以使用一个DMZ对象比如 kong=Object.creat(null),call(kong)
箭头函数没有this,他的this继承自外层最接近自己的一个非箭头函数的this




this的绑定规则
我们前面就说了看函数的绑定要分两种情况,一种是函数作为一个对象与函数作为一个函数
function a[
    this.a=1
}
a.a是没有定义的

var aa=new a()
a.a//1
这个时候是函数生成并返回了一个对象,这个对象的成员根据里面的this来生成


而函数如果里面使用了this,那么在函数调用的时候(非 new) 执行我们this的绑定规则所决定的绑定。


函数的调用栈


a();//指向全局
function a(){
b()//指向a
}
function b(){
c()//指向b
}
function c(){

}


这个就是调用栈,也就是说,函数在执行的时候,this默认是执行上下文中的this的
这个地方,其实所有的this都执行window,但是如果我们进行了改变
a();//指向全局
function a(){
var obj={}
b.call(obj)//指向obj
}
function b(){
c()//指向b
}
function c(){


}


这个时候就是a指向window,b,c指向obj了

默认绑定
就是当当前上下文是window的时候,注意使用 call(null) 也是指向window


隐式绑定
也是根据上下文来绑定
即,函数的this指向最接近自己的作用域函数的this


显示绑定
通过call bind apply来进行绑定,强制改变this指向


new
此时函数通过new返回一个对象
这个时候函数中的this指向这个返回的对象
当使用一个new来调用函数的时候
    1、创建一个全新的对象
    2、这个新对象会指向 原型 连接
    3、这个新对象会绑定到函数调用的this
    4、如果函数没有其他的返回对象,那么new表达式中的函数会自动返回这个新对象


或者我们可以进行一下总结,当你函数里面使用了this的时候,此时,函数应该作为一个构造函数来使用,也就是必须使用new

不然我也不知道为什么要使用this了


猜你喜欢

转载自blog.csdn.net/aboyl/article/details/79522711