关于function中的this指向问题

关于function中的this指向老觉得很迷惑。


document.body.onclick = function(){
    console.log(this); // 这个this指向body
    function click_inner(){
       console.log(this); // 这个this指向了window
    }
    click_inner();
}

从上面的代码可以推测出:每个function中都有一个this。

我原先的理解为:click_inner 内没有this,但是其上层函数中有this,所以根据JS的作用域和作用域链的知识可知(内部没有的变量就上溯到上层环境查找,找到就返回),内部的this就是外部函数的变量对象中的this。

按照我原先的理解:那么click_inner内操作的this也应该指向body,但是结果显然说明我原先理解错了。。。

按照结果来说,click_inner内的this也是指向window的,但是为什么window.click_inner()就报错呢?好像又推翻了上面的推测。。

请大神详细的解答一下关于this的知识。。感激不尽!!

阅读 6.6k
7 个回答

javascript 的this主要是看如何调用这个函数,而不是这个函数所在的作用域。obj.fn() fn中的 this 就是 obj。 fn() this是undifine, 而在js进入函数之前,会有 if(!this) { this = window} 这样的操作。因此,后面那个this是window

总结一下,this 一共有六种不同的值:

  1. 普通函数调用,this为全局对象或是undefined

  2. 作为对象的方法,this为那个对象

  3. new 表达式,this为以该函数为原型的新创建的对象

  4. 使用 apply/call指定 this

  5. 用bind绑定固定的this

  6. 事件处理函数中的this是当前的触发事件的DOM元素(event.currentTarget)

详情见: http://zonxin.github.io/post/2015/11/javascript-this

你这个问题比较复杂,实际中很少出现

1,this跟代码中的位置没关系,是在执行的时候赋值的
2,你是点击body,触发了body的onclick事件,onclick是body对象的方法,所以它的this是body
3,你在onclick函数内部声明了一个click_inner函数,这时候这个函数的作用域是全局作用域也就是window,执行它也是在全局作用域里执行,因为你不是this.click_inner = function ... 执行的时候也不是this.click_inner(),没指定this,this就跑到全局了
4,为什么直接window.click_inner 里你直接跑没有,因为click_inner是在onclick里声明的啊,你没执行onclick的时候window里是没有click_inner的

js的this比较诡异,谁执行就指向谁,很明显,click_inner没人调用,是window执行的。。。所以的就指向window

你在定义body的onclick时,可以理解成定义body对象的一个方法,此时引用的this就是body对象,而click_inner则并不是定义成body的方法的,所以直接引用this。

另外,正如你所说的,如果当前域找不到变量,程序会向上查找,但这并不代表方法本身也能向上依靠。click_inner只是向上查找到this为window,但并不表示window向下就可以查到click_inner这个方法,所以你直接调用window.click_inner()并不一定是正确的。

1) this是不会沿着变量作用域、原型链或闭包结构向上查找的
2) this只存在于函数调用期间,在变量作用域中不存在

函数中this的指向有以下几种:
1)当函数作为一个对象的方法调用时,this指向这个对象
2)当函数作为普通函数调用时,this指向全局对象window(浏览器环境下)或global(nodejs环境下)
3)当函数作为构造函数并通过new操作符时,this指向新创建的对象
4)可以通过Function的apply和call方法强制调整this的指向

document.body.onclick = function(){
    console.log(this); // 这个this指向body
    function click_inner(){
       console.log(this); // 这个this指向了window
    }
    click_inner();
}

onClick回调函数作为document.body的一个方法调用,所以其this指向body
click_inner为回调函数中定义的的一个内部函数,其作用域在onclick的回调函数内
click_inner();作为普通函数调用,其运行期的this指向window
window.click_inner()报错是因为click_inner函数在window对象下不存在...

var outer = new Object();
outer.func = function() {
    console.log(this);        //outer
    function inner() {
        console.log(this);    //window
    }
    inner();
}
outer.func();

func()是作为outer对象的方法调用的,它的this就是outer。—— 函数作为谁的方法被调用,其this就是该方法

inner()作为函数被调用,它的this就是window。只不过inner如果在函数内部声明,只有在函数内部才能访问到inner。把函数名函数功能分割开来 —— 函数功能的执行环境即this的值是全局,函数名只能在函数内部被访问到

参考:JavaScript this 讲解

推荐问题
宣传栏