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的主要内容,如果未能解决你的问题,请参考以下文章