函数的this指向谁,和函数在哪里被定义的,函数在哪里被执行的没有半毛钱关系,只遵守下面的规律:
在非严格模式中:
1、自执行函数里面,this永远指向window;
<script>
var a = 1;
var o = {
a: 2,
fn: (function(){ //自执行函数,在定义的时候就已经执行啦
console.log('自执行函数里面是window',this.a); //自执行函数里面的this指向的是window
return function() { // 但是这里的this 指向的是谁调用的这个函数
console.log('但是还是要具体问题具体分析',this.a)
}
})()
}
o.fn();
</script>
结果请看

2、给元素的某一个行为绑定方法,当行为触发所调用的函数里面this指向的该dom 元素;
<script>
var dd = document.getElementById('dd');
function f1 () {
console.log(this);
}
dd.onclick=f1; // 点击的那个dom对象
</script>
但是我要是稍微改一下:
<script>
var dd=document.getElementById('dd');
function fn () {
console.log(this);
}
dd.onclick=function(){
console.log(this); // dom 对象
fn(); // window ,这时候就看该函数是被谁调用的啦
}
</script>
3、看看函数执行有咩有 . ,如果有则是前面的那个,如果没有则是window
4、在构造函数里面,this 指向的是当前的实例;
<script>
function fn() {
console.log(this);
};
function ff () {
this.name="杜俊成";
this.say=function(){
console.log(this); // this指向该构造函数的原型
fn() // window ,因为fn 函数的直接调用者是window,
}
}
var a = new ff();
a.say();
</script>
5、使用call / apply 改变了this 的指向;(关于call 和 apply 想一劳永逸的搞明白吗?请看我的一篇文章)
严格模式:
1、自执行函数里面,this永远指向undefined;
<script>
var obj ={
fn:(function(){
// this => undefined
console.log(this)
return function(){
// this=> obk
console.log(this);
}
})()
}
obj.fn; //obj.fn 的方法在声明的时候就已经被执行了, window
obj.fn(); //obj.fn的自执行方法返回的方法执行 obj
</script>
2、看前面有咩有 . ,如果有则是前面的那个,如果没有则是undefined
总结就是:严格模式和非严格模式的区别:当调用主体不明时,严格模式是undefined,非严格模式是window
<script>
'use strict';
function fn(){
alert(this);
}
/*非严格模式*/
fn.call()//this - window;
fn.call(null)//this - window;
fn.call(undefined);//this -undefined
/*严格模式下,给call或apply第一个参数传谁this就是谁,不传就是undefined*/
fn.call() //this - undefined;
fn.call(null) //this -null;
fn.call(undefined) //this-undefined
</script>
es6 新增的箭头函数比较特殊。我们使用function定义的函数,在定义时,它并不知道这个this会指向哪里,只有在运行的时候才能明确this的值。
箭头函数本身不具有this,它会直接绑定到它的词法作用域内的this,也就是定义它时的作用域内的this值。所以试图使用apply,call等方法修改箭头函数的this是不会成功的,因为箭头函数自身没有this。所以我们来看下面一段代码:
var func = () => { console.log(this); } func(); // Window func.apply({}); // Window
function func() { console.log(this) return () => {console.log(this)} }; func()() // Window // Window func.apply({a:1})() // Object {a:1} // Object {a:1} func.apply({a:2})() // Object {a:2} // Object {a:2}
通过这段代码,我们应该可以明确的看出来,箭头函数是直接使用的它词法作用域内的this,也就是定义它时的作用域内的this。当我们修改它的作用域内的this值,也就是func的this值时,在箭头函数内也可以反映出来。用作对比,我们看下使用function定义的函数:
function func() { console.log(this) return function(){ console.log(this) } }; func()() //window window func.apply({a:1})() // {a:1} window func.apply({a:2})() // {a:2} window
github地址:https://github.com/dujuncheng