首先来看两个例子
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对象。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。