面向对象Javascript说的有些多余,因为Javascript这门语言就是完全的面向对象。也不可能以非面向对象的方法来使用(没有声明对象的全局范围,实际上是window对象下的操作);
与其它面向对象语言不同的是,Javascript中并不存在类的概念。Javascript对象本身可以用来创建新对象(任何函数都可以被实例化为一个对象)。而且,对象可以继承自其它对象(原型继承);
对象是Javascript的基本单元,Javascript中的一切都是对象;
示例:创建对象并为其添加属性
1 //创建默认对象 2 var obj=new Ojbect(); 3 //为对象添加属性 4 obj.val='value'; 5 obj.click=function(){ 6 alert('clicked'); 7 } 8 9 //另一种方式,与上一个obj一样 10 var obj={ 11 val:'value', 12 click:function(){ 13 alert('clicked'); 14 } 15 } 16 17 //创建一般对象 18 function Persion(name){ 19 this.name=name; 20 } 21 //创建Persion的对象 22 var psn=new Persion('FENG'); 23 alert(psn.name);//FENG 24 alert(psn.constructor);//Persion 25 //由于Persion为window对象的方法,所以可以直接调用 26 Persion('LIU'); 27 //因为当前上下文为window,以下等同于alert(window.name) 28 alert(name);//LIU 29 30 //创建一般对象的另一种方式:使用一个对象的constructor属性创建 31 var psnScn=new psn.constructor('LAN'); 32 laert(psnScn.name);//LAN
引用:
引用是指向对象实际位置的指针(实际的对象肯定不会是引用)。不像Perl语言中允许多层引用,Javascript引用会沿着引用连一直追溯到所引用对象本身,所以Javascript引用只能指向具体的对象;
示例:引用的简单示例
1 //引用的简单示例 2 function refTst () { 3 var obj=new Object(); 4 obj.ppt='a property value'; 5 //obj与objRef指向同一个对象 6 var objRef=obj; 7 alert(objRef.ppt);//'a property value' 8 objRef.ppt='another property value'; 9 alert(obj.ppt);//'another property value' 10 objRef.ppt+=' aaa'; 11 alert(obj.ppt);//'some thing else' 12 }
示例:引用自修改
1 //自修改对象 2 function selfModify () { 3 var ary=new Array('one','two','three'); 4 //aryRef和ary指向同一个对象 5 var aryRef=ary; 6 //自修改对象,ary和aryRef指向同一个对象 7 ary.push('four'); 8 alert('aryRef.length='+aryRef.length);//aryRef.length=4 9 }
示例:修改引用的对象
1 //修改对象的引用 2 function refModify () { 3 var ary=['one','two','three']; 4 //aryRef和ary指向同一个对象 5 var aryRef=ary; 6 //ary指向一个新的对象 7 ary=['new','array']; 8 alert('ary.length='+ary.length+' '+'aryRef.length='+aryRef.length);//ary.length=2 aryRef.length=3 9 }
示例:字符串连接
1 //字符串连接操作的结果是一个新的字符串对象,而非原字符串的修改 2 function strJoin () { 3 var str='test'; 4 //strRef和str指向同一个引用 5 var strRef=str; 6 //str指向一个新的字符串 7 str+='ing'; 8 alert('str='+str+' '+'strRef='+strRef);//str=testing strRef=test 9 }
this关键字:
Javascript代码总是有一个上下文对象(代码处在该对象内),this指向当前代码所处的对象。如:全局变量是window对象的属性,全局范围中的this所指向的对象就是window对象;
示例:this的使用
1 //this的使用 2 var obj={ 3 yes:function(){ 4 this.val=true; 5 }, 6 no:function(){ 7 this.val=false; 8 } 9 } 10 //obj中尚未定义val属性,所以obj.val为undefined 11 alert(obj.val);//undefuned 12 obj.yes(); 13 alert(obj.val);//true 14 //将obj的no()方法赋值给window.no() 15 window.no=obj.no; 16 //no()方法中的this指向window,而非obj 17 window.no(); 18 //因为上句执行的是window的no(),而非obj的no(),所以obj.val仍然是true 19 alert(obj.val);//true
示例:使用call()和apply()修改上下文环境
1 //使用call()修改上下文环境 2 function changeColor(color){ 3 //设置上下文对象的颜色 4 this.style.color=color; 5 } 6 7 //window上下文中调用该函数将失败,因为window对象不含style属性 8 changeColor('red'); 9 10 //call()将上下文对象设置为其第一个参数所指向的对象,并将其它参数作为原函数的参数 11 var dv=document.getElementsByTagName('div')[0]; 12 //将dv对象所指向的元素设置为红色 13 changeColor.call(dv,'red'); 14 15 //apply()将上下文对象设置为其第一个参数所指定的对象,第二个参数为传给函数的所有残所的数组 16 //设置body元素的函数 17 function setBodyColor(){ 18 changeColor.apply(document.body,arguments); 19 } 20 //设置背景为黑色 21 setBodyColor('black');
prototype属性:
prototype属性包含了一个对象(对象的原型),该对象可以作为所有新副本的基引用。本质上说,所有对象的prototype属性都能在该对象的每个实例中找到。和其它对象一样,可以为对象的原型添加任何新属性,且由该原型实例化的每个对象都会获得这些属性(也就是说这些属性公有化了);
公共方法:
在对象的上下文中始终可以使用的方法。可以在对象的原型上添加方法;
示例:创建公共方法
1 //通过原型创建公共方法 2 function Persion(name){ 3 this.name=name; 4 } 5 //创建公共方法 6 Persion.propotype.showName(){ 7 alert(this.name); 8 } 9 10 var psn=new Persion('FENG'); 11 psn.showName();//FENG
特权方法:
特权方法(privileged method)是指那些在查看并处理对象中私有变量的同时,允许用户以共有方法的方式访问的方法;
特权方法是动态生成的。实在运行时才添加到对象中的,而不是在代码第一次编译时就已经生成的。虽然这种方式创建的方法比直接在原型中添加方法的开销大,但是功能更强大,更灵活;
示例:创建特权方法
1 function Persion(name,age){ 2 //私有变量year,出生年份 3 var year=(new Date()).getFullYear()-age; 4 //创建特权方法,访问year私有变量 5 this.showBornYear=function(){ 6 alert(year); 7 } 8 } 9 10 var psn=new Persion('FENG',22); 11 //调用特权方法 12 psn.showBornYear();//1990 13 //私有成员变量,不可访问 14 alert(psn.year);//undefined
私有方法:
私有方法和私有变量只允许其他的私有方法/变量和特权方法访问。用于定义只让对象内部访问,而对象外部无法访问的代码;
参考:
http://javascript.crockford.com
http://javascript.crockford.com/private.html
示例:创建和使用是有方法
1 function Classromm(studentNames){ 2 this.studentNames=studentNames; 3 //私有方法,显示班级所有学生的名字 4 function dispStudent(){ 5 alert(this.studentNames.join(',')); 6 } 7 //内部调用私有方法 8 showStudent(); 9 } 10 11 var clsRom=new ClassRomm(['LIU','FENG','LAN']); 12 //出错,showStudent()未定义(私有方法) 13 clsRom.showStudent();
静态方法:
静态方法域其它一般函数相似,最主要的区别在于,其它函数是以对象的静态属性形式存在的。作为一个属性,它们不能在其对象的实例的上下文中访问,而只能在属于主对象本上的那个上下文中使用;
使用静态方法的一个特例是设置命名空间;
示例:创建静态方法
1 Persion.clonePersion=function(psn){ 2 //通过复制psn的属性创建并返回一个新用户 3 return new Persion(psn.getName,psn.getAge); 4 }
函数重载:函数重载必须依赖两件事情:判断传入参数的数量和参数类型的判断;
参数个数的判断:
Javascript的每个函数都带有一个作用于仅在该函数范围内的变量arguments。它是一个包含所有传给函数参数的伪数组(不能修改,也不能使用push(),但可用length属性和下标引用其中的元素);
示例:函数重载
1 //函数重载的例子 2 function sendMessage(msg,obj){ 3 //判断参数的个数 4 if(arguments.length==2){ 5 //给对象发送消息 6 obj.handleMsg(msg); 7 } 8 else{ 9 alert(msg); 10 } 11 } 12 13 //测试:一个参数 14 sendMessage('Hello,World!'); 15 //测试:两个参数 16 sendMessage('How are you?',{ 17 handleMsg:function(msg){ 18 alert('This is a custom message:'+mag); 19 } 20 });
参数类型的判断:
typeof:获取指定变量的类型。格式:typeof obj或typeof(obj)。可能取值为:boolean(true/false),mumber(数值类型,包括整数和浮点数),string(字符串),function(函数),undefined(Undefined或未定义)和object(其它类型,包括数组和NULL);
constructor:所有Javascript对象(Undefined和NULL类型除外)都有一个constructor属性,该属性用来引用原本用来构造该对象的那个函数。格式:obj.constructor。可能取值为:Boolean(true/false),Sumber(数值型,包括整型和浮点型),String(字符窜),Function(函数名或类名),Array(数组),Object(Object对象)或相应的类名(该类的对象);
说明:
1.返回值:typeof返回的是字符串类型的小写数据类型名,constructor返回的是首字母大写的类型名(非字符串类型);
2.typeof可用于Undefined和NULL类型的变量,而constructor不能,否则出错;
3.任何类型的变量,其值类型变量都可使用typeof操作,而数值型的值类型变量不可直接使用constructor,必须通过变量名使用contructor(其它类型的对象可直接通过值类型使用contructor);
示例:判断数据类型
1 //数据类型的判断 2 var nmbInt=2; 3 var nmbDouble=2.222; 4 var nul=null; 5 var udf=undefined; 6 var ud; 7 function Persion () { 8 this.name='nme' 9 } 10 var psn=new Persion(); 11 12 //typeof 13 alert(typeof (2)+' '+typeof (2.2)+' '+typeof (true)+' '+typeof ('')+' '+typeof (['s'])+' '+typeof (Persion)+' '+typeof (psn)+' '+typeof (udf)+' '+typeof (ud)+' '+typeof (u)+' '+typeof (null)); 14 //结果为:number number boolean string object function object undefined undefined undefined object 15 16 //constructor 17 alert(nmbInt.constructor+' '+nmbDouble.constructor+' '+true.constructor+' '+''.constructor+' '+['s'].constructor+' '+Persion.constructor+' '+psn.constructor); 18 //结果为: 19 /*function Number() { 20 [native code] 21 } function Number() { 22 [native code] 23 } function Boolean() { 24 [native code] 25 } function String() { 26 [native code] 27 } function Array() { 28 [native code] 29 } function Function() { 30 [native code] 31 } function Persion() { 32 this.name='nme' 33 }*/ 34 35 //判断 36 typeof ('')=='string'; //true 37 ''.constructor=='string'; //false 38 ''.constructor=='String'; //false 39 ''.constructor==String; //true