前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript 面向对象(封装、继承、多态)多种方式实现完全总结

JavaScript 面向对象(封装、继承、多态)多种方式实现完全总结

作者头像
csxiaoyao
发布2019-02-15 16:39:56
1.3K0
发布2019-02-15 16:39:56
举报
文章被收录于专栏:csxiaoyao

1. 封装

封装就是把抽象出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法),才能对数据进行操作。 创建对象实现封装可以通过4种方式: 1. 对象字面量 {key:value,key:value…} 只能创建一次对象,复用性较差,如果要创建多个对象,代码冗余度太高 2. 内置构造函数 var obj = new Object();obj.name = “csxiaoyao”; 3. 简单工厂函数 function createObj(name,company){var obj =new Object();obj.name = name;return obj;} 4. 自定构造函数

代码语言:javascript
复制
function Person(name, agei){ 
    // public
    this.name = name;// 可直接通过对象点语法调用
    // private
    var age = agei;// 不可通过对象点语法调用
    this.getAge = function(){//getter
        return age;
    }
    this.setAge = function(a){//setter
        age = a;
    }
}
Person.prototype.show = function(){
    var str = this.name + " "+ this.getAge();
    //报错分析: 1.不加this表示访问原型属性 2.原型不能访问所在类的私有属性和方法
    // var str = name + " "+ age;
    return str;
}
//必须使用new关键字创建对象,否则this指向window
var p1 = new Person('csxiaoyao', 25);
//调用对象公开属性和私有属性(undefined)
console.log(p1.name + " " + p1.age);//csxiaoyao undefined
//调用对象方法
p1.setAge(20);
console.log(p1.getAge());//20
//调用原型方法
console.log(p1.show());//csxiaoyao 20
var p2 = new Person();
//利用对象动态性添加属性
p1.n = "sunshine";
console.log(p1.n);//sunshine

JS封装只有两种状态,一种是公开的,一种是私有的。

通过【构造函数】和【原型法】添加成员方法的区别 1. 通过原型法分配的函数(引用类型即可)所有对象共享 2. 通过原型法分配的属性(基本类型)独立 3. 若希望所有对象使用同一个函数,建议使用原型法添加函数,节省内存 4. 通过prototype给所有对象添加方法,不能访问所在类的私有属性和方法

2. 继承

继承可以解决代码复用,让编程更接近人的思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过继承父类中的属性和方法。 实现继承可以通过5种方式: 1. 混入式继承 使用for in遍历对象1的属性,将所有的属性添加到另外一个对象2上 2. 经典继承 var 对象1 = Object.create(对象2); 创建的对象1继承自对象2,需要解决Object.create方法兼容性问题 3. 原型继承 (1)利用对象的动态特性,为原型对象添加成员 (2)直接替换原型对象(需要手动指定原型对象的construtor属性)

代码语言:javascript
复制
function Person(name, age){
    this.name = name;
    this.age = age;
}
//1.给原型对象中添加成员(通过对象的动态特性)不是严格意义上的继承
Person.prototype.sayHello = function () {
    console.log("sayHello1");
}
// p1对象继承原型
var p1 = new Person("csxiaoyao",25);
p1.sayHello();//sayHello1
//2.直接替换原型对象
var parent = {
    sayHello : function () {
        console.log("sayHello2");
    }
}
Person.prototype = parent;
var p2 = new Person("csxiaoyao",25);
p2.sayHello();//sayHello2

★4. 对象填充

代码语言:javascript
复制
function Stu(name, age){
    this.name = name;
    this.age = age;
    this.show = function(){
        console.log(this.name + " " + this.age);
    }
}
function MidStu(name, age, money) {
    this.stu = Stu;//为当前对象创建Stu构造方法,赋值给stu属性
    this.stu(name, age);//调用构造方法,为当前构造函数添加name、age、show
    this.payFee = function(){//添加子类方法
        console.log("缴费" + money * 0.8);
    }
}
function Pupil(name, age, money) {
    this.stu = Stu;
    this.stu(name, age);
    this.payFee = function(){
        console.log("缴费" + money * 0.5);
    }
}
var midStu = new MidStu("csxiaoyao", 13, 10000);
var pupil = new Pupil("sunshine", 10, 10000);
midStu.show();//csxiaoyao 13
midStu.payFee();//缴费8000
pupil.show();//sunshine 10
pupil.payFee();//缴费5000

★5. call / apply (推荐)

代码语言:javascript
复制
function Stu(name,age){
    this.name=name;
    this.age=age;
    this.show=function(){
        console.log(this.name+" "+this.age);
    }
}
function MidStu(name,age){
    Stu.call(this,name,age);//调用父类构造函数
    //Stu.apply(this,[name,age]); 
    this.pay=function(fee){
        console.log("学费:"+fee*0.8);
    }
} 
function Pupil(name,age){ 
    Stu.call(this,name,age);
    this.pay=function(fee){
        console.log("学费:"+fee*0.5);
    }
}
var midstu = new MidStu("csxiaoyao",15); 
var pupil = new Pupil("sunshine",12); 
midstu.show();// csxiaoyao 15
midstu.pay(100);// 学费:80
pupil.show();// sunshine 12
pupil.pay(100);// 学费:50

3. 多态性

3.1 函数重载

函数重载是多态的基础,JS函数不支持多态,事实上JS函数是无态的,支持任意长度、类型的参数列表。如果同时定义了多个同名函数,以最后一个函数为准。

代码语言:javascript
复制
//js通过判断参数个数、类型来实现重载
function Person(){
    this.test = function (){
        if(arguments.length==1 && (typeof arguments[0])==="string"){
            this.show1(arguments[0]);
        }else if(arguments.length==1 && (typeof arguments[0])==="number"){
            this.show2(arguments[0]);
        }else if(arguments.length==2){
            this.show3(arguments[0],arguments[1]);
        }else if(arguments.length==3){
            this.show4(arguments[0],arguments[1],arguments[2]);
        }
    }
    this.show1=function(a){
        console.log("function(string):"+a);
    }
    this.show2=function(a){
        console.log("function(number):"+a);
    }
    this.show3=function(a,b){ 
        console.log("function(a,b):"+a+","+b); 
    }
    function show4(a,b,c){ 
        console.log("function(a,b,c):"+a+","+b+","+c); 
    }
} 
var p1=new Person();
p1.test("a");//function(string):a
p1.test(1);//function(number):1
p1.test("sun","shine");//function(a,b):sun,shine
// p1.test("sun","shine","studio");//报错 is not a function

3.2 多态实现

多态是指一个引用(类型)在不同情况下的多种状态(通过指向父类的引用,来调用在不同子类中的实现方法)。

代码语言:javascript
复制
// Master类
function Master(name){
    this.nam=name;
}
//原型法添加成员函数
Master.prototype.feed=function (animal,food){
    console.log("给 "+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 Animal(name){
    this.name=name;
}
function Cat(name){
    this.animal=Animal;
    this.animal(name);
}
function Dog(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("csxiaoyao"); 
master.feed(dog,bone);//给 狗 喂 骨头
master.feed(cat,fish);//给 猫 喂 鱼
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年05月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 封装
  • 2. 继承
  • 3. 多态性
    • 3.1 函数重载
      • 3.2 多态实现
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档