其实,this的取值,分四种情况。我们来挨个看一下。
在此再强调一遍一个非常重要的知识点:在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。
情况1:构造函数
所谓构造函数就是用来new对象的函数。其实严格来说,所有的函数都可以new一个对象,但是有些函数的定义是为了new一个对象,而有些函数则不是。另外注意,构造函数的函数名第一个字母大写(规则约定)。例如:Object、Array、Function等。
JavaScript代码
- function Foo(){
- this.name="刘新修";
- this.year=1986;
- console.log(this); //Foo {name: "刘新修", year: 1986}
- }
- var f1=new Foo();
- console.log(f1.name); //刘新修
- console.log(f1.year); //1986
注意,以上仅限new Foo()的情况,即Foo函数作为构造函数的情况。如果直接调用Foo函数,而不是new Foo(),情况就大不一样了, 那就是普通函数调用了:
JavaScript代码
- function Foo(){
- this.name="刘新修";
- this.year=1986;
- console.log(this); //Window {top: Window, location: Location, document: document, window: Window, external: Object…}
- }
- Foo();
这种情况下this就是window,个人总结:this就是就近原则,谁近就是谁,不然就是window,另外有关于闭包的两个demo同时也便于大家理解this 代码如下:
****************************************************************************************************************
代码片段一:
JavaScript代码
- var name="The Window";
- var object={
- name:"My Object",
- getNameFunc:function(){
- return function(){
- return this.name;
- };
- }
- };
- alert(object.getNameFunc()()); //返回The Window
代码片段二:
JavaScript代码
- var name="The Window";
- var object={
- name:"My Object",
- getNameFunc:function(){
- var that=this;
- return function(){
- return that.name;
- };
- }
- };
- //alert(object.getNameFunc()()); //返回My Object 注:因为var that=this; 声明的为私有变量
- console.log((object.getNameFunc()())); //返回My Object 注:因为var that=this; 声明的为私有变量
**********************************************************************************************************************
情况2:函数作为对象的一个属性
如果函数作为对象的一个属性时,并且作为对象的一个属性被调用时,函数中的this指向该对象。
JavaScript代码
- var obj={
- x:10,
- fn:function(){
- console.log(this); //object {fu:function,x:10}
- console.log(this.x); //10
- }
- };
- obj.fn();
以上代码中,fn不仅作为一个对象的一个属性,而且的确是作为对象的一个属性被调用。结果this就是obj对象。
注意,如果fn函数不作为obj的一个属性被调用,会是什么结果呢?
JavaScript代码
- var obj={
- x:10,
- fn:function(){
- console.log(this); //Window {top: Window, location: Location, document: document, window: Window, external: Object…}
- console.log(this.x); //如果this是window那this.x 自然就是 undefined
- }
- };
- var fn1=obj.fn;
- fn1();
情况3:函数用call或者apply调用
当一个函数被call和apply调用时,this的值就取传入的对象的值。至于call和apply如何使用,不会的朋友可以去查查其他资料,本系列教程不做讲解。
JavaScript代码
- var obj={
- x:10
- };
- var fn=function(){
- console.log(this); //Object {x: 10}
- console.log(this.x); //10
- };
- fn.call(obj);
情况4:全局 & 调用普通函数
在全局环境下,this永远是window,这个应该没有非议。
JavaScript代码
- console.log(this===window); //true
普通函数在调用时,其中的this全部都指向window 如下:
JavaScript代码
- var x=10;
- var fn=function(){
- console.log(this); //window
- console.log(this.x); //10
- };
- fn();
以上代码很好理解,如果函数里套子函数this仍然指向window 如下:
JavaScript代码
- var x=10;
- var obj={
- x:10,
- fn:function(){
- function f(){
- console.log(this); //window
- console.log(this.x); //10
- };
- f();
- }
- };
- obj.fn();
除非用局部变量 var that=this; 重新定义this 这时候的that 变量只能在函数内部调用,如下:
JavaScript代码
- var name="The Window";
- var object={
- name:"My Object",
- getNameFunc:function(){
- var that=this;
- console.log(that); //Object {name: "My Object"}
- console.log(this.name); //My Object
- }
- };
- object.getNameFunc();