问题描述
我有一个类
function Node() { //implementation }
和另一个类
function AttributionalNode() { this.prototype.setAttr = function (attr) { this.atText = attr; }; } AttributionalNode.prototype = new Node(); AttributionalNode.prototype.constructor = AttributionalNode;
如何使class node()无法实例化? 例如,当我尝试
时var node = new Node();
所以它会引发异常?
推荐答案
这将有效:
function Node() { if (this.constructor === Node) { throw new Error("Cannot instantiate this class"); } } function AttributionalNode() { Node.call(this); // call super } AttributionalNode.prototype = Object.create(Node.prototype); AttributionalNode.prototype.setAttr = function (attr) { this.atText = attr; }; AttributionalNode.prototype.constructor = AttributionalNode; var attrNode = new AttributionalNode(); console.log(attrNode); new Node();
注意:您不能在构造函数内部参考this.prototype,因为原型只是构造函数函数的属性,而不是实例的属性.
其他推荐答案
在支持Ecmascript 2015(aka es6)类语法的JavaScript引擎中,可以使用new.target meta-property:
来完成此操作.function Node() { if (new.target === Node) throw TypeError("new of abstract class Node"); }
或使用类语法:
class Node { constructor () { if (new.target === Node) throw TypeError("new of abstract class Node"); } }
无论哪种情况,只需定义AttributionalNode as:
class AttributionalNode extends Node { constructor () { super(); } setAttr(attr) { this.atText = attr; } } new Node(); // will throw TypeError new AttributionalNode(); // works fine
有关new.target的更详细说明>请参阅第4.2节的此文档 .
其他推荐答案
适应 @levi的答案,您可以使用类似的解决方案来使用ES6(如new.target尚未确定):
您可以看到它可以在Babel的Repl上运行: http://bit.lit.ly/1cxygop
class Node { constructor () { if (this.constructor === Node) throw new Error("Cannot instantiate Base Class"); } callMeBaby () { console.log("Hello Baby!"); } } class AttributionalNode extends Node { constructor () { super(); console.log("AttributionalNode instantiated!"); } } let attrNode = new AttributionalNode(); attrNode.callMeBaby(); let node = new Node();
问题描述
I have a class
function Node() { //implementation }
and another class
function AttributionalNode() { this.prototype.setAttr = function (attr) { this.atText = attr; }; } AttributionalNode.prototype = new Node(); AttributionalNode.prototype.constructor = AttributionalNode;
How to make class Node() so it can't be instantiated? e.g when I try
var node = new Node();
So it throws an Exception?
推荐答案
This would work:
function Node() { if (this.constructor === Node) { throw new Error("Cannot instantiate this class"); } } function AttributionalNode() { Node.call(this); // call super } AttributionalNode.prototype = Object.create(Node.prototype); AttributionalNode.prototype.setAttr = function (attr) { this.atText = attr; }; AttributionalNode.prototype.constructor = AttributionalNode; var attrNode = new AttributionalNode(); console.log(attrNode); new Node();
Note: you cannot refer to this.prototype inside the constructor, as the prototype is only a property of the constructor function, not of the instances.
Also, see here for a good article on how to properly extend JS classes.
其他推荐答案
In JavaScript engines that support ECMAScript 2015 (aka ES6) class syntax, this can be accomplished using the new.target meta-property:
function Node() { if (new.target === Node) throw TypeError("new of abstract class Node"); }
or using class syntax:
class Node { constructor () { if (new.target === Node) throw TypeError("new of abstract class Node"); } }
in either case, just define AttributionalNode as:
class AttributionalNode extends Node { constructor () { super(); } setAttr(attr) { this.atText = attr; } } new Node(); // will throw TypeError new AttributionalNode(); // works fine
For a more detailed explanation of new.target see section 4.2 of this document.
其他推荐答案
Adapting @levi's answer, you can go with a similar solution for using with ES6 today (as new.target isn't established yet):
You can see it running on Babel's repl: http://bit.ly/1cxYGOP
class Node { constructor () { if (this.constructor === Node) throw new Error("Cannot instantiate Base Class"); } callMeBaby () { console.log("Hello Baby!"); } } class AttributionalNode extends Node { constructor () { super(); console.log("AttributionalNode instantiated!"); } } let attrNode = new AttributionalNode(); attrNode.callMeBaby(); let node = new Node();