26javascript基于对象

来源:互联网 发布:java swing 表格 编辑:程序博客网 时间:2024/04/29 08:48
1. 用JavaScript实现类
       JavaScritpt没有专门的机制实现类,这里是借助它的函数允许嵌套的机制来实现类的。一个函数可以包含变量,又可以包含其它函数,这样,变量可以作为属性,内部的函数就可以作为成员方法了。因此外层函数本身就可以作为一个类了。如下:


function myClass()
{
    //此处相当于构造函数
}
这里 myClass就是一个类。其实可以把它看成类的构造函数。至于非构造函数的部分,以后会详细描述。


如何获得一个类的实例
实现了类就应该可以获得类的实例,JavaScript提供了一个方法可以获得对象实例。即 new操作符。其实JavaScript中,类和函数是同一个概念,当用new操作一个函数时就返回一个对象。如下:
var obj1 = new myClass();


对象的成员的引用
在JavaScript中引用一个类的属性或方法的方法有以下三种。
点号操作符,这是一种最普遍的引用方式,就不累赘。即如下形式:
对象名.属性名;
对象名.方法名;


方括号引用,JavaScript中允许用方括号引用对象的成员。如下:
对象名["属性名"];
对象名["方法名"];
这里方括号内是代表属性或方法名的字符串,不一定是字符串常量。也可以使用变量。这样就可以使用变量传递属性或方法名。为编程带来了方便。在某些情况下,代码中不能确定要调用那个属性或方法时,就可以采用这种方式。否则,如果使用点号操作符,还需要使用条件判断来调用属性或方法。
另外,使用方括号引用的属性和方法名还可以以数字开头,或者出现空格,而使用点号引用的属性和方法名则遵循标识符的规则。但一般不提倡使用非标识符的命名方法。


如果引用一个非对象的成员则会返回undefined。
 
使用eval函数
如果不希望使用变量传递变量或方法名,又不想使用条件判断,那么eval函数是一个好的选择。eval接收一个字符串类型的参数,然后将这个字符串作为代码在上下文中执行,返回执行的结果。这里正是利用了eval的这一功能。如下:
alert(eval("对象名." + element.value));//通过eval执行对象的某个函数或得到对象的某个属性
        
2对对象属性,方法的添加、修改和删除操作
javascript的Object(Object的实例)就是一个无序的集合。
JavaScript中,在生成对象之后还可以为对象动态添加、修改和删除属性和方法,这与其它面向对象的语言是不同的。
添加属性和方法
先创建一个对象,空对象创建后没有任何属性和方法,然而我们可以在代码中创建。
var obj1 = new Object();
//添加属性
obj1.ID = 1;//或者obj1['ID']=1;
obj1.Name = "johnson";//或者obj1['Name']="johnson"


//添加方法
obj1.showMessage = function()
{
    alert("ID: " + this.ID + ", Name: " + this.Name);
}


修改属性与方法
与添加属性和方法类似,例如接着上面的例子:
// 修改属性
obj1.ID = 1;
obj1.Name = "Amanda";


// 修改方法
obj1.showMessage = function()
{
    alert("ID: " + this.ID");
}
    
删除属性与方法
直接将要删除的属性或方法赋值为undefined即可:
obj1.ID = 1;
obj1.Name = undefined;


obj1.showMessage = undefined;




3创建无类型对象。
JavaScript 也可以创建无类型的对象。形式如下:
var obj1 = {};
var obj2 = 
{
    ID: 1,
    Name: "Johnson",
    showMessage: function()
    {
        alert("ID: " + this.ID + "Name: " + this.Name);
    }
}
这里定义了两个无类型的对象,obj1和obj2。其中obj1是一个空对象。obj2包括两个属性ID, Name和一个方法showMessage。每个属性和方法用逗号分割。属性(方法)名和其值之间用分号分割。
       用这种方式创建属性方法时,也可以用字符串定义属性方法的名字。如:
var obj2 = 
{
    "ID" : 1,
    "Name": "Johnson"
}
 
in 操作符判断是否是某个对象的属性,如果不是对象的属性则返回false。
例如:
var aa = {
  CONST: {
      SINGLE: 'single',
      MULTI: 'multi'
     },
    include: function(type) {
      return (type.toUpperCase() in this.CONST);
     }
}
alert(aa.include('single')); 将返回 true,include方法判断'single'是否是对象aa里面的CONST对象里的属性。include方法里面的this关键字表示当前对象aa。




3prototype
每个函数对象都具有一个子对象prototype,因为函数也可以表示类,所以prototype表示一个类的成员的集合。当new 一个对象时,prototype对象的成员都会被实例化成对象的成员。先看一个例子:
function myClass()
{ }


myClass.prototype.ID = 1;
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
    alert("ID: " + this.ID + "Name: " + this.Name);
}


var obj1 = new myClass();
obj1.showMessage();
      使用prototype对象创建类有一个好处。如果将所有的成员直接写在类的声明中,如下:
