美文网首页
类的继承(ES5)

类的继承(ES5)

作者: royluck | 来源:发表于2019-11-12 15:26 被阅读0次

通过闭包实现类的静态变量:

var Book = (function (argument) {
    // 静态私有变量
    var bookNum = 0;
    // 静态私有方法
    function checkBook(name){}
    // 创建类
    function _book(newId, newName, newPrice){
        // 私有变量
        var name, price;
        // 私有方法
        function checkID(id){}
        // 特权方法
        this.getName = function(){};
        this.getPrice = function(){};
        this.setName = function(){};
        this.setPRice = function(){};
        // 共有属性
        this.id = newId;
        // 共有方法
        this.copy = function(){};
        bookNum++
        if(bookNum > 100){
            throw new Error('我们仅出版100本书.');
        }
        // 构造器
        this.setName(name);
        this.setPrice(price);
    }
    __book.prototype = {
        // 静态共有属性
        isJSBook: false,
        // 静态公有方法
        display: function(){}
    }
    // 返回类
    return __book;
})()

创建对象的安全模式:

var Book = function(title, time, type){
    // 判断执行过程中this是否是当前这个对象(如果是说明是用new创建的)
    if(this instanceOf Book){
        this.title = title;
        this.time = time;
        this.type = type;
    // 否则重新创建这个对象       
    }else{
        return new Book(title, time, type);
    }
}

var book = new Book('javaScript','2014','js')

类主要由三部分组成:

  • 第一部分是构造函数内的,这是供实例化对象复制用的;
  • 第二部分是构造函数外的,直接通过点语法添加的,这是供类使用的,实例化对象访问不到;
  • 第三部分是类的原型中的,实例化对象可以通过其原型链间接地访问到,也是为供所有实例化对象所共用的。

instanceof是判断前面的对象是否是后面类的实例;
创建的所有对象都是Object的实例。



实现继承:
  • 类式继承:
    新创建的对象不仅仅可以访问父类原型上的属性和方法,同样也可访问从父类构造函数中复制的属性和方法。你将这个对象赋值给子类的原型,那么这个子类的原型同样可以访问父类原型上的属性和方法以及父类构造函数中复制的属性和方法。这正是类式继承原理。
function SuperClass(){
    this.superValue = true;
}

SuperClass.prototype.getSuperValue = function(){
    return this.superValue;
}

function SubClass(){
    this.subValue = false;
}

SubClass.prototype = new SubClass();

subValue.prototype.getSubValue = function(){
    return this.subValue;
};

缺点:在创建父类的时候,无法向父类传递参数,因而在实例化父类的时候也无法对父类构造函数内的属性进行初始化;


  • 构造函数继承:
    对superClass调用这个方法就是将子类中的变量在父类中执行一遍,由于父类中是给this绑定属性的,因此子类自然继承了父类的共有属性。
function SuperClass(id) {
    this.id = id
}

SuperClass.prototype.showBooks = funciton(){
    console.log(this.id);
}

function SubClass(id){
    SuperClass.call(this, id); // 构造函数继承精华
}

var instance1 = new SubClass(10) // =>10
instance1.showBooks()   // TypeError

缺点:没有涉及原型prototype,父类的原型方法不被子类继承。因此instance1.showBooks()报错误TypeError


  • 组合继承:
    类式继承和构造函数继承的组合
function SuperClass(id){
    this.books = ['html', 'css', 'javaScript'];
    this.id = id;
}

SuperClass.prototype.showBooks = function(){
    console.log(this.books)
}

function SubClass(id){
    SuperClass.call(this, id) // 父类构造函数被调用第一次
}

SubClass.prototype = new SuperClass() // 父类构造函数被调用第二次

SubClass.prototype.showId = function () {
    console.log(this.id)
}

var instance1 = new SubClass(10)
var instance2 = new SubClass(11)
instance1.books.push('设计模式')
instance1.showBooks() //  ["html", "css", "javaScript", "设计模式"]
instance1.showId() // =>10

instance2.showBooks() //  ["html", "css", "javaScript"]
instance2.showId() // =>11

缺点:父类构造函数被调用二次


  • 原型式继承:
    对类式继承的封装,过渡对象相当于类似继承的子类。
    Object.create()方法
