JS篇——javascript中的this

原创 2016年06月02日 14:55:00

  一直以来貌似都还没有更新js篇,本来是打算将css3和html5更新完之后再从头总结js,最后发现开始那些好像也没啥总结的,而且我这速度还不知道何时能把css3和html5总结完,所以就想到哪就更哪了,本来今天准备更新闭包,然后发现更新闭包之前,我最好先更新下js中的this关键字,所以这一篇更新js中的this关键字。

javascript中的this

在java中,this固定指向运行时的当前对象。但在javascript中,this的含义要多的多,它可以是全局对象、当前对象或者任意对象,完全取决于函数调用的方式。

this究竟指向哪里

一句话,javascript中的this指向的是执行时的当前对象,而不是声明时的当前对象。这句话什么意思,看下面例子。

var x=1;
var test= {  
      x: 2,  
      show : function(){  
          alert(this.x);  
      } 
 };  
 var obj = test.show;
 obj();//1

上面这个例子最后弹出的是全局变量1,虽然this是在test.show里面声明的,但是执行的时候的对象却不是test,所以this不是指向的test对象,这是为啥呢,后面再说。

Javascript一共有四种调用模式:对象方法调用模式、纯函数调用模式、构造器调用模式以及apply调用模式。调用模式不同,对应的隐藏参数this值也会不同。

对象方法调用模式

函数作为对象的属性时,称为方法。此时函数(即方法)中的this对应是该对象。

var x=1;
var test= {  
      x: 2,  
      show : function(){  
          alert(this.x);  
   } 
 };  
 test.show();//2
弹出2,此刻运行的是test对象的show属性,所以this指向test对象,所以当前对象是test对象。

然而,还有另外一种情况的方法调用,就是“this究竟指向哪里”中的例子。

var x=1;
var test= {  
      x: 2,  
      show : function(){  
          alert(this.x);  
      } 
 };  
 var obj = test.show;
 obj();//1
此时弹出的是1,此刻并不是调用了test这个对象的show属性,而是将test.show这个函数赋值给obj,又因为该函数是一个匿名函数,本身是没有对象的,所以show方法里的this就没有对象,没有对象就是window,window.x就是全局变量1。
谈到这里就顺便说一下setTimeout、setInterval和匿名函数中的“this”.

在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,浏览器中全局变量可以当成是window对象下的变量,例如:全局变量a,可以用window.a来引用。

var x=1;
 var test= {  
      x: 2,  
      show : function(){  
          alert(this.x);  
      },
      other:function(){
      	setTimeout(function(){
             alert(this.x);
      	}, 1000);
      }
    };  
test.other();//1
弹出1,这是因为setTimeout中的匿名函数运行时,匿名函数中的this指向window,所以window.x弹出1。setInterval与setTimeout类似。

怎样可以让上面例子弹出2呢?

var x=1;
var test= {  
      x: 2,  
      show : function(){  
          alert(this.x);  
      },
      other:function(){
      	var that = this;
      	setTimeout(function(){
             alert(that.x);
      	}, 1000);
      }
    };  
test.other();//2

弹出2,这是因为在setTimeout中的匿名函数运行前,this指定的当前对象是test(这时运行的test对象的other属性),现将test对象赋值给that,setTimeout中的匿名函数运行后,改变的是this指定的对象,与that无关,that仍指定test对象。

这里再说一下setTimeout(函数名,延迟),setTimeout(匿名函数,延迟),setTimeout(字符串,延迟)这三的区别。以下面例子为例:

var x=1;
var test= {  
      x: 2,  
      show : function(){  
          alert(this.x);  
      } 
 };
setTimeout(函数名,延迟)(比如setTimeout(test.show(),1000))

test.show()是函数运行,这种传递方式真正传进去的是test.show()函数的返回值。如果是setInterval(test.show(),1000)这种方式只会执行test.show()一次,因为test.show()已经执行了,和setTimeout、setInterval其实没有关系

setTimeout(匿名函数,延迟)(比如setTimeout(test.show,1000))

这个相当于一个延时执行,传入了一个匿名函数,此时this变量是全局变量window,但是注意,它是没有传入函数参数的,如果函数有参数的话,建议使用闭包或者使用setTimeout(字符串,延迟)

setTimeout(字符串,延迟)比如setTimeout("test.show()",1000))

这个也相当于一个延时执行,用字符串代码创建了一个新的函数,因此该函数没有明确的对象,所以this指向全局变量。

