一、this
this:上 下文,根据执行环境而发生指向的改变,只有函数执行的时候才能确定this到底指向谁。实际上this的最终指向的是那个调用它的对象。
例子1:在严格版中的默认的this不再是window,而是undefined。我们这里不讨论严格版的。
//在直接调用函数中获取this
function a(){
var user = "萌萌";
console.log(this.user);
console.log(this);
}
a();//undefined Window
window.a();//undefined Window
//函数作为对象的一个属性中获取this
var b = {
user:"萌萌",
fn:function(){
console.log(this.user);
console.log(this);
}
}
b.fn();//萌萌 b
window.b.fn();//萌萌 b
//this依赖调用函数前的对象
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
更改一下我们常规的用法,看一下有什么不一样:
var o1 = {
a:10,
b:{
fn:function(){
console.log(this.a);
}
}
}
o1.b.fn();//undefined
//再次强调,this指向函数执行前的对象
var o2 = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o2.b.fn;
j();
二、构造函数版的this:
function Fn(){
this.user = "萌萌";
}
var a = new Fn();
console.log(a.user); //萌萌
构造函数new的优先级是最高的,this只会绑定到a上,不会被任何方式修改this的指向。顺便提一下,构造函数的函数名第一个字母大写。
new关键字会创建一个空的对象,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。
还有就是利用call、apply、bind改变this ,这个优先级仅次于new
三、当this遇到return
function fn1()
{
this.user = '萌萌';
return {};
}
var a = new fn1;
console.log(a.user); //undefined
function fn2()
{
this.user = '萌萌';
return function(){};
}
var b = new fn2;
console.log(b.user); //undefined
function fn3()
{
this.user = '萌萌';
return 1;
}
var c = new fn3;
console.log(c.user); //萌萌
function fn4()
{
this.user = '萌萌';
return undefined;
}
var d = new fn4;
console.log(d.user); //萌萌
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
四、其他情况
- 定时器中的this,指向的是window
- 元素绑定事件,事件触发后执行的函数中的this,指向的当前元素
- 箭头函数其实是没有this的,这个函数中的this只取决于他外面的第一个不是箭头函数的函数的this
- this一旦绑定了上下文,就不会被任何代码改变。
五、腾讯笔试题
var x = 20;
var a = {
x: 15,
fn: function() {
var x = 30;
return function() {
return this.x
}
}
}
console.log(a.fn());//function(){return this.x}
console.log((a.fn())());//20
console.log(a.fn()());//20
console.log(a.fn()() == (a.fn())());//true
console.log(a.fn().call(this));//20
console.log(a.fn().call(a));//15
答案:
1、对象调用方法,返回一个方法
2、a.fn()返回的是一个函数,()()这是自执行表达式,匿名函数自调用,this指向window
3、a.fn()相当于在全局定义了一个函数,然后再自己调用执行。this -> window
4、由2和3的答案可以推出4为true
5、这段代码在全局环境中执行,this -> window