看了《征服Ajax - Web20开发技术详解试读版》第六章 发现写得很好,总结如下,很多是原书中的也增加了自己理解的部分
1.创建数组快捷方式
例子:
<script language="JavaScript" type="text/javascript">
<!--
var arr1 = new Array(1,2);//方式一
var arr2 = [1,2];//方式二
alert(arr1);
alert(arr2);
-->
</script>
以上两种创建数组的效果相同
2.使用方括号([])引用对象的属性和方法
语法:
方式一:对象名.属性(方法)名
方式二:对象名["属性(方法)名"]
区别:方式二可以有特殊字符
例子:
<script language="JavaScript" type="text/javascript">
<!--
Array arr=new Array();
//为数组添加一个元素
arr["push"]("abc");
//获得数组的长度
var len=arr["length"];//相当于arr.length
//输出数组的长度
alert(len);
-->
</script>
3.使用大括号({})语法创建无类型对象(注意:是对象不是类)
语法:
{
property1:statement,
property2:statement2,
…,
propertyN:statmentN
}
例子1:
<script language="JavaScript" type="text/javascript">
<!--
var obj = {
a:"11111",
print:function(){
alert(this.a);
}
};
obj.print();
-->
</script>
相当于
<script language="JavaScript" type="text/javascript">
<!--
function Class1(){
this.a = "1111";
this.print = function(){
alert(this.a);
};
}
var obj = new Class1();
obj.print();
-->
</script>
但上面的对象相关的类是匿名的
例子2:
<script language="JavaScript" type="text/javascript">
<!--
var objstyle = {
text-align:center,
background-color:#00CC00
}//是不是有点像css
-->
</script>
4.js对象成员的4种定义方式,搞清楚这点对写js的面向对象很有帮助
以下以定义方法为例,变量或对象类似
<script language="JavaScript" type="text/javascript">
<!--
function Class1(){
//该类实例的私有方法,不能被外部访问
method = function(){
alert("private instance method");
}
//该类实例的公共方法
this.method = function(){
alert("public instance method");
//调用私有方法
method();
}
}
//静态方法
Class1.method = function(){
alert("static method");
}
//原型方法
Class1.prototype.method = function(){
alert("prototype method");
}
var obj = new Class1();
obj.method();//调用公共方法,优先调用实例方法而不是prototype方法,当不存在实例方法时才会调用prototype方法
Class1.method();//调用静态方法,不能通过"对象.方法名"调用,只能用"类名.方法名"调用
Class1.prototype.method();//调用原型方法
-->
</script>
原型的作用:prototype和设计模式里的原型一样,使原型对象或方法预先创建一份,需要时复制使用,如还不明白去看设计模式
js中原型处理方式,prototype属于一个类的子对象,声明类时原型就存在且只有一份,当创建对象时,会先把prototype的所有成员都复制一份给对象,所以类的所有实例化对象都能获得原型的成员,当有同名成员时会优先调用实例对象的成员
5.arguments函数的参数集合,但并不是Array对象
例子1:传递给函数的隐含参数
<script language="JavaScript" type="text/javascript">
<!--
function func(a,b){
alert(a);
alert(b);
for(var i=0;i<arguments.length;i++){
alert(arguments[i]);
}
}
func(1,2,3);//输出1 2 3
-->
</script>
例子2:arguments.callee表示调用函数本身
<script language="JavaScript" type="text/javascript">
<!--
var sum=function(n){
if(1==n)return 1;
else return n+arguments.callee(n-1);//这里arguments.callee相当于sum
}
alert(sum(100));
-->
</script>
6.函数的 apply、call 方法和 length 属性
语法:
Function.prototype.apply(thisArg,argArray);//@1为对象 @2为参数数组(数组可以容纳更多的参数)
Function.prototype.call(thisArg[,arg1[,arg2…]]);//@1为对象 @2为参数可多个...
说明:让prototype方法可以临时访问thisArg对象的成员,改变了this指针(指向thisArg对象),相当于java的内部类,c++的友员
例子:
<script language="JavaScript" type="text/javascript">
<!--
//定义一个函数 func1,具有属性 p 和方法 A
function func1(){
this.p="func1-";
this.A=function(arg){
alert(this.p+arg);
}
}
//定义一个函数 func2,具有属性 p 和方法 B
function func2(){
this.p="func2-";
this.B=function(arg){
alert(this.p+arg);
}
}
var obj1=new func1();
var obj2=new func2();
obj1.A.apply(obj2,["byA"]); //显示 func2-byA,其中[“byA”]是仅有一个元素的数组,下同
obj2.B.apply(obj1,["byB"]); //显示 func1-byB
obj1.A.call(obj2,"byA"); //显示 func2-byA
obj2.B.call(obj1,"byB"); //显示 func1-byB
//alert("last " + obj1.B("byB"));//临时指定B方法并不会加到obj1中去,取消此注释会报错,因为obj1中没有B方法
function sum(a,b){
return a+b;
}
alert(sum.length);//输出sum定义时的参数个数而不管实际传入多少个参数
-->
</script>
7.在 JavaScript 中利用 for(…in…)语句实现反射
语法:
for(var p in obj){
//语句
}
例子:
<script language="JavaScript" type="text/javascript">
<!--
setStyle({ color:#ffffff,backgroundColor:#ff0000,borderWidth:2px});
function setStyle(_style){
//得到要改变样式的界面对象
var element=getElement();//getElement返回一个html对象
//用反射可以只更新_style对象里有的属性,而没有的仍然保持element.style里的原值
for(var p in _style){
element.style[p]=_style[p];
}
}
-->
</script>
8.类的继承
方式一:利用共享 prototype 实现继承
<script language="JavaScript" type="text/javascript">
<!--
function classParent(){
}
classParent.prototype.method1 = function(){
alert("classParent_method1");
}
classParent.prototype.method2 = function(){
alert("classParent_method2");
}
function classChild(){
}
classChild.prototype = classParent.prototype;
classChild.prototype.methodNew = function(){
alert("classChild_methodNew");
}
classChild.prototype.method2 = function(){
alert("classChild_method2");
}
var obj = new classChild();
obj.method1();//输出classParent_method1
obj.method2();//输出classChild_method2
obj.methodNew();//输出classChild_methodNew
var objParent = new classParent();
objParent.method2();//输出classChild_method2,父类的方法也被子类覆盖了
-->
</script>
此方式会覆盖父类的方法,所以不太适用
方式二:利用反射机制和 prototype 实现继承
<script language="JavaScript" type="text/javascript">
<!--
//为类添加静态方法 inherit 表示继承于某类
Function.prototype.inherit = function(baseClass){
for(var p in baseClass.prototype){
this.prototype[p]=baseClass.prototype[p];
}
}
function classParent(){
}
classParent.prototype = {
method1:function(){
alert("classParent_method1");
},
method2:function(){
alert("classParent_method2");
}
}
function classChild(){
}
classChild.inherit(classParent);
classChild.prototype.methodNew=function(){
alert("classChild_methodNew");
};
classChild.prototype.method2=function(){
alert("classChild_method2");
};
var obj = new classChild();
obj.method1();//输出classParent_method1
obj.method2();//输出classChild_method2
obj.methodNew();//输出classChild_methodNew
var objParent = new classParent();
objParent.method2();//输出classParent_method2,父类方法没有被覆盖
-->
</script>
9.在JavaScript实现接口或抽象类
<script language="JavaScript" type="text/javascript">
<!--
Function.prototype.inherit = function(baseClass){
for(var p in baseClass.prototype){
this.prototype[p]=baseClass.prototype[p];
}
}
function Class1(){
}
Class1.prototype = {
method:undefined//接口
};
function class2(){}
class2.inherit(Class1);
class2.prototype.method = function(){alert("has been implimented");};//实现接口
var obj = new class2();
obj.method();//不实现接口的话这句会报错
-->
</script>
10.js实现构造函数,同时也是实现接口的另一种方式
<script language="JavaScript" type="text/javascript">
<!--
//Class是一个全局对象,有一个方法create,用于返回一个类
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
var class1=Class.create();
class1.prototype={
initialize:function(userName){
alert("hello,"+userName);
}
}
var obj = new class1("dd");//initialize方法会被调用
-->
</script>
11.事件
1)单个事件
<script language="JavaScript" type="text/javascript">
<!--
function Class1(){
this.text = "";
}
Class1.prototype = {
setText:function(text){
this.text = text;
this.OnTextChange(this.text);
},
OnTextChange:function(text){
}//默认事件处理
}
var obj = new Class1();
obj.setText("text init");//无任何输出
//alert(obj.text);
obj.OnTextChange = function(text){//添加事件处理
alert(text);
}
obj.setText("Text Chanaged");//输出"Text Chanaged"
-->
</script>
2)把全局变量传给事件
<script language="JavaScript" type="text/javascript">
<!--
function Class1(){
this.text = "";
}
Class1.prototype = {
setText:function(text){
this.text = text;
this.OnTextChange(this.text);
},
OnTextChange:function(text){
}//默认事件处理
}
//创建function函数
function createFunction(obj,strFunc){
var args=[];
if(!obj)obj=window;
for(var i=2;i<arguments.length;i++)
args.push(arguments[i]);
return function(){
obj[strFunc].apply(obj,args);
}
}
var obj = new Class1();
function OnTextChangeHandle(text){//全局事件
alert(text);
}
var globalparams = "global params";
obj.OnTextChange = createFunction(null,"OnTextChangeHandle",globalparams);//绑定全局事件和参数
obj.setText("Text Chanaged");//输出"global params"
-->
</script>
3)注册多个事件
<script language="JavaScript" type="text/javascript">
<!--
function Class1(){
this.text = "";
}
Class1.prototype = {
OnTextChange:[],//事件数组
setText:function(text){
this.text = text;
//通知调用OnTextChange事件
for(var i = 0;i < this.OnTextChange.length;i++){
this.OnTextChange[i](this.text);
}
},
addOnTextChangeListener:function(_event){//添加注册事件方法
//检查该事件是否已添加防止重复添加
for(var i = 0;i < this.OnTextChange.length;i++){
if(_event == this.OnTextChange[i]){
return;
}
}
this.OnTextChange.push(_event);
},
removeOnTextChangeListener:function(_event){//移除注册事件方法
var arr = [];
for(var i = 0;i < this.OnTextChange.length;i++){
if(_event != this.OnTextChange[i]){
arr.push(this.OnTextChange[i]);
}
}
this.OnTextChange = arr;
}
}
var obj = new Class1();
function MyOnTextChange1(text){
alert("MyOnTextChange1:"+text);
}
function MyOnTextChange2(text){
alert("MyOnTextChange2:"+text);
}
obj.addOnTextChangeListener(MyOnTextChange1);
obj.addOnTextChangeListener(MyOnTextChange1);//不会重复添加
obj.addOnTextChangeListener(MyOnTextChange2);
obj.setText("Text Chanaged 1");
obj.removeOnTextChangeListener(MyOnTextChange2);
obj.setText("Text Chanaged 2");
-->
</script>
12.js实现命名空间(此例同时展示了js中类的定义和调用)
<script language="JavaScript" type="text/javascript">
<!--
//声明
var com = new Object();//只能new一遍
if(com.briup == undefined){//防止重复定义
com.briup = new Object();
}
com.briup.Class1 = function(){
this.a = 10;
};
com.briup.Class1.prototype = {
print:function(){
alert(this.a);
}
};
if(com.briup == undefined){
com.briup = new Object();
}
if(com.briup.hrtc == undefined){
com.briup.hrtc = new Object();
}
com.briup.hrtc.Class2 = function(){
this.b = 20;
};
com.briup.hrtc.Class2.prototype = {
print:function(){
alert(this.b);
}
};
//调用
var obj1 = new com.briup.Class1();
obj1.print();
var obj2 = new com.briup.hrtc.Class2();
obj2.print();
-->
</script>
准备看第七章,看完再写,希望能与大家共同学习。