总结下关于常见的this指向的问题。首先,this对象只会是在一个函数中才需要确定,如果在全局作用域下,this永远指向global对象,在浏览器环境下是window对象,在javascript中,函数调用一般有这四种情况:

1、Function Invocation Pattern

函数调用模式,即直接调用定义的函数,如fn(),是函数最直接的使用方式,在这里fn是作为单独的变量出现,而非属性。在这种模式下,fn函数中的this永远指向全局对象,也就是global或者window。

2、Method Invocation Pattern

方法调用模式,此时函数做为一个对象的属性出现,如fn.handle(),主要的特征就是有“.”或者“[]”符号,在这种模式下,handle函数中的this永远指向的是“.”或者“[]”符号前的对象,在上面小例也就是fn。

3、Constructor Pattern

构造模式,在构造函数实例化的时候出现,如new Fn(),其中的new关键字很明显,在种模式下Fn函数内部的this永远指向new Fn()返回的对象,即Fn的实例。

4、Apply Pattern

适应模式,这种模式下,可以使用js提供的call()apply()方法来改变this的指向,如fn.call(Object)fn.call(Object),在这种模式下,fn函数内部的this指向call和apply函数的第一个参数,但是在Object为null或者undefined时,this指向变为global。

ES6中箭头函数的this

在ES6中的箭头函数,(x, y) => x * x + y * y,省略了function、{}return语句,有种匿名函数的感觉,箭头函数内部的this词法作用域,有上下文决定。所谓词法作用域,简单的理解就是函数定义的时候this的作用域就已经固定了,是什么就是什么,不会随着运行调用的改变而改变,也就是有些地方所说的静态作用域,不多说来个小例子:

以前javascript对this的绑定:

1
2
3
4
5
6
7
8
9
10
11
var obj = {
name: "nn",
fun: function(){
var m = this.name; //obj.fun() 指向obj
var say = function(){
return this.name;
};
return say(); //直接调用指向全局
}
};
console.log(obj.fun()); // undefined

箭头函数固定了this指向:

1
2
3
4
5
6
7
8
9
var obj2 = {
num: 3,
total: function(){
var m = this.num;
var count = ()=> this.num; //词法作用域 指向外层域obj2
return count(); //直接调用此时已不管用
}
};
console.log(obj2.total()); //3

看到这里是不是感觉有点懵逼,其实我也一样懵逼,所以下面再贴一段代码,让我们来加深下对词法作用域和箭头函数固定this作用域的理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj3 = {
a: 2333,
b: {
m: 3444,
n: function(){
var w = this.a;
var x = this.m;
var y = ()=>this.m; //词法作用域 指向外层域b 3444
var z = ()=>this.a; //词法作用域 指向外层域b undefined
return [y(),z()];
}
}
};
console.log(obj3.b.n());

其实就是在obj3对象里面又嵌套一个对象,层层嵌套,那啥(想到了那啥烧饼广告0.0),这样更加清晰的理解什么是词法作用域,什么是指向外层域。好了,鄙人才疏学浅,如有不足之处,还望不吝赐教。