浏览 2916 次
锁定老帖子 主题:二、JavaScript脚本总结
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-03-03
最后修改:2009-03-03
一、JS中对象与JAVA对象的区别 java语言是一种强类型语言,它对显示和隐式类型转换都是非常严格的。java对象中的方法是与它的对象绑定在一起,只能通过对象来调用方法。但是在javascript中,函数可以附加到对象上,使得它们的行为类似与方法,就是我可以通过一个函数完成一个对象应有的操作。使用它们可以在其上下文中调用,也就是说函数的事件源是什么?并且在运行时附加到其它对象上,通过javascript函数的调用,可以把这些函数附加到原来没有该操作的对象上。对于java来讲就没有这种优势。因为java中只要你定义一个类,除非这个类扩展了某个接口,它会拥有其他的功能,否则不可能在原类的基础上再添加一些方法,如果你非要添加的话,你还得重新编译这个类。所以这是javascript中一个优势所在。javascript的本质是什么?它的本质就是一个数组,数值的元素可以是一个值,也可以是开一个键值对。当然这里的数组元素就是键和值。这里的键就是函数的函数名或者是对象中的属性,值就是它的函数体或者是内容。javascript中的对象创建问题,记住一点在javascript中,函数是最高的统治者。我们创建的对象就是在创建函数。这个函数和一般的对象是有区别的。下面写一个简单的对象: <html> <head> <script type="text/javascript" > function myObject(name,age){ this.name = name; this.age = age; var myName="lukuijun" this.myFucntion(){ alert(myName); alert(this.name+ " " + this.age); alert(this["name"]+ " " + this["age"]); } } function show(){ var my=new myObject("lukuijun",20); my.myFunction(); var myObject=myFunction:function(){alert{"lukuijun"}}; myObject["name"]="lukuijun1"; myObject["age"]="200"; alert(myObject["name"]+""+myObject["age"]); alert("调用了函数:" + myObject["myFunction"]); myObject["myFunction"];//这一点要注意了 } </script> </head> <body> </body> </html>函数myObject写完,但是有一个问题,我们以往在写javascript函数的时候,传进去两个参数之后,函数体里面没有this关键字。现在这个this是指我们按照 this.name, this.age这样的this.方式来写,表示我们现在是在创建一个对象。在这个对象中有两个属性name和age。这两个属性就是针对java中类似的情况写的。所以javascript它是一中类java的语言或者说是类面向对象的语言。这里javascript里面的myObject函数可以理解为java中的构造函数。只是在javascript里面只需要写这么一个函数就可以了。接下来可以对它进行实例化,当然也可以增加一些函数如this.myFunction=function(){ alert(this.name+ " " + this.age);},这里声明了一个函数,它相当于类中的方法。创建的方式呢,this.后面也是相当于key,这个key也是相当于对函数的引用。function(){ alert(myName:"函数");}是对函数的声明以及函数体。如果你想应用这个javascript的对象的话,你要创建它,创建的方式呢,由于javascript是弱类型语言,你可以这样写var my=new myObject("lukuijun",20),这样就创建完成一个对象。接下来我们让页面加载的时候直接加载它<body onload=>,注意一点,调用javascript函数的时候一般是触发onload或者onclick事件,它仅仅是会调用一个方法。因此要声明一个方法,吧对象的创建放进去,然后调用对象的方法。function show(){var my=new myObject("lukuijun","20"); my.myFunction();}可以了。运行打印出 lukuijun 20。说明我们这个对象已经创建成功。这是第一种创建对象的方式,通过function创建。函数的创建方式决定了你是创建的普通函数还是一个对象。对于javascript引用对象中的属性,有两种形式:this.xxx和this["xxx"],印证了javascript的本质就是一个数组。this["xxx"],this数组,下标xxx就是属性如name,要以类似于字符串形式书写加""。运行打印出lukuijun 20 lukuijun 20。这点请大家注意不要忽略了。 创建对象的第二种方式,因为在javascript中可以把它理解为一个数组。 var myObject={name:null,age:null};创建了一个对象,如果想用就必须对name和age先赋值。myObject["name"]="lukuijun";myObject["age"]="20";当程序加载的时候,onload时间会触发它,alert(myObject["name"]+""+myObject["age"]);打印一下结果:lukuijun1 200 以上所讲的就是创建javascript对象的两种方式以及如何引用它们的属性。 怎样引用javascript对象中的方法?两种方式: 1、 声明对象,调用对象的函数。举例: var my=new myObject("lukuijun",20); my.myFunction(); 2、在声明对象的时候,以键值对的形式放在最后,键就是方法名,值就是这个函数,这个函数也可以传递参数。举例:在创建对象的第二种方式下,这样引用: var myObject=name:null,age:null,myFunction:function(){alert{"lukuijun"}}}; alert("调用了函数:" + myObject["myFunction"]); 印结果:lukuijun1 funciton(){alert("200 ")} lukuijun,注意必须加(),myObject["myFunction"]()表明调用的是它的函数。应该理解name:map{}方式。 注意,如果以第一中方式创建对象,函数有一个name、age还有一个方法myFunction, myFunction方法是在类似于构造方法为它定义的。这种方式有一个弊端,在内存中创建的这些函数存在内存泄漏问题。因为每创建一个myObject,都会重新创建出myFunction这个函数,而不是仅仅用它编译过去。就像在java中,这函数已经存在与内存中了,new一个东西仅仅是这个指针指向了这个函数。但是现在就不一样了,如果按照第一种方式来写,在创建这个name age属性和方法myFunction的时候,这个函数myFunction是要重新在内存分配一个空间,所以就会引起内存泄漏。了解到这一点创建对象越多就有可能引起内存泄漏。采用哪一种方式来声明?javascript中给我们提供了原型方式。原型方式的好处就是可以在已有的已存在的的对象当中往里面添加一些属性一些方法。不是在动态的创建一个,而是在原有的基础上增加。这样也就避免了所谓的内存泄漏。 二、闭包 在构造函数体的内部创建了一个临时变量,这个临时变量对于一个在构造体里的函数来讲,是可以调用的。但是创建在函数体的外部就不可以调用,所以它就形成了一种闭包。采用第一种方式,我在里面定义一个闭包var myName="lukuijun",现在把这个变量在myFunction里面打印出来alert(myName);结果为lukuijun.但是在外面通过原型来引用是不可以的。 三、原型 原型在某些程度上解决了内存泄漏问题, 格式:函数名.prototype.方法(函数) myObject.prototype.myFunction=function(){ alert(myName); alert(this.name+ " " + this.age); alert(this["name"]+ " " + this["age"]); }写在类构造体myObject外面,不能打印出myName,报错误是类型未定义。这说明myName是不可用的,它的作用范围超出了声明时候的作用范围。这就产生了闭包问题。 通过原型也就获得了一个对象的引用,通过这个引用来添加我们需要的内容。包括属性和方法等等。这个原型prototype是javascript中的属性,我们可以直接.prototype引用,或者通过[prototype]引用也是可以的:myObject["prototype"].myFunction=function()。利用原型在javascript中创建对象很方便。 四、扩展内建类 在javascript中会有一些内建类,最简单的就是一个数组,它是一个内建类,是javascript给我们设置好的可以直接用。扩展内建类提供了一些数组对象,但这些数组 对象中会有一些常用方法来使用。我们要扩展内建类,通过原型在里面扩展一些我们自己的方法。自己定义的方法接下来可以自己引用,给我们编程带来一定的方便。 我们需要的一些功能可以直接把它封装在一个函数中,把内建类扩展。可以扩展属性和方法,举例: Array.prototype.name="Array";在show()方法中new一个数组:var arr = Array();alert(arr);结果会打印Array。如果没有Array.prototype.name="Array";打印会 提示说没有定义,这就扩展了内建类。 扩展一个索引方法: Array.prototype.indexof=function(obj){ var result=-1; for(var i=0;i<this.length;i++) if(this[i]==obj){ result=i; break; } } } 在show()方法中调用 var arr = new Array("1","2","3"); alert(arr.indexOf("1"));打印结果0,表明1是存在的,所在数组下标是0。 五、函数不属于对象 验证下: <html> <head> <script type="text/javascript" > function personA(name,age){ this.name=name; this.age=age; } function personB(name,age){ this.name=name; this.age=age; } personA.prototype.shout=function(context){ alert(this.name+":"+context); } show(){ var a = new personA("张三","20"); var b = new personA("李四","20"); a.shot("该吃饭了"); //b.shot("该吃饭了"); } </script> </head> <body onload="show();"> <div id="a">张三</div> <div id="a">李四</div> <div id="context"></div> </body> </html> 打印结果:张三:该吃饭了。如果将 a.shot("该吃饭了");注释掉,添加 b.shot("该吃饭了");执行结果会报错:对象不支持该属性或者方法。javascript中有一个类似于java中的反射机制,可以通过一个函数的引用它直接去调用这个函数,而不是通过对象的方式去调用。下面的代码来调用: var b_function=a.shout;//没有()表示a的shout属性或者引用。 b_function.call(b,"该吃饭了")//call方法是javascript给我们提供的内建方法,它的第一个参数表示希望哪一个对象来给我们提供调用(这里b来给我们提供调用),第二个参数呢,是函数参数的内容("该饭了"),看看打印结果:李四:该吃饭了。因为personA通过原型的方式增加了 shout方法,但是personB没有,但是通过b_function.call(b,"该吃饭了")类似与java里的反射。注意b_function.call(b,"该吃饭了")。注意一点:personA和personB的参数相同,所以通过call(b,"该吃饭了")能调用b的方法。在java中如果自己这个对象没有这个方法而调用是不允许的,但是在javascript里面则可以。前提是只要有那么个方法存在,不管那个方法在哪个函数里,这点是javascript和java的区别。通过其他对象可以调用我这个对象中不存在的方法,所以函数不属于对象是成立的。没有函数属于哪个对象这么一说。 六、事件处理和函数上下文 看在div里面添加onclick时间,看看这个this是相对于什么来说的。 <div id="context" onclick="alert(this.id)">函数上下文</div> 结果,打印出context,所以这个this是相对于div这个元素来说的,代表这个div。如果将onclick="alert(this.id)"改为onclick="alert(this.context)",打印结果为 function anonymous(){ alert(this.onclick)},这是一个匿名的函数,这个匿名的函数中含有了 alert(this.onclick),也就是说这个<div id="context" onclick="alert(this.id)">函数上下文</div>调用是通过浏览器来调用的,因为这个是通过浏览器来执行的。浏览器调用,触发onclick事件,this相当于它的上下文 是这个div,这个元素的上下文。javascript中给我们提供了匿名的函数,这里函数体的内容就是alert(this.onclick)这句话。this对应这个函数的上下文,就是这个元素。 看另一种方式: 在show()函数里添加下面的代码: var my_div=document.getElementById("context"); var myobj=new obj("myid".my_div); 两外申明一个对象: function obj(id,div){ this.id=id; this.div=div; this.div.onclick=this.clickHandler; } obj.prototype.clickHandler=function(){ alert(this.id); } 在body的onload事件里调用show方法,打印结果为context,为什么? 采用对象的方式在里面增加了onclick事件,以为这个this是obj对象的,但是事实是这个this也是指向这个div,为什么?因为这个onclick时间最终是浏览器来调用,所以谁调用它,这个上下文this就是谁。函数不属于对象,它可以附属在任何对象中,这个就是javascript和java的区别,这个一定要注意。强调javascript中的this和java中面向对象的引用this是有区别的。实质上的东西是一样的,但是它的上下文是变的。最终的原因就是函数的上下文不同,函数不属于对象。那有什么方法去改变呢?对于弱类型的语言来讲,我创建一个对象,可以往它上面增加无数的信息,包括属性方法等可以动态的将器添加。通过这,可以把obj的引用给保留下来,在用的时候可以先把obj的引用取出来,然后通过id就可以显示出来。 在var myobj=new obj("myid".my_div);下面添加my_div.my_obj=myobj;这样就将myobj的引用保留了下来,保存到div的my_obj属性里了。所以采用this.my_obj.id就 可以获得obj的id。开发中最好不要用this的方式,很容易引起误会。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-03-03
最后修改:2009-03-03
非常好的一篇文章。虽然错别字 和 例子有点错误。
|
|
返回顶楼 | |
发表时间:2009-03-03
谢谢您的提醒,修订ing...
|
|
返回顶楼 | |