用自己的话说出“面向对象”

179 阅读3分钟

面向对象

ES5中的编写方式

function Person (name) {
    this._name = name;
    this.getName = function(name){
        console.log(this._name);
    };
    this.setName = function(name){
        this._name = name;
    }
}
var p = new Person("张三");
p.getName();//张三
p.setName("李四");//李四
p.getName();//李四

ES6中的编写方式

class Person {
    constructor(name){
        this._name = name;
    }
    getName(){
        console.log(this._name);
    }
    setName(name){
        this._name = name;
    }
}
var p = new Person("张三");
p.getName();//张三
p.setName("李四");//李四
p.getName();//李四

js面向对象的三大特征

1、封装
    封装很常见,我们日常使用的方法和类都是一种封装,遇到一些公共的过着逻辑比较长的,我们抽离出来独立封装成一个方法,直接就可以调用了;
2、继承
    常用的就是子类继承父类。
    ```
    class Son extends Person{
        contructor(name,age){
            //实例化子类的时候把子类的数据传给父类(这里的super必须有,super里的参数是所继承的父类实例化所需要的数据)
            super(name);
            this._age = age;
        }
    }
    ```

3、多态
    多态多是表示方法重写和方法重载
    方法重写:感觉像是把之前的方法extends继承下来覆盖掉
    

说说集中继承方式

function Person (name) {
    this._name = name;
    this.getName = function(){
        console.log(this._name);
    }
}
Person.prototype.out = function(conts){
    console.log(this._name+"正在:"+conts)
}
1、原型链继承
    function Child(){};
    Child.prototype = new Person();
    Child.prototype.name = "child";
    var child = new Child();
    
    console.log(child.name);//child
    console.log(child.out("想”"));//undefined正在:想”
    console.log(child instanceof Child);//true
    console.log(child instanceof Person);//true
    console.log(Child instanceof Person);//false
    
    特点:就是既是子类也是父类实例,“不分彼此”,父类新增的原型方法和属性,子类都能访问到,比较简单。
    缺点:无法实现多继承,来自原型对象的引用属性是所有实例共享的;创建子类实例,无法向父类构造函数传参。

2、构造继承
    
    function Child(name){
        Person.call(this);
        this._name = name;
    }
    var child = new Child();
    
    特点:创建实例可以向父级传递参数;也可以实现继承多个;
    缺点:实例并不是父级的实例,只是子级的实例;只能继承父级的实例熟悉和方法,不能继承原型属性和方法;无法实现函数复用,每个子类都有父类实例函数的副本,影响性能;
    
3、实例继承
    function Child(name){
        var child = new Person();
        child._name = name;
        return child;
    }
    var child = new Child;
    
    特点:不限制调用方式;
    缺点:实例时父级的,不是子级的;不支持多继承;
    
4、拷贝继承
    function Child(name){
        var person = new Person();
        for(var p in person){
            Child.prototype[p] = person[p];
        };
        Child.prototype._name = name;
    }
    var child = new Child();
    
    特点:多继承;
    缺点:效率低,内存占用高;里面用到forin枚举方法,有些属性是forin不到的。
    
5、组合继承
    function Child(name){
        Person.call(this);
        this._name = name;
    }
    Child.prototype = new Person();
    var child = new Child();
    
    特点:继承了实例和原型的方法与属性;是子类也是父类的实例;可传参可复用;
    缺点:调用了两次父类构造函数,生成两份实例
    
6、寄生组合继承
    function Child(name){
        Person.call(this);
        this._name = name;
    }
    (function(){
        var Other = function(){};
        Other.prototype = Person.prototype;
        Child.ptototype = new Other();
    }();
    var child = new Child();
    
    就是复杂了点,其他还好!
    

三大特征的优点:

封装:封装的优势在于定义只可以在类内部进行对属性的操作,外部无法对这些属性指手画脚,要想修改,也只能通过你定义的封装方法;

继承:继承减少了代码的冗余,省略了很多重复代码,开发者可以从父类底层定义所有子类必须有的属性和方法,以达到耦合的目的;

多态:多态实现了方法的个性化,不同的子类根据具体状况可以实现不同的方法,光有父类定义的方法不够灵活,遇见特殊状况就捉襟见肘了