如何理解 javascript保留关键字 中的 this 关键字

JavaScript中的this关键字使用详解
作者:libuchao
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了JavaScript中的this关键字使用,是JavaScript入门学习中的基础知识,需要的朋友可以参考下
&和其它许多面向对象的语言一样,JavaScript 中也有 this 关键字,this 在函数中用来指向调用此方法的对象。实际编程中要判断 this 到底指向谁,一般可遵循以下原则:
&&& 如果该函数被 Function.call 或者 Function.apply 调用,那么 this 指向 call/apply 的第一个参数,如果参数是 null 或者 undefined,this 则指向全局对象(在浏览器中的话,全局对象就是 window 对象)。
&&& 如果该函数被 Function.bind 调用,那么 this 将指向 bind 的第一个参数(方法被创建时)。
&&& 如果该函数被一个对象作为方法调用,那么 this 指向这个对象。
&&& 如果该函数只是光溜溜的作为函数被调用,不附属于任何对象,那么 this 指向全局变量 window。
首先,让我们看看”函数”:
function introduce() {
alert("Hello, I am Laruence\r\n");
对于,这个函数, this关键字指向谁呢?
定义在全局的函数, 函数的所有者就是当前页面, 也就是window对象.
这也就是为什么, 我把函数用引号引起来. 因为定义在全局的函数, 其实也就是window对象的一个方法.
所以,我们即可用通过函数名直接调用, 也可用通过window.方法名来调用, 这个时候, 方法中的this关键字指向它的所有者:window对象.
如果, 我们查看window的introduce属性, 就会得到:
var name = "I am Laruence";
function introduce() {
alert(this.name);
alert(window.introduce);
* function introduce() {
* alert(this.name);
看了上面的代码, 也许你就会想到既然, 全局函数是window对象的方法, 全局变量是window对象的属性(Javasript作用域中已有述及), 那么,在全局函数中就可用通过this关键字来访问全局变量吧?
答案是肯定的, 如果调用introduce函数, 你就会认识我是Laruence.
事件处理函数
也许, 对于this关键字的迷惑, 绝大部分原因是来自把函数(方法)用在事件处理的时候.
&input id="name" type="text" name="name" value="Laruence" /&
比如, 我们现在需要在点击”name”输入框的时候, 显示出name输入框的value. 那么, 可用写下如下代码:
function showValue() {
alert(this.value);
document.getElementById('name').onclick = showV
上面的代码, 运行正常, 但是why? 不是说函数的this指针永远指向函数所有者么? 不是说全局变量的所有者是window对象么?
呵呵, 如果你能想到这个问题, 那说明你在认真的看我的文章, 否则,,我建议你从头看起, 否则看完了,你还是迷糊~
恩, 对, 对于上面的代码, showValue是定义在了全局对象, 那么看来问题只能发生在onclick事件绑定的时候了.
我们知道, 在Js中一切都是对象, 函数和方法也都是对象的属性, 只不过函数有可执行的内部属性. 所以, 对于上面的代码, 在对onclick绑定处理器的时候, 其实是对id为name的输入框Dom对象的onclick属性赋值.
也就是说, 我们把函数showValue Copy 给了name输入框对象的onclick属性. 如果我们查看此时的onclick:
function showValue() {
alert(this.value);
document.getElementById('name').onclick = showV
alert(document.getElementById('name').onclick);
* function showValue() {
* alert(this.value);
所以, 当事件触发的时候, 就会去调用name输入框的onclick方法, 这个时候,this关键字自然就指向的是name输入框了.
但是, 迷惑的事情就来了, 比如下面这种写法:
function showValue() {
alert(this.value);
&input id="name" type="text" name="name" value="Laruence" onclick="showValue()"/&
就无法正常运行, 这又是为什么呢?
恩, 因为这个时候, 并不是赋值, 而是引用.
如果我们注意俩种onclick的写法, 你会发现, 对于之前的方法, 我们使用的是:
dom.onclick = //没有调用符
而对于刚才的方法:
onclick = "showvalue()" //有调用符
这个也能侧面的反映出俩者的区别:对于前者,是赋值, 而对于后者是引用. 如果我们这个时候查看输入框的onclick属性,我们得到:
alert(dom.onclick);
* function onclick() {
showValue();
看到区别了么? 也就懂得为什么了吧?
讲到这里, 有一个很有趣的例子 ,大家可以在IE下试试:
&img src="xxx" onerror="alert(1);} function hi() { alert(2); " /&
改变this的指向
那, 既然我们已经知道为什么了, 那怎么才能让this指向我们想要指的地方呢?
对于上面的事件处理函数来说, 我们可以有如下几种写法:
dom.onclick = showValue();
dom.onclick = function() { alert(this.value) ;}
&input onclick="alert(this.value);" /& //想想刚才我们的引用,是如何把这句嵌入的.
dom.addEventListener(dom, showValue, false); //ff only
而对于不是事件处理函数的场合, 我们可以使用apply, 或者call, 来改变this关键字的指向.
var laruence = {
name : 'laruence',
position : 'Senior PHP Engineer',
company : 'Baidu.inc'
function introduce() {
alert(this.name);
introduce.call(laruence);
函数被 Function.call 调用的例子:
var myObject = {
sayHello : function() {
console.log('Hi! My name is ' + this.myName);
myName : 'Rebecca'
var secondObject = {
myName : 'Colin'
myObject.sayHello();
// logs 'Hi! My name is Rebecca'
myObject.sayHello.call(secondObject); // logs 'Hi! My name is Colin'
函数被 Function.call 调用过的例子:
var myName = 'the global object',
sayHello = function () {
console.log('Hi! My name is ' + this.myName);
myObject = {
myName : 'Rebecca'
var myObjectHello = sayHello.bind(myObject);
sayHello();
// logs 'Hi! My name is the global object'
myObjectHello(); // logs 'Hi! My name is Rebecca'
函数被对象调用的例子:
var myName = 'the global object',
sayHello = function() {
console.log('Hi! My name is ' + this.myName);
myObject = {
myName : 'Rebecca'
secondObject = {
myName : 'Colin'
myObject.sayHello = sayH
secondObject.sayHello = sayH
sayHello();
// logs 'Hi! My name is the global object'
myObject.sayHello();
// logs 'Hi! My name is Rebecca'
secondObject.sayHello(); // logs 'Hi! My name is Colin'
在调用一个很深的命名空间中函数的时候,我们通常会缓存一个变量指向那个要调用的函数,以减少代码量。但是这样做会改变函数中 this 的值,最终执行错误的操作。例如:
var myNamespace = {
myObject : {
sayHello : function() {
console.log('Hi! My name is ' + this.myName);
myName : 'Rebecca'
var hello = myNamespace.myObject.sayH
hello(); // logs 'Hi! My name is undefined'
所以,要缓存变量以节省代码量的话,正确的做法是只节省到调用那个函数的对象为止:
var myNamespace = {
myObject : {
sayHello : function() {
console.log('Hi! My name is ' + this.myName);
myName : 'Rebecca'
var obj = myNamespace.myO
obj.sayHello(); // logs 'Hi! My name is Rebecca'
总之,有一个大原则:谁调用了那个函数,this 就指向谁。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具在JavaScript中this变量是一个令人难以摸清的关键字,this可谓是非常强大,充分了解this的相关知识有助于我们在编写面向对象的JavaScript程序时能够游刃有余。
1. 一般用处
对于this变量最要的是能够理清this所引用的对象到底是哪一个,也许很多资料上都有自己的解释,但有些概念讲的偏繁杂。而我的理解是:首先分析this所在的函数是当做哪个对象的方法调用的,则该对象就是this所引用的对象。
var obj = {};
obj.x = 100;
obj.y = function() { alert( this.x ); };
//弹出 100
这段代码非常容易理解,当执行 obj.y() 时,函数是作为对象obj的方法调用的,因此函数体内的this指向的是obj对象,所以会弹出100。
var checkThis = function() {
alert( this.x);
var x = 'this is a property of window';
var obj = {};
obj.x = 100;
obj.y = function(){ alert( this.x ); };
var obj2 = obj.y;
//弹出 100
checkThis();
//弹出 'this is a property of window
//弹出 'this is a property of window
这里为什么会弹出 'this is a property of window',可能有些让人迷惑。在JavaScript的变量作用域里有一条规则&全局变量都是window对象的属性&。当执行 checkThis() 时相当于 window.checkThis(),因此,此时checkThis函数体内的this关键字的指向变成了window对象,而又因为window对象又一个x属性( 'this is a property of window'),所以会弹出 'this is a property of window'。
上面的两个示例都是比较容易理解的,因为只要判断出当前函数是作为哪个对象的方法调用(被哪个对象调用)的,就可以很容易的判断出当前this变量的指向。
2. this.x 与 apply()、call()
通过call和apply可以重新定义函数的执行环境,即this的指向,这对于一些应用当中是十分常用的。
示例三:call()
function changeStyle( type , value ){
this.style[ type ] =
var one = document.getElementById( 'one' );
changeStyle.call( one , 'fontSize' , '100px' );
changeStyle('fontSize' , '300px');
//出现错误,因为此时changeStyle中this引用的是window对象,而window并无style属性。
注意changeStyle.call() 中有三个参数,第一个参数用于指定该函数将被哪个对象所调用。这里指定了one,也就意味着,changeStyle函数将被one调用,因此函数体内this指向是one对象。而第二个和第三个参数对应的是changeStyle函数里的type和value两个形参。最总我们看到的效果是Dom元素one的字体变成了20px。
示例四:apply()
function changeStyle( type , value ){
this.style[ type ] =
var one = document.getElementById( 'one' );
changeStyle.apply( one , ['fontSize' , '100px' ]);
changeStyle('fontSize' , '300px');
//出现错误,原因同示例三
apply的用法和call大致相同,只有一点区别,apply只接受两个参数,第一个参数和call相同,第二个参数必须是一个数组,数组中的元素对应的就是函数的形参。
3. 无意义(诡异)的this用处
var obj = {
y : function(){
setTimeout(
function(){ alert(this.x); }
//这里的this指向的是window对象,并不是我们期待的obj,所以会弹出undefined
如何达到预期的效果
var obj = {
y : function(){
var that =
setTimeout(
function(){ alert(that.x); }
4. 事件监听函数中的this
var one = document.getElementById( 'one' );
one.onclick = function(){
alert( this.innerHTML );
//this指向的是one元素,这点十分简单..
以上可以归纳为:
调用形式this指向
全局对象window
对象的方法
新构造的对象
阅读(...) 评论()下次自动登录
现在的位置:
& 综合 & 正文
JavaScript中this关键字使用方法详解
在面向对象中,对于this关键字我们是非常熟悉的。比如C++、C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要 理解了,用起来是非常方便和意义确定的。JavaScript也提供了这个this关键字,不过用起来就比经典OO语言中要"混乱"的多了。
下面就来看看,在JavaScript中各种this的使用方法有什么混乱之处?
1、在HTML元素事件属性中inline方式使用this关键字:
&div onclick=" // 可以在里面使用this "&division element&/div&
我们一般比较常用的方法是在此使用:javascirpt: EventHandler(this),这样的形式。不过这里其实可以写任何合法的JavaScript语句,要是高兴在此定义个类也可以(不过将会是个 内部类)。这里的原理是脚本引擎生成了一个div实例对象的匿名成员方法,而onclick指向这个方法。
2、用DOM方式在事件处理函数中使用this关键字:
&div id="elmtDiv"&division element&/div& &script language="javascript"& var div = document.getElementById('elmtDiv'); div.attachEvent('onclick', EventHandler); function EventHandler() {
// 在此使用this } &/script&
这时的EventHandler()方法中的this关键字,指示的对象是IE的window对象。这是因为 EventHandler只是一个普通的函数,对于attachEvent后,脚本引擎对它的调用和div对象本身没有任何的关系。同时你可以再看看 EventHandler的caller属性,它是等于null的。如果我们要在这个方法中获得div对象引用,应该使用: this.event.srcElement。
3、用DHTML方式在事件处理函数中使用this关键字:
&div id="elmtDiv"&division element&/div& &script language="javascript"& var div = document.getElementById('elmtDiv'); div.onclick = function() {
// 在此使用this }; &/script&
这里的this关键字指示的内容是div元素对象实例,在脚本中使用DHTML方式直接为div.onclick赋值一个 EventHandler的方法,等于为div对象实例添加一个成员方法。这种方式和第一种方法的区别是,第一种方法是使用HTML方式,而这里是 DHTML方式,后者脚本解析引擎不会再生成匿名方法。
4、类定义中使用this关键字:
function JSClass()
var myName = 'jsclass';
this.m_Name = 'JSClass';
JSClass.prototype.ToString = function()
alert(myName + ', ' + this.m_Name);
var jc = new JSClass();
jc.ToString();
这是JavaScript模拟类定义中对this的使用,这个和其它的OO语言中的情况非常的相识。但是这里要求成员属性和方法必须使用this关键字来引用,运行上面的会被告知myName未定义。
5、为脚本引擎内部对象添加中的this关键字:
Function.prototype.GetName = function()
var fnName = this.toString();
fnName = fnName.substr(0, fnName.indexOf('('));
fnName = fnName.replace(/^function/, '');
return fnName.replace(/(^/s+)|(/s+$)/g, '');
function foo(){}
alert(foo.GetName());
这里的this指代的是被添加原形的类的实例,和4中类定义有些相似,没有什么太特别的地方。
6、结合2&4,说一个比较迷惑的this关键字使用:
function JSClass()
this.m_Text = 'division element';
this.m_Element = document.createElement('DIV');
this.m_Element.innerHTML = this.m_T
this.m_Element.attachEvent('onclick', this.ToString);
JSClass.prototype.Render = function()
document.body.appendChild(this.m_Element);
JSClass.prototype.ToString = function()
alert(this.m_Text);
var jc = new JSClass();
jc.Render();
jc.ToString();
我就说说结果,页面运行后会显示:"division element",确定后点击文字"division element",将会显示:"undefined"。
7、CSS的expression表达式中使用this关键字:
&table width="100" height="100"&
&div style="width: expression(this.parentElement.width);
height: expression(this.parentElement.height);"&
division element&/div&
这里的this看作和1中的一样就可以了,它也是指代div元素对象实例本身。
8、函数中的内部函数中使用this关键字:
function OuterFoo()
this.Name = 'Outer Name';
function InnerFoo()
&&&&推荐文章:
【上篇】【下篇】

我要回帖

更多关于 javascript new关键字 的文章

 

随机推荐