一,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