2

首先来看两个例子

var user='lilei'
function fn(){
    console.log(user);
    console.log(this.user);
}
fn();
console.log(this.user);

输出结果

lilei
lilei
lilei

这个很好解释,user定义的是全局变量,fn调用的时候,相当于是window.fn(),而this就是指向调用它的对象,也就是window,所以第二个console输入的是lilei.而在最外层,this.user这里面的this其实是指向window的,所以也就相当于window.user,输出lilei。

node中输出

lilei
undefined
undefined

再看个例子

function fn(){
    var user='lilei'
    console.log(user);
    console.log(this.user);
}
fn();
console.log(this.user);

输出结果

lilei
undefined
undefined

这里面牵涉到局部变量和全局变量相同时,局部变量会覆盖全局变量。所以第一个自然是lilei。此时函数内部的this调用指向window,而在全局变量中并未定义user,所以报undefined。而第三个和第二个是一样的。

有一点需要明确的是,this在创建函数的内部是不知道到底指向谁,只有在调用的时候,方能决定!
var user='lihua'
function fn(){
    console.log(user);
    var user='lilei';
    console.log(this.user);
    this.user=123;
}
fn();
console.log(this.user);

输出结果

undefined
lihua
123

第一个之所以打印undefined,是因为代码处理分两个阶段,第一阶段是变量,函数声明,以及正常格式的参数创建,这是一个解析和进入上下文的阶段。第二个阶段是代码执行,函数表达式和不合格的标识符(为声明的变量)被创建。所以fn就相当于

function fn(){
    var user;
    console.log(user);
    user='lilei';
    console.log(this.user);
    this.user=123;
}

打印undefined是自然而然的事情。第二个打印lihua,没什么解释的。第三个是因为修改了this.user,所以会打印123。

也就是说,this指向的是最后调用他的对象。不过可以通过call,apply,bind来改变this的指向。

那么对于构造函数是如何指向的呢?

function Fn(){
    this.user = "lilei";
}
var a = new Fn();
console.log(a.user); //lilei

我们发现这个this指向a,之所以指向a是因为new操作符,改变了this的指向。
那么对于有返回值构造函数,this如何指定呢?

function Fn(){
    this.user = "lilei";
    return 1;
}
var a = new Fn();
console.log(a.user); //lilei

function Fn(){
    this.user = "lilei";
    return {user:'lihua'};
}
var a = new Fn();
console.log(a.user); //lihua

从上面,我们可以看出

return的是Object 这种情况下,不再返回this对象,而是返回return语句的返回值。a.user的时候那么调用的{user:lihua}的值。

这种情况我们可以这样理解

function Fn(){
    this.user = "lilei";
    return 1;
}
var a = new Fn();
等价于
function Fn(){}
var a = new Object();
a.__proto__ = Fn.prototype;
Fn.call(a)

function Fn(){
    this.user = "lilei";
    return {user:'lihua'};
}
var a = new Fn();

等价于

function Fn(){}
var a = new Object();
a.__proto__ =  {user:'lihua'}.prototype;
{user:'lihua'}.call(a)
如果return的是五种简单数据类型:String,Number,Boolean,Null,Undefined。这种情况下,忽视return值,依然返回this对象。

儿独
729 声望25 粉丝