在Javascript中,最玄妙的特性之一,就是this的指向玄幻莫测,一会儿指向这一会儿指向那,让初学者十分伤脑筋。
本文总结一下,方便初学者掌握奥妙之处,同时方便老鸟温故而知新。
首先,看一段代码:
var module = { x: 42, getX: function() { return this.x; } } console.log(module.getX());//42 var unboundGetX = module.getX; console.log(unboundGetX()); //undefined
一个输出42,一个输出undefined,这是为何呢??
var unboundGetX = module.getX;
相当于是
var unboundGetX = function(){ return this.x; }
这是不是就比较容易懂了?OK,引出结论:
函数体内的this指向调用该函数时所处的上下文环境(context)
没错,this的定义就是就这么简单。
那么该怎么找上下文环境呢?调用函数时,该函数名往左由“·”符号连起来的对象,就是上下文环境。
console.log(module.getX());
很明显,这句函数调用,是通过module对象调用的,那么上下文环境就是module,this指向module,module.x=42,所以输出42;
console.log(unboundGetX());
而上面这句,调用unboundGetX()时没有通过“·”指名是通过谁来调用的,那么就寻找当前作用域链上的上一级对象,那就是全局对象window,所以此时的上下文环境就是window,this指向window,而window.x未定义,当然返回undefined。
OK,讲到这里,最重要的内容基本上就讲完了。
放一段代码,大家利用我讲的知识,去思考为什么是这个运行结果?
var name = "window" function func() { console.log(this.name); } var TB = { name: "object", test(fn) { fn && fn(); return function() { return this.name; } } } console.log(TB.test(func)());
最后一些tips:
1)严格模式下,函数体内的this是undefined。
2)在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素。
3)apply、call、bind 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
4)在ES6中,当使用箭头函数(=>)时,this的指向总是指向定义它的上下文环境(context)。