面向对象的三大特点:
封装:将描述同一个东西的属性和方法,定义在一个对象中
继承:父对象中的属性和方法,子对象可直接使用
多态:同一个对象,在不同情况下,呈现不同的状态
重载:同一个方法名相同,传入参数不同,执行不同的操作
重写:子对象觉得父对象的成员不好用,可自己定义一个,覆盖父对象的成员
继承:js中一切继承都是用原型对象实现的!
创建对象:4种
1.对象直接量(只一个对象)
var obj={"属性名":值,
···········:···,
“方法名”:function(){···this.属性名}
}
2.var obj=new Object();//创建一个空对象
obj.属性名=值;
obj.方法名=function(){····this.属性名}
3.利用构造函数**反复创建相同结构的对象:(好多相同类型对象)
构造函数:描述一类对象结构的特殊函数
2步:
3.1.定义构造函数
function 构造函数名|类型名(属性参数1,········){
this.属性名=属性参数1;//在当前正在创建的对象中创建一个属性名,赋值为属性参数1的值
if(!构造函数.ptototype.方法名){
构造函数 .prototype.方法名=function(){
·················this.属性名·····}
}
}
3.2.利用构造函数创建对象
var obj=new 构造函数名|类型名(属性参数1,········);
new:1.创建一个空对象:var obj={ };
2.调用空对象调用构造函数
构造函数在空对象中添加属性和方法
3.设置新对象的_proto_属性指向构造函数的prototype对象
4.返回新对象的地址
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自定义数组</title>
<script type="text/javascript">
// var lilei={
// sname:"li lei",
// age:12,
// instrSelf:function(){
// alert("i'm "+this.sname+",i'm 12");
// }
// }
// var hmm={
// sname:"han meimei",
// age:11,
// instrSelf:function(){
// alert("i'm han meimei,i'm 11");
// }
// }
function Student(sname,age){
this.sname=sname;
this.age=age;
}
Student.prototype.instrSelf=function(){
alert("i'm "+this.sname+",i'm "+this.age+" years old");}
var lilei=new Student("lilei",12);
var hanmeimei=new Student("hanmeimei",11);
Student.prototype.money=100;
console.log(hanmeimei.money);
lilei.instrSelf();
</script>
</head>
<body>
</body>
</html>
4.Object.crete(父对象,{扩展属性的列表对象})
原型对象:每个函数对象都有一个原型对象
构造函数的原型对象负责保存所有子对象共享的成员!
建议:所有子对象共享的方法,都应定义在构造函数的原型对象中--避免重复定义方法对象,浪费内存
所有函数都有prototype,指向自己的原型对象
所有函数都有_proto_,指向自己父级原型对象
所有原型对象都有constructor,指向原型对应的构造函数
扩展对象属性:2种扩展
1.扩展共有属性:通过构造函数.prototype添加的属性
2.扩展自有属性:通过某一个具体子对象添加的属性
**判断自有属性还是共有属性:
1.判断自有属性:obj.hasOwnProperty("属性名");
2.判断原型链上的属性:3种:
判断不包含:if(!(“属性名” in obj))
if (obj.属性名==undefined)
if(!obj.属性名)
3.判断共有属性:!obj.hasOwnProperty("属性名")&& obj .属性名
in包括了原型对象和子对象
删除属性:delete 对象.属性名
仅能删除当前对象自己的属性,无法删除共有属性
全局变量:3种
var n=1; window.n=1; window["n"]=1;
不能delete 不能delete 能delete
获取任意对象的原型:
obj._proto_X
Object.getPrototypeOf(obj)
判断父对象是否在子对象的原型链上:
父对象.isPrototypeOf(子对象)
检测一个对象是不是数组类型(4种):
方法一:Array.prototype是不是在obj的原型链中Array.prototype.isPrototypeOf(obj);
方法二obj instanceof构造函数名,判断obj对象是否被构造函数创建
obj instanceof Array;
方法三:原型对象的constructor属性
obj.constructor==Array;
方法四:object原型的tostring方法call/apply
Object.prototype.toString.call(obj)=="[object Array]";
原型链(多级继承):由各级对象的_proto_逐级继承形成的关系
获得任意对象的父级原型对象
object.getPrototypeOf(子对象)
==》子对象._proto_
继承:
什么是继承?代码重用!节省空间!
1.直接继承对象:想方设法修改对象的_proto_
3种:
1.1.仅修改一个对象的_proto_
Object.setPrototypeOf(子对象,父对象)
1.2通过修改构造函数的原型对象,实现批量修改后续子对象的继承关键
构造函数.prototype=父对象
强调:仅影响之后创建的对象的继承关系
之前创建的对象依然继承旧构造函数
1.3Object.create(父对象,{属性列表});
创建一个空对象,继承父对象中的属性
继承同时可在扩展属性和方法
继承同时可在扩展属性和方法
1.4子对象重写 改写
子对象.属性名=值;
子对象.方法名=function(){
············函数体··········};
2.仅继承结构:模拟Java中的继承
function 父类型构造函数(属性参数){
this.属性1=属性参数1;
this.属性2=属性参数2;
}
function 子类型构造函数(属性参数1,属性参数2,属性参数3){
父类型构造函数.call(this,属性参数1,属性参数2);
this.属性3=属性参数3;
}
var obj=new 子类型构造函数(值1,值2,值3);