var x = 1;  
var obj ={  
    x : 2,  
    show : function(){  
        alert(this.x);  
    },  
    other : function(){
        var that = this;
        setTimeout("that.show();", 1000);
    }
}; 
 
obj.other();//报错
纯函数调用模式

这种很简单,此时this就代表全局对象,即window。

function show(){
	this.x = 2;
	alert(this.x);
}
show();//2
var x = 1;
function show(){
	alert(this.x);
}
show();//1
var x = 1;
function show(){
	this.x = 2;
}
show();
alert(this.x);//2
构造器调用模式
构造器,就是生成一个新对象,这时,这个this就指这个新对象。

var x=1;
function show(){
	x=2;
	alert(x);
	alert(this.x);
	var x;
	alert(this.x);
	alert(x);
}
show();
上面弹出的结果是2,1,1,2

这就是上面说的那种情况,纯函数调用模式,这里的this对象就是全局对象window.

var x=1;
function show(){
	x=2;
	alert(x);
	alert(this.x);
	var x;
	alert(this.x);
	alert(x);
}
var test = new show();
test();
上面弹出的是2,undefined,undefined,2

这里的this对象就是new新创建的对象,新创建的对象里面并没有定义this.a,所以this.a为undefined。

apply调用模式

apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象,因此,this指的就是这第一个参数。
call的用法和apply大致相同,只有一点区别,apply只接受两个参数,第一个参数和call相同,第二个参数必须是一个数组,数组中的元素对应的就是函数的形参。所以这里只主要讲一个apply。

var x=1;
function show(a){
	this.x = this.x+a;
	alert(this.x);
}
var obj = {
	x:0
};
show.apply();//NaN,apply()的参数为空时,默认调用全局对象,所以this.x为1,但此时show函数的参数中没有定义a,因此a为undefined,所以结果为NaN
show.apply(obj,[3]);//3,此时this对象为obj对象,所以this.x为0。0+3等于3。
show.call(obj,4);//7,此时this对象是obj对象,但因为上一步,所以现在obj中的x为3,3+4等于7





版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

JavaScript进阶设计模式系列——基础篇——this-call-apply

this在JavaScript的世界中,this是一个很让人挠头的概念,为什么呢?第一,它总是指向一个对象,使用起来可以简化代码。第二,它是基于函数的执行环境进行动态绑定的,而不是在函数被声明时的环境...

JavaScript-读 You Dont Know JS,this到底是什么

You Dont Know JS一系列书不错。这一系列博客是我读这本书以后总结的干货。这篇博客讲解为什么使用this,以及如何确定一次函数调用的this到底是哪个对象。

javascript面试题 之 js中this关键字的用法

随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。 下面分四种情况,详细讨论this的用法。 情况一:函数调用 这是函数的最通常用法,属...

javascript中的this---you don't know js学习笔记(一)

this是javascript中的关键字,this在运行的时候决定而不是在作者编写函数(author-time)的时候决定。 因此理解this的最好方式,是查看调用栈(call stack),找...

JavaScript笔记——this的取值

函数this对象在全局上下文与函数上下文中的取值 绝大多数情况下,函数的调用方式决定了this的取值;在JavaScript严格模式与非严格模式下this的取值也略有区别

JavaScript学习总结——this对象

在JavaScript中,this关键字是动态绑定的,或称为运行期绑定,这极大地增强的我们程序的灵活性,同时也给初学者带来了很多困惑。本文总结了this的几个使用场景和常见误区。 全局环境 ...

JavaScript难点——this的用法及指向问题

this是Javascript语言的一个关键字,它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,...

深入理解javascript原型和闭包(10)——this

接着上一节讲的话,应该轮到“执行上下文栈”了,但是这里不得不插入一节,把this说一下。因为this很重要,js的面试题如果不出几个与this有关的,那出题者都不合格。  其实,this的取值,分四种...

javascript学习笔记——this对象

this对象是在运行时基于函数的执行环境绑定的。 在全局函数中,this等于window;当函数别作为某个对象的方法调用时,this等于该对象。this的几个常用方法:1、全局性调用此时this对象...

深入理解javascript原型和闭包(10)——this

转载自:http://www.cnblogs.com/wangfupeng1988/p/3988422.html 接着上一节讲的话,应该轮到“执行上下文栈”了,但是这里不得不插入一节...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)