Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

原型链实现继承 #1

Open
nianxiongdi opened this issue Aug 4, 2019 · 0 comments
Open

原型链实现继承 #1

nianxiongdi opened this issue Aug 4, 2019 · 0 comments
Labels
learing Learning articles

Comments

@nianxiongdi
Copy link
Owner

nianxiongdi commented Aug 4, 2019

原型链继承

通过prototype去实现

属性的继承

// 父类
function Base(name, sno) {
    this.name = name;
    this.sno = sno;
}

// 子类
function Student(name, sno, class_name) {
    Base.call(this, name, sno); // 调用父类的属性
    this.class_name = class_name;
}

const st = new Student('qy', '20170102', '3-2')
console.log(st);

继承方法

    function Base(name, sno) {
        this.name = name;
        this.sno = sno;
    }

    Base.prototype.learing = function() {
        console.log(this);
    }
    function Student(name, sno, class_name) {
        Base.call(this, name, sno); // 调用父类的属性
        this.class_name = class_name;
    }

    const st = new Student('qy', '20170102', '3-2')
    console.log(st);
    st.learing(); // Uncaught TypeError: st.learing is not a function 
    // 不存在的原因 Student调用Base的属性,为对方法进行继承,如何实现继承呢?
    // 初步想法是 使用 Student.prototye = Base.prototype

使用 Student.prototye = Base.prototype实现继承方法

    function Base(name, sno) {
        this.name = name;
        this.sno = sno;
    }

    Base.prototype.learing = function() {
        console.log(this);
    }
    function Student(name, sno, class_name) {
        Base.call(this, name, sno); // 调用父类的属性
        this.class_name = class_name;
    }

    Student.prototype = Base.prototype;
    Student.prototype.play_game = function() {
        console.log('play game');
    }

    const st = new Student('qy', '20170102', '3-2')
    console.log(st);

image

这样会出现一个问题,我们在子对象prototype上定义一个方法,会在父类上出现,这不符合面向对象的思想

Student.prototype.play_game = function() {
    console.log('play game');
}

image

如何解决play_game在子对象出现,在父对象不出现呢,我们可以通过子实例去解决这个问题,实例如下:

    function Base(name, sno) {
        this.name = name;
        this.sno = sno;
    }

    // Base.prototype指向的原型为Object
    Base.prototype.learing = function() {
        console.log(this);
    }
    function Student(name, sno, class_name) {
        Base.call(this, name, sno); // 调用父类的属性
        this.class_name = class_name;
    }

    //这里进行修改
    Student.prototype = new Base();

    // Student.prototype指向的原型为Base
    Student.prototype.play_game = function() {
        console.log('play game');
    }
    const st = new Student('qy', '20170102', '3-2')
    console.log(st);

image

这里还会出现一个问题,在我们打印Student.prototype.constructor, 构造器为父类,应该是自己,我们需要通过手动指定去解决这个问题:

    // 打印结果,
    ƒ Base(name, sno) {
        this.name = name;
        this.sno = sno;
    }
    function Base(name, sno) {
        this.name = name;
        this.sno = sno;
    }

    // Base.prototype指向的原型为Object
    Base.prototype.learing = function() {
        console.log(this);
    }
    function Student(name, sno, class_name) {
        Base.call(this, name, sno); // 调用父类的属性
        this.class_name = class_name;
    }

    //这里进行修改
    Student.prototype = new Base();

    //如果利用对象的形式修改原型对象,需要使用constructor 值回原来的对象
    Student.prototype.constructor = Student;
    // Student.prototype指向的原型为Base
    Student.prototype.play_game = function() {
        console.log('play game');
    }
    const st = new Student('qy', '20170102', '3-2')
    console.log(st);

image

使用Object.create实现继承

       function Base(name) {
            this.name = name;
        }
        Base.prototype.say = function() {
            console.log('base fun...');
        }
        function Student(name, className) {
            Base.call(this, name);
            this.className = className;
        }
        

        // 理解一点  对象的.__proto__ == 构造函数.prototype
        Student.prototype = Object.create(Base.prototype);
        
        Student.prototype.constructor = Student;

        Student.prototype.pay = function() {
            console.log('song...');
        }

        let st = new Student('name', '3_2')
        console.log(st);

image

这样就实现继承,类似于es6

class Student extends Base() {
    ...
}

继承属性和方法

       var A = function(name) {
            this.name1 = name; // this.name代表函数名,这里避免冲突
            this.getAname = function(){ console.log() }
        }

        var B = function(age) {
            this.age = age;
            this.getAge = function() {}
        }

        var C = function(name, age) {
            A.call(this, name);
            B.call(this, age);
        }

        // usage
        var c = new C('n', 2);
@nianxiongdi nianxiongdi added the learing Learning articles label Aug 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
learing Learning articles
Projects
None yet
Development

No branches or pull requests

1 participant