高级面向对象
一,JS是基于原型的对象
//最基本的面向对象写法 //创建构造函数 function Aaa(){ this.name='小明'; } //构造方法 Aaa.prototype.showName=function(){ alert(this.name); } //使用 //创建实例 var a1=new Aaa(); a1.showName(); //在JS源码中:系统对象也是基于原型的程序 function Array(){ this.lenglth=0; } Array.prototype.push=function(){}; Array.prototype.sort=function(){}; var arr=new Array(); arr.push(); arr.sort();
二,包装对象
/*var str='hello'; alert(typeof str);//string str.charAt(0); str.indexOf('e');*/ //包装对象:基本类型都有自己对应的包装对象,String/Number/Boolean //var str=new String('hello'); //alert(typeof str);//object //String.prototype.charAt=function(){}; var str='hello'; //调用此句时触发的动作:基本类型会找到对应的包装对象类型,然后包装对象把所有的属性和方法给基本类型,然后包装对象消失 //str.charAt(0); //在原型上创建的方法是共享的 String.prototype.lastValue=function(){ return this.charAt(this.length-1); } alert(str.lastValue());//o //调用此句时,在String包装对象下创建num属性,创建完成后包装对象消失 str.num=10; //此句又重新创建了num属性 alert(str.num);//undefined
三,原型链
//原型链:实例对象与原型之间的连接 //原型链的最外层:object.prototype function Aaa(){ //此处的num在实例a1上 this.num=20; } //此处的num在原型Aaa.prototype上 Aaa.prototype.num=10; Object.prototype.num=30; var a1=new Aaa(); alert(a1.num);//20
四,面向对象的一些属性和方法
1.hasOwnProperty():看是不是对象自身下面的属性
2.constructor:查看对象的构造函数
每个原型都会自动添加constructor属性
For in的时候有些属性是找不到的
避免修改constructor属性
3.instanceof:运算符
对象与构造函数在原型链上是否有关系
4.toString():object上的方法
(1)hasOwnProperty()
var arr=[]; arr.num=10; Array.prototype.num2=20; alert(arr.hasOwnProperty('num'));//true //num2是在原型的上公用方法,而不是自身独有的 alert(arr.hasOwnProperty('num2'));//false
(2)constructor
function Aaa(){ } var a1=new Aaa(); alert(a1.constructor);//function Aaa(){} var arr=[]; //alert(arr.constructor);//function Array(){[native code]} alert(arr.constructor==Array);//true
//当我们写构造函数Aaa后,系统会在原型上自动生成constructor function Aaa(){}; //系统自动添加 //每一个函数都会有的,都是自动生成的 //Aaa.prototype.constructor=Aaa; //手动修改constructor指向 Aaa.prototype.constructor=Array; var a1=new Aaa(); alert(a1.constructor);//function Array(){[native code]} alert(a1.hasOwnProperty==Object.prototype.hasOwnProperty);//true
function Aaa(){}; //constructor:function Aaa(){}; //Aaa.prototype.name='小明'; //Aaa.prototype.age=20; //constructor:function Array(){[native code]} //json直接赋值给了Aaa.prototype,将系统自动生成的覆盖掉了 Aaa.prototype={ //手动修正 constructor:Aaa, name:'小明', age:20 }; var a1=new Aaa(); alert(a1.constructor);
function Aaa(){}; Aaa.prototype.name='小明'; //系统自带的属性遍历不到 for (var attr in Aaa.prototype) { alert(attr);//name }
(3)instanceof:运算符
function Aaa(){ } var a1=new Aaa(); alert(a1 instanceof Aaa);//true alert(a1 instanceof Object);//true alert(a1 instanceof Array);//false //做类型判断 var arr=[]; alert(arr instanceof Array);
(4)toString()
//toString():Object上的方法 //系统对象下面都是自带的,自己写的对象都是通过原型链找object下面的 var arr=[]; alert(arr.toString==Object.prototype.toString);//false alert(arr.toString==Array.prototype.toString);//false function Aaa(){ } var a1=new Aaa(); alert(a1.toString==Object.prototype.toString);//true //把对象转换成字符串 var arr=[1,2,3]; Array.prototype.toString=function(){ return this.join('+'); } alert(arr.toString());//1+2+3 //进制转换 //十进制转换成16进制 var num=255; alert(num.toString(16));//ff //类型的判断 var arr1=[]; alert(Object.prototype.toString.call(arr1));//'[object Array]' var arr2={}; alert(Object.prototype.toString.call(arr2));//'[object object]' var arr3=new Date(); alert(Object.prototype.toString.call(arr3));//'[object Date]' //判断数组 alert(Object.prototype.toString.call(arr1)=='[object Array]');//true //iframe var oF=document.createElement('iframe'); document.body.appendChild(oF); var ifArray=window.frames[0].Array; var arr=new ifArray(); //constructor判断类型失效 alert(arr.constructor==Array);//false //instanceof判断类型失效 alert(arr instanceof Array);//false alert(Object.prototype.toString.call(arr)=='[object Array]');//true