V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liujianwei
V2EX  ›  程序员

JavaScript 继承,看过来

  •  
  •   liujianwei ·
    jianliuwei · 2019-04-03 13:55:01 +08:00 · 1680 次点击
    这是一个创建于 2065 天前的主题,其中的信息可能已经有所发展或是发生改变。

    JavaScript 有多种方式实现继承,下面这些大家哪种用的比较多,还有没有其它方式?

    ES6 引入的 class 是不是最佳实践呢? ES5 时代,大家都用什么方式?

    组合 /模块模式的方式是不是可以作为继承的替代?

    请大家指导,各抒己见。

    构造函数

    function SuperClass(p) {
        this.prop = p
        this.method = function () {return this.prop}
    }
    
    function SubClass(p2) {
        this.prop2 = p2
        this.method2 = function () {return this.prop2}
    }
    
    SubClass.prototype = new SuperClass('prop') // inherit/extends
    
    let so = new SubClass('prop2') // create instance
    
    console.log(so.method())
    console.log(so.method2())
    

    Object.create

    let SuperObject = {
        prop: 'prop',
        method: function () {
            return this.prop
        }
    }
    
    let SubObject = Object.create(SuperObject) // equals to inheritance/extension
    
    let so = Object.assign(SubObject, { // equals to instantiation
        prop2: 'prop2',
        method2: function () {
            return this.prop2
        }
    })
    
    console.log(so.method())
    console.log(so.method2())
    

    Object.setPrototypeOf

    let SuperObject = {
        prop: 'prop',
        method: function () {
            return this.prop
        }
    }
    
    let SubObject = {
        prop2: 'prop2',
        method2: function () {
            return this.prop2
        }
    }
    
    let so = Object.setPrototypeOf(SubObject, SuperObject) // equals to inheritance/extension, and  equals to instantiation also
    
    console.log(so.method())
    console.log(so.method2())
    

    Class

    class SuperClass {
        constructor(p) {
            this.prop = p
        }
    
        method() {
            return this.prop
        }
    }
    
    class SubClass extends SuperClass { // inherit/extends
        constructor(p2) {
            super('prop')
            this.prop2 = p2
        }
    
        method2() {
            return this.prop2
        }
    }
    
    let so = new SubClass('prop2') // create instance
    
    console.log(so.method())
    console.log(so.method2())
    

    组合或模块模式

    let SuperClass = {
        createNew: function (p) {
            let prop = p
            let o = {}
            o.method = function () {
                return prop
            }
            return o
        }
    }
    
    let SubClass = {
        createNew: function (p2) {
            let prop2 = p2
            let o = SuperClass.createNew('prop') // equals to inheritance/extension, you can use composition also
            o.method2 = function () {
                return prop2
            }
            return o
        }
    }
    
    let so = SubClass.createNew('prop2') // equals to instantiation
    
    console.log(so.method())
    console.log(so.method2())
    
    6 条回复    2019-04-08 18:54:41 +08:00
    GTim
        1
    GTim  
       2019-04-03 14:16:07 +08:00
    9102 年了,当然是 ES6 + Babel
    leemove
        2
    leemove  
       2019-04-03 14:19:27 +08:00
    es6 时代肯定用 class,es5 的时候基本都用你这个列表的第一种,详细的可以参考高程,没记错里面应该有六种.
    murmur
        3
    murmur  
       2019-04-03 14:20:25 +08:00
    用了 vue 之后就发现对于应用层来说,mixin+plugin 的方法比 js 假 oo 好得多
    KuroNekoFan
        4
    KuroNekoFan  
       2019-04-03 14:43:31 +08:00
    用 class 就好
    love
        5
    love  
       2019-04-03 14:48:23 +08:00
    都 9102 年了,还在整这个,直接 class 走起
    ourleven
        6
    ourleven  
       2019-04-08 18:54:41 +08:00 via iPhone
    @murmur +1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5532 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 08:42 · PVG 16:42 · LAX 00:42 · JFK 03:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.