JS继承之extends

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS继承之extends相关的知识,希望对你有一定的参考价值。

参考技术A

ES6中有关 class 的继承方式,引入了 extends 关键字。
但其本质仍然是 构造函数 + 原型链的 组合式继承。

上述 B 类 (class)通过 extends 关键字,继承了 A 类 的所有属性和方法。 A 类 中的所有方法默认是添加到 B 的原型上,所以 extends 继承的实质仍然是原型链。

super 这个关键字,既可以当作函数使用,也可以当作对象使用。当作函数使用时 super 代表父类的构造函数,并在子类中执行 Parent.apply(this) ,从而将父类实例对象的属性和方法,添加到子类的 this 上面。

特别注意

因为类必须通过 new 关键字调用,所以在类的构造函数中 new.target 的值永远不会是 undefined 。

Vue.js 继承调用父方法

【中文标题】Vue.js 继承调用父方法【英文标题】:Vue.js inheritance call parent method 【发布时间】:2016-08-14 07:59:38 【问题描述】:

是否可以在 Vue.js 中使用方法覆盖?

var SomeClassA = Vue.extend(
  methods: 
    someFunction: function() 
      // ClassA some stuff
    
  
);

var SomeClassB = SomeClassA.extend(
  methods: 
    someFunction: function() 
      // CALL SomeClassA.someFunction
    
  
);

我想从 ClassB someFunction 中调用 ClassA someFunction。有没有可能?

【问题讨论】:

【参考方案1】:

不,vue 不适用于直接继承模型。据我所知,你不能A.extend 一个组件。它的父子关系主要通过道具和事件来运作。

但是有三种解决方案:

1.传递道具(父子)

var SomeComponentA = Vue.extend(
    methods: 
        someFunction: function () 
            // ClassA some stuff
        
    
);

var SomeComponentB = Vue.extend(
   props: [ 'someFunctionParent' ],
   methods: 
       someFunction: function () 
           // Do your stuff
           this.someFunctionParent();
       
   
);

在 SomeComponentA 的模板中:

<some-component-b someFunctionParent="someFunction"></some-component-b>

2。混合

如果这是您想在其他地方使用的常用功能,则使用 mixin 可能更符合习惯:

var mixin = 
    methods: 
        someFunction: function() 
            // ...
        
    
;

var SomeComponentA = Vue.extend(
    mixins: [ mixin ],
    methods: 
    
);

var SomeComponentB = Vue.extend(
   methods: 
       someFunctionExtended: function () 
           // Do your stuff
           this.someFunction();
       
   
);

3.调用父道具(父子,丑)

// In someComponentB's 'someFunction':
this.$parent.$options.methods.someFunction(...);

【讨论】:

1.在万不得已的情况下,这是一个很好的解决方案,但它的可扩展性不是很好。 2.这里有考虑过使用Mixins,但是修改函数名的必要性也不是可扩展的。 3. 你能搞定这个吗!? jsfiddle.net/9s146cdr/1 。这将是最好的选择,如果它是真的:) 我真的不推荐使用#3,我只是将它包含在参考中。其他两个对于 vue 来说更惯用(继承通常没有太大意义,因为 componentA 不是抽象类,而是 DOM 中的父组件,其职责与 componentB 不同)。如果您少考虑可扩展性而多考虑组件职责,这可能会有所帮助。 你不能使用#3,因为它不起作用 :) 我不能同意 因为 componentA 不是抽象类,而是 DOM 中的父组件,其职责与 componentB 不同 因为我错过了命名类,它应该是SomeAbstractComponentA。我从 Ember 来到 Vue,在我看来,组件中的继承并没有什么问题。 另外,您使用 vue 的示例不正确。您不应该在组件上调用 new。我会准备一个例子……这不是 Ember ;) 当然,这个小提琴只是为了证明#3 选项不起作用。我在模板中实例化组件。【参考方案2】:

如果有人对 JustWorksTM 解决方案感兴趣:

var FooComponent = 
  template: '<button @click="fooMethod()" v-text="buttonLabel"></button>',

  data: function () 
   return 
     foo: 1,
     bar: 'lorem',
     buttonLabel: 'Click me',
   
  ,

  methods: 
    fooMethod: function () 
      alert('called from FooComponent');
    ,
    
    barMethod: function () 
      alert('called from FooComponent');
    ,
  


var FooComponentSpecialised = 
  extends: FooComponent,

  data: function () 
   return 
     buttonLabel: 'Specialised click me',
     zar: 'ipsum',
   
  ,

  methods: 
    fooMethod: function () 
      FooComponent.methods.fooMethod.call(this);
    
      alert('called from FooComponentSpecialised');
    ,
  

jsfiddle:https://jsfiddle.net/7b3tx0aw/2/


更多信息:

    此解决方案适用于由于某种原因无法使用 TypeScript 的开发人员(我认为这允许将 vue 组件定义为类,从而允许完全继承功能集)。 进一步阐述解决方案(为什么和如何):https://github.com/vuejs/vue/issues/2977 考虑到这里没有使用火箭科学,这并没有那么难看(调用匿名函数并替换了 this 指针对于任何体面的 js 开发人员来说都不是魔法)。

如何使用Function.prototype.call()

参考https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

示例代码:

function Product(name, price) 
  this.name = name;
  this.price = price;


function Food(name, price) 
  Product.call(this, name, price);
  this.category = 'food';


console.log(new Food('cheese', 5).name);
// expected output: "cheese"

【讨论】:

我不知道这篇文章之后是否有什么变化,但我需要FooComponent.options.methods.fooMethod.call(this);【参考方案3】:

如果有人在这里寻求解决方案,这是我的,并且工作正常:

var SomeClassA = 
    methods: 
        someFunction: function () 
            this.defaultSomeFunction();
        ,
        // defaultSomeFunction acts like parent.someFunction() so call it in inheritance
        defaultSomeFunction: function () 
            // ClassA some stuff
        ,
    ,
;

var SomeClassB = 
    extends: SomeClassA,
    methods: 
        someFunction: function () 
            // Replace the wanted SomeClassA::someFunction()
            this.defaultSomeFunction();
            // Add custom code here
        ,
    ,
;

使用 https://vuejs.org/v2/api/#extends 中的 juste extends 替换 Vue.extends() 的用法

【讨论】:

以上是关于JS继承之extends的主要内容,如果未能解决你的问题,请参考以下文章

JS继承之原型继承

js继承之组合继承(结合原型链继承 和 借用构造函数继承)

js继承之原型继承

js继承之原型链继承

JS继承之借用构造函数继承和组合继承

js继承之借用构造函数继承