哪里调用this就指向哪里。this指向依赖于调用时的位置和调用方法,而非建立时的位置。
默认状况下,全局上下文环境的this指向于window对象。git
var a = 1; console.log(this.a); // 1 console.log(this == window); // true
值得注意的是,在ES6中let关键字声明定义的全局变量,不挂在顶层对象window中github
let a = 1; console.log(this.a); // undefined console.log(this == window); // true
在分析函数上下文以前,咱们先来了解下调用位置。JavaScript引擎在执行代码时按照顺序执行,则全局上下文(global text)应当首先进入调用栈。以后才是函数上下文进栈,当函数被调用时则进行出栈。数组
举个例子app
function foo(){ foo2(); } function foo2(){ foo3(); } function foo3(){ console.log("i am foo3"); } foo();
如上这段代码,最开始是全局上下文首先入栈,然后foo入栈,看到foo中还调用foo2则继续进栈,同理入栈foo3。根据栈后进先出的原则,则foo3首先被弹出栈,然后foo二、foo依次出栈。该函数上下文所在栈元素的前一个元素,则为调用位置。而实际上,须要结合调用方式来断定。函数
var a = 1; function foo(){ var a = 2; foo2(); } function foo2(){ var a = 3; console.log(this.a); // 1 foo3(); } function foo3(){ console.log(this.a); // 1 console.log("i am foo3"); } foo();
此处为函数独立调用,因此this实际指向于windowthis
在非严格模式下,普通函数的this指向于windowcode
var a = 1; function foo(){ console.log(this.a); }
而在严格模式下,普通函数的this是undefined对象
'use strict' var a = 1; function foo(){ console.log(this); // undefined console.log(this.a); // 报错 } foo();
嵌套函数调用事件
var a = 1; function foo(){ return function(){ var a = 2; console.log(this.a); } } foo()(); // 1 var f = foo(); f(); // 1
在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。若是调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。ip
var a = 1; function getA(){ return this.a; } var obj = { a:2, foo:getA } console.log(obj.foo()); // 2
若是函数独立调用,那么该函数内部的this,则指向undefined。可是在非严格模式中,当this指向undefined时,它会被自动指向全局对象。
var a = 1; function getA(){ return this.a; } var obj = { a:2, foo:getA }; var f = obj.foo; console.log(f()); // 1
须要注意的是,这仅是针对函数上下文而言。
var a = 1; function getA(){ return this.a; } var obj = { a:2, b:this.a, foo:function(){ return this.a; } }; console.log(obj.b); // 1 console.log(obj.foo()); // 2
使用call/apply调用时,this做用域指向call/apply的第一个参数对象。call/apply自己差异不大,主要差异就是call传递的形参是一个一个的,而apply是一整个数组传。
var song = 'hello'; function sing(){ console.log(this.song); } var obj = { song:'let it go' }; sing.call(obj); // let it go
this指向被建立的对象
var age = 13; function Animal(age){ this.age = age; } var dog = new Animal(12); console.log(dog.age); //12
this指向于触发事件的DOM元素
var ele = document.getElementById("id"); ele.addEventListener("click",function(e){ console.log(this); console.log(this === e.target); // true })
箭头函数调用应当是this指向在函数调用里面的特例了,在箭头函数中,会捕获其所在上下文的this值,做为本身的this值。简单来讲,就是包裹箭头函数的第一个普通函数中的this。
function foo() { setTimeout(()=>{ console.log(this.a); },100) } var obj = { a: 2 } foo.call(obj); // 2
肯定This指向时,首先找到函数调用位置及调用方式
new
调用:绑定到新建立的对象call
或apply
、bind
调用:绑定到指定的对象参考文章: https://github.com/axuebin/ar...