建议使用原型法
当 for ++ 出错的时候,可以考虑用for in 遍历
构造函数(方法)是的一种特殊的方法,它的主要作用是完成对对
象实例的初始化。它有几个特点:
①构造函数(方法)名和类名相同
②在创建一个对象实例时,系统会自动的调用该类的构造方法完
成对新对象的初始化。
构造方法(函数)小结
①构造方法名和类名相同
②主要作用是完成对新对象实例的初始化
③在创建对象实例时,系统自动调用该对象的构造方法
Object类是所有javascript类的基类,提供了一种创建自定义对象的简单方式,不需要程序员再定义构造函数。
主要属性:
constructor-对象的构造函数
prototype-获得类的prototype对象,static性质
主要方法:
hasOwnProperty(property)-是否属于本类定义的属性
isPrototypeOf(object)-是否是指定类的prototype
propertyIsEnumerable(property)-是否可例举的属性
toString()-返回对象对应的字符串
valueOf()-返回对象对应的原始类型值
-----------------------------------------------------------------------------
function Person(){
var name="abc"; //私有的,只能在内部使用
var age=900; //私有的,只能在内部使用
this.show=function (){ //函数
window.alert("name ="+name+" age"+age);
}
}
var p1=new Person();
window.alert(p1.name+“ ”+p1.age);//错误,因为name 和age是私有属性
p1.show();//ok,通过对象的一个内部函数来访问私有属性
-----------------------------------------------------
function 类名(){
this.属性名; //公开属性
var 属性名//私有属性
}
---------------------------------------------------
--------------------------------------------------------------------------------------------
u js面向对象的再说明
(1) 对于比较简单的对象,我们也可以这样定义
var dog={name: "小明"};
window.alert(dog['name']);
var dog1={name:'小红',sayHello:function(a,b){window.alert(a+b);}};
dog1.sayHello(45,55);
(2) 在某些情况下,我们需要去改变某个函数的this指向,我们可以通过 call/apply 来实现
基本用法:
函数名.call(对象); // 这时 函数的this就是 对象
(3) for ... in的另外用法
可以对数组遍历
可以对象遍历
//json
var dog={name:"xm",age:34,color:"red"};
//遍历对象
/*for(var key in dog){
window.alert(dog[key]);
}*/
//你的浏览器window对象支持的属性有那些
for(var key in window){
document.write("<br/>"+key+"="+window[key]);
}
(4) 可以通过delete 对象名.属性 来手动的删除某个属性值.
js的面向对象的三大特征
1. 封装性
所谓封装,就是把我们抽象出的属性和对属性的操作写到类的定义中,称为封装.
js 中实现封装主要有两种封装( 公开,私有)
class Person(name,sal){
this.name=name; //公开
var sal=sal;//私有
this.showInfo=function(){ //公开
window.alert(this.name+” ”+sal);
}
showInfo2(){ //把函数私有化.
window.alert(“你好”+this.name+” ”+sal)
}
}
通过构造函数添加成员方法和通过原型法添加成员方法的区别
1. 通过原型法分配的函数是所有对象共享的.
2. 通过原型法分配的属性是独立.(如果你不修改属性,他们是共享)
3. 建议,如果我们希望所有的对象使用同一一个函数,最好使用原型法添加函数,这样比较节省内存.
function Dog(){
this.shout=function(){
}
}
//原型法
Dog.prototype.shout=function (){
window.alert("小狗尖叫"+this.name);
}
//通过原型也可以给每个对象,分配属性
Dog.prototype.color="red";
var dog1=new Dog("aa");
var dog2=new Dog("bb");
if(dog1.shout==dog2.shout){
window.alert("dog1.shout==dog2.shout");
}
dog1.color="黑色";
window.alert(dog1.color+" "+dog2.color);
4. 请大家看一个题:
function Person(){
}
// 创建对象
var p1=new Person();
// p1.say(); [错误]
// 这时用原型法分配
Person.prototype.say=function(){
window.alert("ok");
}
p1.say();
结论是 类.prototype.函数=function (){};
称为后置绑定.
js面相对象的继承
看一段代码->问题是什么?
①对象冒充
代码如下:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<script type="text/javascript">
//中学生
/* function MidStu(name,age){
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
this.pay=function(fee){
window.alert("你的学费是"+fee*0.8);
}
}
//小学生
function Pupil(name,age){
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
this.pay=function(fee){
window.alert("你的学费是"+fee*0.5);
}
}*/
//代码的复用性不高.
//修改如下:
//1. 把子类中共有的属性和方法抽取出,定义一个父类Stu
function Stu(name,age){
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
}
//2.通过对象冒充来继承父类的属性的方法
function MidStu(name,age){
this.stu=Stu; //这里相当于把Stu构造函数(类)赋值给我们的属性this.stu
//调用this.stu方法
this.stu(name,age); //这个表示初始化MidStu,相当于执行Stu(name,age),这句话必须有,否则无法实现集成的效果
//可以写MidStu自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.8);
}
}
function Pupil(name,age){
this.stu=Stu;//这里只是把码继承.
//初始化一把
this.stu(name,age);
//可以写Pupil自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.5);
}
}
//测试
var midstu=new MidStu("贾宝玉",15);
var pupil=new Pupil("贾环",12);
midstu.show();
midstu.pay(100);
pupil.show();
pupil.pay(100);
</script>
</html>
②通过call 或者apply来实现
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<script type="text/javascript">
//中学生
/* function MidStu(name,age){
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
this.pay=function(fee){
window.alert("你的学费是"+fee*0.8);
}
}
//小学生
function Pupil(name,age){
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
this.pay=function(fee){
window.alert("你的学费是"+fee*0.5);
}
}*/
//代码的复用性不高.
//修改如下:
//1. 把子类中共有的属性和方法抽取出,定义一个父类Stu
function Stu(name,age){
window.alert("确实被调用.");
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
}
//2.通过对象冒充来继承父类的属性的方法
function MidStu(name,age){
//这里这样理解: 通过call修改了Stu构造函数的this指向,
//让它指向了调用者本身.
Stu.call(this,name,age);
//如果用apply实现,则可以
//Stu.apply(this,[name,age]); //说明传入的参数是 数组方式
//可以写MidStu自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.8);
}
}
function Pupil(name,age){
Stu.call(this,name,age);//当我们创建Pupil对象实例,Stu的构造函数会被执行,当执行后,我们Pupil对象就获取从 Stu封装的属性和方法
//可以写Pupil自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.5);
}
}
//测试
var midstu=new MidStu("孙悟空",15);
var pupil=new Pupil("猪八戒",12);
midstu.show();
midstu.pay(100);
pupil.show();
pupil.pay(100);
</script>
</html>
u js的继承小结
(1) js对象可以通过对象冒充,实现多重继承
(2) Object 类是所有js类的基类
js的多态的特性
① js的函数的重载文件
js默认不支持重载,我们可以通过,判断参数的个数来实现重载
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<script type="text/javascript">
//*****************说明js不支持重载*****
/*function Person(){
this.test1=function (a,b){
window.alert('function (a,b)');
}
this.test1=function (a){
window.alert('function (a)');
}
}
var p1=new Person();
//js中不支持重载.
p1.test1("a","b");
p1.test1("a");*/
//js怎么实现重载.通过判断参数的个数来实现重载
function Person(){
this.test1=function (){
if(arguments.length==1){
this.show1(arguments[0]);
}else if(arguments.length==2){
this.show2(arguments[0],arguments[1]);
}else if(arguments.length==3){
this.show3(arguments[0],arguments[1],arguments[2]);
}
}
this.show1=function(a){
window.alert("show1()被调用"+a);
}
this.show2=function(a,b){
window.alert("show2()被调用"+"--"+a+"--"+b);
}
function show3(a,b,c){
window.alert("show3()被调用");
}
}
var p1=new Person();
//js中不支持重载.
p1.test1("a","b");
p1.test1("a");
</script>
</html>
② 覆盖
当子类有一个方法和父类一样,则我们称子类的方法覆盖了父类的方法 。
//父类
function Stu(){
this.show=function(){
window.alert("stu show");
}
}
//子类
function MidStu(){
this.stu=Stu;
this.stu();
this.show=function(){
window.alert("midstu show");
}
}
var midstu=new MidStu();
midstu.show();
☞ 要实现覆盖,需要把子类的方法,防止类定义的后面.
<script type="text/javascript">
// Master类
function Master(name){
this.nam=name;
//方法[给动物喂食物]
}
//原型法添加成员函数
Master.prototype.feed=function (animal,food){
window.alert("给"+animal.name+" 喂"+ food.name);
}
function Food(name){
this.name=name;
}
//鱼类
function Fish(name){
this.food=Food;
this.food(name);
}
//骨头
function Bone(name){
this.food=Food;
this.food(name);
}
function Peach(name){
this.food=Food;
this.food(name);
}
//动物类
function Animal(name){
this.name=name;
}
//猫猫
function Cat(name){
this.animal=Animal;
this.animal(name);
}
//狗狗
function Dog(name){
this.animal=Animal;
this.animal(name);
}
//猴子
function Monkey(name){
this.animal=Animal;
this.animal(name);
}
var cat=new Cat("大花猫");
var fish=new Fish("黄花鱼");
var dog=new Dog("大花狗");
var bone=new Bone("猪骨头");
//创建一个主人
var master=new Master("韩顺平");
master.feed(dog,bone);
//扩展
var monkey=new Monkey("金丝猴");
var peach=new Peach("仙桃");
master.feed(monkey,peach);
</script>
再来一个
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<script type="text/javascript">
//中学生
/* function MidStu(name,age){
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
this.pay=function(fee){
window.alert("你的学费是"+fee*0.8);
}
}
//小学生
function Pupil(name,age){
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
this.pay=function(fee){
window.alert("你的学费是"+fee*0.5);
}
}*/
//代码的复用性不高.
//修改如下:
//1. 把子类中共有的属性和方法抽取出,定义一个父类Stu
function Stu(name,age){
window.alert("确实被调用.");
this.name=name;
this.age=age;
this.show=function(){
window.alert(this.name+"年龄是="+this.age);
}
}
//2.通过对象冒充来继承父类的属性的方法
function MidStu(name,age){
//这里这样理解: 通过call修改了Stu构造函数的this指向,
//让它指向了调用者本身.
Stu.apply(this,[name,age]);
//可以写MidStu自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.8);
}
}
function Pupil(name,age){
Stu.call(this,name,age);//当我们创建Pupil对象实例,Stu的构造函数会被执行,当执行后,我们Pupil对象就获取从 Stu封装的属性和方法
//可以写Pupil自己的方法.
this.pay=function(fee){
window.alert("你的学费是"+fee*0.5);
}
}
//测试
var midstu=new MidStu("孙悟空",15);
var pupil=new Pupil("猪八戒",12);
midstu.show();
midstu.pay(100);
pupil.show();
pupil.pay(100);
</script>
</html>