this在JS中经常出现并使用,其中this所取的值是当函数被调用执行时才可以确定,定义时还无法确定。因为this取值关乎执行上下文环境,每次调用时可能都不一样,下面介绍this的几种取值情况:
构造函数:
当this出现在构造函数中时,它代表的就是即将创建出的这个对象。
function People() { this.name = "srk"; this.age = 100; console.log(this); //People{name : "srk", age : 100} } People.prototype.speak = function () { console.log("hello person"); }; var p1 = new People();
这里是如何知道People是一个构造函数的呢,就是由下面这个new People()决定的,换而言之,如果把这句换成People(),this的输出结果就会为Window对象。
function People() { this.name = "srk"; this.age = 100; console.log(this); //Window } People.prototype.speak = function () { console.log("hello person"); }; People();
函数作为属性被调用:
函数作为对象的属性被调用时,函数中的this所指为该对象。
var a = { x : 20, y : function () { console.log(this);//Object {x: 20, y: function} console.log(this.x);//20 } }; a.y();这里要注意的是,a.y()中的y()是作为a对象的属性进行调用的,所以this是a对象。
var a = { x : 20, y : function () { console.log(this);//Window console.log(this.x);//undefined } }; var b = a.y; b();这里对b的赋值直接是a对象的y属性,所以没有作为a的属性进行调用,得到的this便是Window对象,this.x自然也没法找到。
我觉得这里也是一个向上寻找上下文环境的过程,第一种情况:当方法作为属性调用时,this的上下文环境是a对象。但是当直接调用这个方法不通过a时,上下文环境就变成了全局,所以自然就是Window。
函数用call或者apply调用:
call与apply主要都是通过改变context上下文,来动态改变this的,例如:
var a = { x : 20, y : function () { console.log(this);//Window console.log(this.x);//undefined } }; var b = {x:40}; a.y.call(b); //40这时y的上下文环境就变成了b而不是a,此时输出的也是40。
在原型链的Prototype当中:
在原型链的prototype当中this指的是该对象的值,例子如下所示:
function People() { this.name = "srk"; this.age = 100; } People.prototype.speak = function () { console.log(this.name); //Tom }; function Student() {} Student.prototype = new People(); //实现继承 var p2 = new Student(); p2.name = "Tom"; p2.speak();p2是一个Student对象,它调用speak()方法,然后通过原型链到People的prototype中找,然后可以看出此时的this就是p2。
全局和调用普通函数
这个在之前的例子中都能够看出来,这里的this指向了Window。