Javascript 如何使用原型实现异常类
我试图在JavaScript中创建一个异常类,但我在原型设计方面遇到了一个小问题,尽管我已经使用JavaScript很长时间了,但我从未真正正确地使用原型设计 这是我的密码Javascript 如何使用原型实现异常类,javascript,prototype,Javascript,Prototype,我试图在JavaScript中创建一个异常类,但我在原型设计方面遇到了一个小问题,尽管我已经使用JavaScript很长时间了,但我从未真正正确地使用原型设计 这是我的密码 // load the Object Prototype Exception = Object; Exception.prototype = new function () { // set defaults this.name = "Exception"; this.message = "";
// load the Object Prototype
Exception = Object;
Exception.prototype = new function () {
// set defaults
this.name = "Exception";
this.message = "";
this.level = "Unrecoverable";
this.html = "No HTML provided";
// code so that the console can get the name from this.name insted of using [object Object]
this.getName = function(){
return this.name;
}
// this is the exec of the object prototype the code that is executed when the new Exception call is made
this.exec = function(msg, name, lvl, html){
// create a return variable
var ret;
// check that msg is defined and is not empty
if(typeof(msg) == "undefined" || msg == ""){
throw new Exception("Can't throw exception without a msg");
}
// set up this Exception Object values
this.name = (typeof(name) == "undefined")? this.name : name;
this.level = (typeof(lvl) == "undefined")? this.level : lvl;
this.message = msg;
this.html = (typeof(this.html) == "undefined")? this.html : html;
// delete the getName function so it does not get set though to the console
delete this.getName;
// save the Exception object to our return variable
ret = this;
// re add the getName object to the Exception Object so that it can be called from the console
this.getName = function(){
return this.name;
}
// return the saved Exception object without the getName method
return ret;
}
}
但由于某些原因,在控制台中,它返回作为msg
这是我收到的控制台输出
throw new Exception("test");
test
0: "t"
1: "e"
2: "s"
3: "t"
length: 4
__proto__: String
任何帮助都将不胜感激我必须编辑此内容,因为我以前发布的一些信息不是真实的,也不是很有帮助 我之前说过JavaScript没有私有方法或属性;这是不真实的。私有方法可以通过使用闭包来实现: 根据文档,它会带来性能损失
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
要“子类化”现有对象,您必须使用prototype,因为JavaScript不是基于类的语言。下面是一个暴露JavaScript中原型缺点的示例。
以下优秀文档没有提到或至少没有给出适当的警告的是,“子”对象共享一个“父”对象的延迟复制实例。更准确地说,如果两个对象具有相同的原型(共享相同的父对象),则它们共享该父对象属性的相同实例。
其中的一些示例代码:
function Employee () {
this.name = "";
this.dept = "general";
this.objectVal=[];
}
function Manager () {
this.reports = [];
}
Manager.prototype = new Employee;
var bob=new Manager();
bob.name="bob";
bob.objectVal.push("should not be in jane");
var jane=new Manager();
jane.name="jane";
console.log(jane.name);//correct
console.log(jane.objectVal);//incorrect shows ["should not be in jane"]
简单值将正确,但对象值将不正确。在该文件的后面部分,针对该问题给出了一个解决方案,即:
function Manager () {
Employee.call(this);
this.reports = [];
}
Manager.prototype = new Employee;
Manager中的Employee.call(this)所做的是使用Manager的这个上下文调用Employee函数。因此,this.name、this.dept行成为Manager的直接属性,不是通过原型设计,而是通过它们在Manager的this上下文中初始化的事实
直线经理.prototype=新员工;可以省略,但(员工的bob instanceof)将计算为false
所以,在创建自己的类时,可以使用this.something语法将所有需要“由子实例唯一继承”的属性以及对象值放在“parent”中
“parent”的方法可以(根据一些文档应该)用prototype语法指定:
//var Employee=function(){....}
Employee.prototype.EmployeeMethod=function(){}
//or
//var Employee=function(){....}
Employee.prototype={EmployeeMethod:function(){},AnotherOne:function(){},....};
如果您想“子类化”错误(将错误作为异常原型),那么问题在于您没有编写错误,我无法将错误作为原型并使用其属性:
var Exception=function(msg){
// both don't work
// Error.call(Exception.prototype,msg);
Error.call(this,msg);
}
Exception.prototype=new Error;
var e=new Exception("my message");
console.log(e.message);//empty string
不确定原因,调用Error.call(this,msg)会将Error的属性设置为Exceptions属性(将它们复制到Exception),如果它们位于定义为this.someProperty的错误函数体中。调用Error.call(Exception.prototype,msg)不会将属性复制到Exception,但Exception仍然会通过原型链拥有这些属性
下面的链接是一篇文章,您可以在其中找到一个优雅的子类化解决方案,尽管我没有完全理解代码(解决方案在第2部分):
从您的代码判断,我认为这就是您想要做的:
Exception.prototype = new Error;
Exception.prototype.constructor = Exception;
function Exception(message, name, level, html) {
if (typeof message !== "string")
throw new Exception("Expected an error message.");
this.message = message;
this.name = name || "Exception";
this.level = level || "Unrecoverable";
this.html = html || "No HTML provided";
}
有关更多信息,请参阅
编辑:如果您在原型继承方面遇到问题,那么我建议您花一些时间来了解它:这是一个满足您要求的异常“类”示例:
/*
This is a constructor function. It creates a new Exception object.
Use it with the 'new' keyword , e.g. var e = new Exception("Another error").
*/
function Exception( message, name, level, html ) {
if ( !message ) {
throw 'No exceptions without a message!';
}
/*
These properties may have different values for each instance so set
them here in the constructor rather than adding them to the prototype.
*/
this.message = message;
this.name = name || "Exception";
this.level = level || "Unrecoverable";
this.html = html || "No HTML provided";
}
/*
Overwrite the toString method inherited from Object.prototype
by adding a toString method that shows the name and message.
This method is the same for each instance so add it to the
prototype object instead of having to create and add it to
'this' in the constructor every time an instance is created.
*/
Exception.prototype.toString = function () {
return this.name + ': ' + this.message;
}
试试看
try {
throw new Exception("test");
} catch (e) {
console.log( e instanceof Exception); // true
console.log( e instanceof Error); // false
console.log( e );
// Exception {message: "test", name: "Exception", level: "Unrecoverable"...
}
throw new Exception("test"); // Uncaught Exception: test
与上面向
Exception.prototype
添加toString
方法不同,另一种确保Exception
对象的toString
方法返回其名称
和消息
的方法是从内置错误
对象的原型继承
Exception.prototype = Error.prototype;
如果未在异常
构造函数中设置异常
对象,这也会使该对象的默认名称
出现“错误”-但在本例中不需要这样做
这也意味着添加到Error.prototype
的任何属性都将出现
var e = new Exception("Another");
Error.prototype.about = 'This is an Error';
console.log( e.about ); // 'This is an Error'
console.log( e instanceof Exception); // true
console.log( e instanceof Error); // true
或者,我们可以从一个错误
实例继承,而不是从错误.prototype继承,就像Aadit M Shah的回答一样
Exception.prototype = new Error();
以创建一个新的错误对象为代价,这避免了异常.prototype
更改的潜在问题,从而影响错误.prototype
。对Error.prototype
的更改仍将影响Exception.prototype
,因为它们是通过Error
对象继承的
似乎满足您需求的最简单方法可能是避免继承Error
对象或Error.prototype
,只需将自己的toString
方法添加到Exception.prototype
,如第一个示例所示。解决OP“子类化”的原因首先是错误;IE有几个第三方JavaScript控制台
我试过Firebug lite,它可以满足你的需要。记录以下内容时,控制台中不再显示[object:object]:
您的代码中有很多古怪的东西。我建议从新开始,先阅读。JavaScript没有类Exception=Object
不会加载原型,它会生成Exception
对象的另一个名称。我不知道你认为新函数()…
在做什么,但你正在覆盖对象。prototype
。WTF?Object.prototype
似乎不可写(至少在FF中),但您至少正在尝试覆盖它。@FelixKling对象和基本值之间没有区别。在x=y
之后,x
的值与y
之前的值相同。@melpomene程序员没有内存地址,但JavaScript中有内存地址。但是,只有JavaScript引擎可以访问和操作它们。事实上,在每一种编程语言中创建的每个变量都有与其相关联的内存地址,因为变量