this指向问题可以说是百分之百的面试内容。不管大公司小公司,都会问。最近在整理js的基础知识,特意将这个问题单独出来整理。通过查阅一些资料和阮一峰老师对这个问题的解析,自己也深受体会。下面就谈一谈我个人对this指向的理解。
一、this的定义
this指的是函数运行时所在的环境。
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁
二、关于不同调用方式,不同的结果
var obj = {
foo: function () {},
};
var foo = obj.foo;
// 写法一
obj.foo();
// 写法二
foo();
上面代码中,虽然obj.foo和foo指向同一个函数,但是执行结果可能不一样。请看下面的例子。
var obj = {
foo: function () {
console.log(this.bar);
},
bar: 1,
};
var foo = obj.foo;
var bar = 2;
obj.foo(); // 1
foo(); // 2 等同于window.foo()
这种差异的原因是因为函数内部使用了this关键字。对obj.foo()来说,foo运行在obj环境,所以this指向obj;对于foo()来说,foo运行在全局环境,所以this指向全局环境window
例子1:
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
window.a();
例子2:
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();
这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o。
例子3:
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
window.o.fn();
window是js中的全局对象,我们创建的变量实际上是给window添加属性,所以这里可以用window点o对象。
例子4:
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
- 情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。
- 情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
- 情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,例子4可以证明,如果不相信,那么接下来我们继续看几个例子。
例子5:
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
三、构造函数this
function Person3() {
this.name = 'king'; //这个this指向什么?
}
var person3 = new Person3();
this指向这个实例
要创建构造函数新的实例,就必须用new操作符,以这种方式调用构造函数会经历以下4个步骤:
1.创建一个新的对象;
2.将构造函数的作用域赋给新对象(因此this就指向了这个新对象);
3.执行构造函数中的代码;
4.返回新对象。
//构造函数
function Person(name,sex) {
this.name = name;
this.sex = sex;
}
var per=new Person('king','male');
var obj = {};
obj.__proto__ = Person.prototype;
Person.call(obj,'king','male');
四、当this遇到return
function fn()
{
this.user = '追梦子';
return {};
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = '追梦子';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = '追梦子';
return 1;
}
var a = new fn;
console.log(a.user); //追梦子
function fn()
{
this.user = '追梦子';
return undefined;
}
var a = new fn;
console.log(a.user); //追梦子
从以上四个代码块可以看出:
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。