学习JavaScript的时候对this总是一知半解的,通过看http://web.jobbole.com/85198/ 这篇文章,算是搞懂了this,结合这篇文章,并且总结一下自己的理解,如下,如果有不正确,请指出告诉我,谢谢你。
没有占到自习教室位置的苦逼少女,在一楼教室学习,对面教室的老师在好大声的放视频,莫名其妙听到毛爷爷当年说的新中国成立......然后靠着几首超静心的轻音乐含泪写完,鼓掌!
好了不说废话了,先说this的几点规则,如果不理解,后面有例子。
this:
1.如果一个函数中有this,且被上一级的对象所调用(执行),则this指向上一级对象。
2.如果一个函数中有this,但并没有被上一级对象所调用,则this指向window,在严格模式下指向undefined。
3.如果一个函数中有this,并被多重对象包围,且被最外一层对象所调用,this指向的还是上一级对象。
4.this永远指向的是最后调用的对象,即执行的时候调用它的对象。(所以要正确区分是否执行)
5.构造函数中的this,new关键字会改变this的指向,使它指向当前new出来的新对象。
6.当构造函数有return时,1)如果返回的是一个基本值,则this仍指向的是new出来的对象;2)如果返回值是一个对象,则this指向的是返回的对象;3)如果返回的是null,虽然null是一个对象,但仍作为基本值处理,this仍指向new出来的对象。
例子:有点乱,等我静下心来再整理一下
// 一个全局变量
var a = "the window";
this:
1.如果一个函数中有this,且被上一级的对象所调用(执行),则this指向上一级对象。
2.如果一个函数中有this,但并没有被上一级对象所调用,则this指向window,在严格模式下指向undefined。
3.如果一个函数中有this,并被多重对象包围,且被最外一层对象所调用,this指向的还是上一级对象。
4.this永远指向的是最后调用的对象,即执行的时候调用它的对象。(所以要正确区分是否执行)
5.构造函数中的this,new关键字会改变this的指向,使它指向当前new出来的新对象。
6.当构造函数有return时,1)如果返回的是一个基本值,则this仍指向的是new出来的对象;2)如果返回值是一个对象,则this指向的是返回的对象;3)如果返回的是null,虽然null是一个对象,但仍作为基本值处理,this仍指向new出来的对象。
var
a =
"the window";
// 普通函数
function
test1() {
var
a =
"function";
console.
log(
"test1 " +
this.
a);
console.
log(
"test1 " +
this);
}
test1(); // the window [object Window]
此时是在全局环境下调用的,所以this指向全局对象。
// 单层对象
var
test2 = {
a:
"object",
fun:
function () {
console.
log(
"test2 " +
this.
a);
},
}
test2.fun(); // object
// 调用fun的时候立刻执行了,this指向所执行的环境,即test2。
var b = test2.fun;
b(); // the window
//调用fun的时候并没有立刻执行,只是将这个函数的地址赋值给变量b,而执行的时候是在全局环境中执行的。
// 多层对象
// 情况一:
var
test = {
a:
"object",
fun:
function () {
console.
log(
this.
a);
}
}
test.
fun(); // object
windows.test.fun(); // object
这也相当于是多层对象,window.test.fun,此时fun中的this指的是上一级对象,即test。
// 情况二:
var
test3 = {
a:
"object",
b: {
a:
"inner object",
fun:
function () {
console.
log(
"test3 " +
this.
a);
}
},
}
test3.b.fun(); // inner object
this在调用的时候被上一级对象调用,所以指向上一次对象,即b。
// 情况三:
var
test4 = {
a:
"object",
b: {
// a: "inner object",
fun:
function () {
console.
log(
"test4 " +
this.
a);
}
},
}
test4.b.fun(); // undefined
同test3,但是test4.b对象中并没有a变量,所以返回undefined,再次证明当函数被多层对象调用时,函数内的this指向的是它上一次的对象。
其实,函数的两个特殊变量this和arguments都只会在当前执行环境的变量对象中讯中,并不会在再上一层中寻找。
// 构造函数
function
test5() {
this.
a =
"constructor";
this.
fun =
function () {
console.
log(
"test5 " +
this.
a);
}
}
var
obj =
new
test5;
obj.fun(); // constructor
// new会改变this的指向,使它指向新new出来的对象,在这里是obj,
// new一个构造函数,相当于把构造函数中带有“this.”的变量和方法都复制给新对象,所以新new出来的obj中会有a变量和fun方法。
// 但如果构造函数是这样的:
// function test5() {
// a = "constructor";
// this.fun = function () {
// console.log("test5 " + this.a); // undefined
// }
// }
var c = obj.fun;
c(); // the window
在这里只是把fun的地址赋值给c,赋值的时候并没有立刻执行,而执行这个地址里的函数的时候其环境变量是全局环境。
理解1:
var
color =
'green';
var
test4399 = {
color:
"blue",
getColor:
function () {
var color = "red";
console.log(this.color);
console.log(color);
}
}
var getColor = test4399.getColor;
getColor(); // green red
test4399.getColor(); // blue
理解2:
var
name =
"The Window";
var
object = {
name :
"My Object",
getNameFunc :
function(){
console.
log(
'1.' +
this.
name);
return function(){
return this.
name;
};
}
};
var
func =
object.
getNameFunc();
// My Object
console.
log(
object.
getNameFunc()());
// 1.My Object The Window
console.
log(
'2.' +
func());
// 2.The Window
console.
log(
'3.' +
func.
call(
object));
// 3.My Object
console.
log(
'4.' +
func.
apply(
object));
// 4.My Object
最后来个小测验
var greeting = "outer greeting";
function createModule(str) {
return {
greeting: str,
sayIt: function () {
return greeting;
},
};
}
var obj = createModule("inner greeting");
console.log(obj.sayIt()); // outer greeting