zoukankan      html  css  js  c++  java
  • JS中对象继承方式

    JS对象继承方式

    摘自《JavaScript的对象继承方式,有几种写法》,作者:peakedness
    链接:https://my.oschina.net/u/3970421/blog/2872629

    方式一:对象冒充

    原理:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使Parent构造函数称为Children的方法,然后调用它。Children会收到Parent的构造函数中定义的属性和方法。


    //父类构造函数
    var Parent = function(name){
        this.name = name;
        this.sayHi = function(){
            console.log("Hi" + this.name + ".");
        }
    }
    
    var Children = function(name){
        
        this.method = Parent;
        this.method(name);  //实现继承
        delete this.method;
    
        this.getName = function(){
            console.log(this.name);
        }
    }
    
    var P = new Parent("john");
    var C = new Children("joe");
    
    P.sayHi();      //Hi john
    C.sayHi();      //Hi joe
    C.getName();    //joe
    

    方式二:原型链继承

    原理:JS是一门基于原型的语言。在JS中prototype对象的任何属性和方法都被传递给那个类的所有实例。

    //父类构造函数
    var Parent = function(name){
        this.name = name;
        this.sayHi = function(){
            console.log("Hi" + this.name + ".");
        }
    }
    //子类构造函数
    var Children = function(){};
    
    Children.prototype = new Parent();
    
    var P = new Parent();
    var C = new Children();
    
    P.sayHi();
    C.sayHi();
    

    注意:
    调用Parent的构造函数,没有给它传递参数。这是原型链中的标准做法,要确保构造函数没有任何参数。

    方式三:使用call或apply方法

    原理:通过改变this指向实现继承。apply第二个参数必须是数组,call依次传入。

    //父类构造函数
    var Parent = function(name){
        this.name = name;
        this.sayHi = function(){
            console.log("Hi" + this.name + ".");
        }
    };
    //子类构造函数
    var Children = function(name){
        Parent.call(this,name);
        this.getName = function(){
            console.log(this.name);
        }
    };
    var C = new Children("Joe");
    C.sayHi();  //Hi john
    C.getName();    //Joe
    

    方式四:混合使用(推荐)

    使用原型链就无法使用带参数的构造函数了
    因此,在JS中创建类,最好使用构造函数定义属性,使用原型链定义方法。

    //父类构造函数
    var Parent = function(name){
        this.name = name;
    }
    Parent.prototype.sayHi = function(){
        console.log("Hi ! " + this.name + "!!!");
    }
    var P = new Parent("John");
    P.sayHi();  //Hi John !!!
    

    方式五:使用Object.create方法

    Object.create方法会使用指定的原型对象及其属性去创建一个新的对象

    //父类构造函数
    var Parent = function(name){
        this.name = name;
    }
    Parent.prototype.sayHi = function(){
        console.log("Hi " + this.name + ".");
    }
    //子类构造函数
    var Children = function(name,age){
        this.age = age;
        Parent.call(this,name);     //属性不在prototype上
    };
    
    Children.prototype = Object.create(Parent.prototype);
    Children.prototype.constructor = Children;
    Children.prototype.getAge = function(){
        console.log(this.age);
    };
    
    var P = new Parent("John");
    var C = new Children("Joe",30);
    
    P.sayHi();  //Hi John
    C.sayHi();  //Hi Joe
    C.getAge(); //30
    

    注意:
    当执行Children.prototype = Object.create(Parent.prototype)这个语句后,Children的constructor就被变为Parent,因此需要将Children.protype.constructor重新指定为Children本身。

    constructor指向创建此对象的函数的引用。

    方式六:extends关键字实现继承

    class Paren{
        constructor(name,age){
            this.name = name;
            this.age = age;
        }
    }
    class Children extends Parent{
        constructor(name,age,job){
            super(name,age);    //super必须在前,否则代码报错
            this.job = job;
        }
    }
    

    注意:
    子类的constructor方法没有调用super之前,就使用this关键字会报错。原因是:子类Children的构造函数之中的super(),代表调用父类Parent的构造函数。

    super虽然代表了父类Parent的构造函数,但是返回的是子类Children的实例,即super内部的this指的是Children,因此super()在这里相当于Parent.prototype.constructor.call(this);

  • 相关阅读:
    event.relatedTarget、event.fromElement、event.toElement
    before/after伪类常见用法
    $.getJSON 跨域
    ExtJS中store.findExact
    C#生成6位随机验证码
    C#验证手机号
    jQuery轮播图的事项 代码详细,容易理解。。。。谢谢观赏
    ES6 中 static 的this 丢失问题解决办法 简单明了 备注清晰 谢谢欣赏
    ES6 中 static 的this 问题 简单明了 备注清晰 谢谢欣赏
    ES6 中用class创建img 详细明了,步骤清晰,解释完美,谢谢欣赏
  • 原文地址:https://www.cnblogs.com/nanhuaqiushui/p/9949596.html
Copyright © 2011-2022 走看看