JavaScript中this关键字的理解

this关键字是javascript理解中的老大难,尤其作为一个新手,常常会被它弄糊涂,搞不清楚this到底指向“谁”。本文将分析this的各种应用场景。

1.在HTML元素事件属性中i使用this关键字

这种用法是最为常见的方式(javascirpt: EventHandler(this)),在这种情况下,this在哪个元素中,它表示的是就是那个对象。举例说明:
<html>
    <head>
        <title>函数</title>
    </head>
    <body>
        <img src="xsd.jpg" οnclick="JavaScript:alert(this.src);">
        <form name="ttt">
            <input type="text" name="ddd" value="ddaaa" οnclick="checkit(this)">
        </form>
    </body>
    <Script language="JavaScript">
        function checkit(obj){
            if (obj.value == "") {
                alert("空值");
            }
            else {
                alert(obj.value);
            }
        }
    </Script>
</html>

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.value

3.用DHTML方式在事件处理函数中使用this关键字

	<script language="javascript">
		var div = document.getElementById('elmtDiv');
		div.onclick = function() {
			// 在此使用this
		};
	</script>
这里的this关键字指示的内容是div元素对象实例,在脚本中使用DHTML方式直接为div.onclick赋值一个EventHandler的方法,等于为div对象实例添加一个成员方法。这种方式和第一种方法的区别是,第一种方法是使用HTML方式,而这里是DHTML方式,后者脚本解析引擎不会再生成匿名方法。

4、类定义中使用this关键字

在 ECMAScript 中,要掌握的最重要的概念之一是关键字 this 的用法,它用在对象的方法中。关键字 this 总是指向调用该方法的对象。
<pre name="code" class="javascript"><span style="font-family: Arial, Helvetica, sans-serif;">	<script type="text/javascript"></span>
		function Car(sColor, iDoors, iMpg) {
			this.color = sColor;
			this.doors = iDoors;
			this.mpg = iMpg;
			this.showColor = function() {
				alert(this.color);
			};
		}
		var oCar1 = new Car("red", 4, 23);
		var oCar2 = new Car("blue", 3, 25);
		oCar1.showColor();//red
		oCar2.showColor();//blue   alert(oCar1.showColor==oCar2.showColor)//false
	</script>
 
  
代码1 构造函数模式
在上面的代码中,关键字 this 用在对象的 showColor() 方法中。在此环境中,this 等于 oCar。如果不用对象或 this 关键字引用变量,ECMAScript 就会把color看作局部变量或全局变量。然后该函数将查找名为 color 的局部或全局变量,但是不会找到。结果如何呢?该函数将在警告中显示 "null"。
缺陷:每个实例对象的showColor方法一模一样,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率。
能不能让drivers属性和showColort()方法在内存中只生成一次,然后所有实例都指向那个内存地址呢?回答是可以的。
function Car() {
}

Car.prototype.color = "blue";
Car.prototype.doors = 4;
Car.prototype.mpg = 25;
Car.prototype.drivers = new Array("Mike","John");
Car.prototype.showColor = function() {
  alert(this.color);
};

var oCar1 = new Car();
var oCar2 = new Car();

oCar1.drivers.push("Bill");

alert(oCar1.drivers);	//输出 "Mike,John,Bill"
alert(oCar2.drivers);	//输出 "Mike,John,Bill" 
alert(oCar1.showColor==oCar2.showColor)//true
代码2  原型 Prototype模式
该方式利用了对象的 prototype 属性,可以把它看成创建新对象所依赖的原型。
原型方式的缺陷:这种方式下,对象间(oCar1、oCar2)共享属性指向的是对象(new Array   function)。

这个构造函数没有参数。使用原型方式,不能通过给构造函数传递参数来初始化属性的值,因为 Car1 和 Car2 的 color 属性都等于 "blue",doors 属性都等于 4,mpg 属性都等于 25。这意味着必须在对象创建后才能改变属性的默认值,这点很令人讨厌,但还没完。真正的问题出现在属性指向的是对象,而不是函数时。 函数共享不会造成问题,但对象却很少被多个实例共享

解决方法:
	<script type="text/javascript">
		function Car(sColor, iDoors, iMpg) {
			this.color = sColor;
			this.doors = iDoors;
			this.mpg = iMpg;
			this.drivers = new Array("Mike", "John");
		}

		Car.prototype.showColor = function() {
			alert(this.color);
		};

		var oCar1 = new Car("red", 4, 23);
		var oCar2 = new Car("blue", 3, 25);

		oCar1.drivers.push("Bill");

		alert(oCar1.drivers); //输出 "Mike,John,Bill"
		alert(oCar2.drivers); //输出 "Mike,John"
	</script>

5.2&4综合题

	<script language="javascript">
		function JSClass() {
			this.m_Text = 'division element';
			this.m_Element = document.createElement('DIV');
			this.m_Element.innerHTML = this.m_Text;
			//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();
	</script>
页面运行后会显示:"division element",确定后点击文字"division element",将会显示:"undefined"。

6.function中this的使用

	<script language="javascript">
		function OuterFoo() {
			this.Name = 'Outer Name';
			function InnerFoo() {
				var Name = 'Inner Name';
				alert(Name + ', ' + this.Name);
			}
			return InnerFoo;
		}
		OuterFoo()();
	</script>
根据第二点的理解,OuterFoo和InnerFoo都是一个普通的函数,所以函数中的this都是指向Window对象。那么输出应该为" Inner Name, undefined",但是结果却不是这样。输出见下图:
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值