function myClass()
{
    //添加属性
    this.ID = 1;
    this.Name = "johnson";


    //添加方法
    this.showMessage = function()
    {
        alert("ID: " + this.ID + ", Name: " + this.Name);
    }
}


var obj1 = new myClass();
var obj2 = new myClass();
        在上面的代码中,定义了一个类myClass,在类中直接定义了两个属性和一个方法。然后实例化了两个对象,这里的两个属性和一个方法,每创建一次myClass对象都会被创建一次,浪费了内存空间。而用prototype以后就可以解决这个问题,每new一个函数时,其prototype对象的成员都会自动赋给这个对象,当new多个对象时不会重复创建。
        由于prototype的初始化发生在函数体执行之前,用以下代码可以证明:
function myClass()
{
    //此处相当于构造函数
    this.ID = 1;
    this.Name1 = this.Name;
    this.showMessage();
}
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
    alert("ID: " + this.ID + ", Name: " + this.Name);
}


var obj1 = new myClass();
执行以上代码可以发现当new这个类型的对象时,即弹出了对话框。
最后只得一提的是,prototype有一个方法,在面向对象的设计中用得到。即:constructor属性,是对构造函数的调用,这里的构造函数即上文提到的类的声明里的代码。如:
function myClass()
{
    //此处相当于构造函数
    alert("this is in constructor");
}
myClass.prototype.constructor();


var obj1 = new myClass();
执行以上代码你会发现对话框弹出了两次。由此可见,prototype可专门用于设计类的成员,实际上在JavaScript面向对象的设计中,很多时候都会用到prototype。




4javascript异常处理
如下是javascript的异常处理的实例:
<html>
<head>
<script type="text/javascript">
var array = null;
try {
document.write(array[0]);
} catch(err) {
document.writeln("Error name: " + err.name + "</br>");
document.writeln("Error message: " + err.message);
}
finally{
alert("object is null");
}
</script>
</head>
<body>


</body>
</html>
程序执行过程
array[0]的时候由于没有创建array数组,array是个空对象,程序中调用array[0]就会产生object is null的异常


catch(err)语句捕获到这异常通过err.name打印了错误类型,err.message打印了错误的详细信息。比如变量或函数undefined异常等。


finally类似于java的finally,无论有无异常都会执行.


现总结Error.name的六种值对应的信息:
EvalError:eval()的使用与定义不一致
RangeError:数值越界
ReferenceError:非法或不能识别的引用数值
SyntaxError:发生语法解析错误
TypeError:操作数类型错误
URIError:URI处理函数使用不当 


throw语句说明
throw语句在javascript1.4中已经实现。try的语法很简单,如下 throw expression;
其中的expression可以是任何一种类型,也就是说throw "There is a error" 或是throw 1001都是正确的。但通常我们会抛出一个Error对象或是Error对象的子类。关于Error我们稍后介绍,先看一段throw的样例代码。
例如:
function factorial(x) {
    // If the input argument is invalid, throw an exception!
    if (x < 0) 
throw new Error("x must not be negative");
    // Otherwise, compute a value and return normally
    for(var f = 1; x > 1; f *= x, x--) /* empty */ ;
    return f;
}


Error对象
Error对象和它的子类是在javascript1.5中实现的。Error的构造函数有两种
    new Error( )
    new Error(message )
Error有两个基本的属性name和message。message用来表示异常的详细信息。而name指的的是Error对象的构造函数。
此外,不同的js引擎对Error还各自提供了一些扩展,例如mozilla提供了fileName(异常出现的文件名称)和 linenumber(异常出现的行号)的扩展,而IE提供了number(错误号)的支持。不过name和message是两个基本的属性,在 firefox和ie中都能够支持。Javascript中Error还有几个子类EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError。




Javascript的异常处理机制和window.onerror句柄
当javascript代码中出现错误的时候,js引擎就会根据js的调用栈逐级寻找对应的catch,如果没有找到相应的catch handler或catch handler本身又有error或者又抛出新的error,最后就会把这个error的处理交给浏览器,浏览器会用各自不同的方式(IE以黄色三角图案显示在左下角,而firefix会显示在错误控制台中)显示错误信息给访问者。


javascript的window对象有一个特别的属性onerror,如果你将某个function赋值给window的onerror属性,那么但凡这个window中有javascript错误出现,该function都会被调用,也就是说这个function会成为这个window的错误处理句柄。
// Display error messages in a dialog box, but never more than 3
window.onerror = function(msg, url, line) {
    if (onerror.num++ < onerror.max) {
        alert("ERROR: " + msg + "\n" + url + ":" + line);
        return true;
    }
}
onerror.max = 3;
onerror.num = 0;
onerror句柄会3个参数分别是:错误信息提示,产生错误的javascript的document url,错误出现的行号。


onerror句柄的返回值也很重要,如果句柄返回true,表示浏览器无需在对该错误做额外的处理,也就是说浏览器不需要再显示错误信息。而如果返回的是false,浏览器还是会提示错误信息。
0 0
原创粉丝点击