// 等于 Object.create()方法
function inheritObject (o) {
    function f () {

    }
    f.prototype = o
    return new f()
}

var book1 = {
    name: 'js book',
    alikeBook: ['css book', 'html book']
}

var book2 = inheritObject(book1)
// var book2 = Object.create(book1)
book2.name = 'flash book'
book2.alikeBook.push('as book')

var book3 = inheritObject(book1)
console.log(book1.name) // => js book
console.log(book1.alikeBook) //  => ["css book", "html book", "as book"]
console.log(book2.name) // => flash book
console.log(book2.alikeBook) // => ["css book", "html book", "as book"]
console.log(book3.name) // => js book
console.log(book3.alikeBook) // => ["css book", "html book", "as book"]

缺点:跟类式继承一样,父类对象的book中的值类型的属性被复制,引用类型的属性被共用


  • 寄生式继承:
    对原型式继承的二次封装
function createBook (obj) {
    var o = new inheritObject(obj);
    // 拓展新对象
    o.getName = function () {
        console.log(this.name)
    }
    return o
}
var book4 = createBook(book1)
console.log(book4.name) // =>js book
console.log(book4.alikeBook) // =>["css book", "html book", "as book"]
book4.getName() // =>js book
  • 寄生组合式继承:
    综合上述的优点集合
// 寄生组合式继承
function inheritPrototype (subClass, superClass) {
    var p = Object.create(superClass.prototype);
    p.constructor = subClass;
    subClass.prototype = p;
}

function SuperClass (name) {
    this.name = name;
    this.colors = ['red', 'yellow', 'blue'];
}

SuperClass.prototype.getName = function () {
    console.log(this.name)
}

function SubClass (name, time) {
    SuperClass.call(this, name);
    this.time = time;
}

inheritPrototype( SubClass, SuperClass )

// SubClass.prototype = new SuperClass()

SubClass.prototype.getTime = function () {
    console.log(this.time)
}

var instance1 = new SubClass('css book', 2014);
var instance2 = new SubClass('js book', 2019);

instance1.getTime()
instance1.getName()
instance2.getTime()
instance2.getName()

instance1.colors.push('black')
console.log(instance1.colors) // => ["red", "yellow", "blue", "black"]
console.log(instance2.colors) // => ["red", "yellow", "blue"]

相关文章

  • es5继承

    继承 ES5的继承也都是通过借用父类的构造方法来实现父类方法/属性的继承: // 父类 functionsupFa...

  • 面向对象类

    类与实例 类的声明 ES5 ES6 生成实例 类与继承 如何实现继承 继承的几种方式 原型链是实现继承的主要方法 ...

  • ES的类与继承

    ES5中的类与继承 构造函数继承,原型继承,组合式继承 静态方法,静态属性,实例方法,实例属性 ES6中的类与继承...

  • 继承:es5 vs es6

    es5如何实现继承 es5实现继承主要是通过原型来实现的 首先实现一个父类 function Father(na...

  • ES6学习笔记(三)

    十一、类和继承 1、版本 ES5以前的: function Person(){ ​ this....

  • typescript 学习第二天

    一 es5 1.定义类 2.类的继承 3.类的静态方法 二 typescript 1.定义类 2.ts中实现继承...

  • 类的继承(ES5)

    通过闭包实现类的静态变量: 创建对象的安全模式: 类主要由三部分组成: 第一部分是构造函数内的,这是供实例化对象复...

  • ES5的继承和ES6的继承有什么区别?

    ES5的继承是通过prototype或构造函数机制来实现。 ES5的继承实质上是先创建子类的实例对象,然后再将父类...

  • es5 es6静态方法、类、单例模式

    es5中的类和静态方法 es5继承 es6中的类 es6里面的继承 es6里面的静态方法 es6单例模式 转载:h...

  • ES5和ES6继承和区别

    在es5中的继承 由此可知,ES5继承的实质是先创建了子类元素child的的实例对象,然后再把父类元素parent...

网友评论

      本文标题:类的继承(ES5)

      本文链接:https://www.haomeiwen.com/subject/fkkzbctx.html