JavaScript面向对象的简单介绍

作者:killercat 来源:killercat 时间:2008-06-27 12:37:00 

JavaScript是一门OOP,而有些人说,JavaScript是基于对象的。

1) 如何创建对象:

1. 使用constructor,例如:

var obj = new Object() // var 可以省略
var obj = new Date() 

2. 使用对象字面值(object literals),例如:

程序代码

var obj = "123" // 创建一个String对象
var obj = /^abc$/ //创建一个RegExp对象

更加复杂的情况是,我们可以直接生成一个自定义的只有属性的对象:

程序代码

var obj = {
name:"killercat",
home:"www.i170.com/user/killercat"
}
document.write(obj.name+"<br />")
document.write(obj.home)

结果:
killercat
www.i170.com/user/killercat



2) JavaScript中的属性:

str = "www.i170.com/user/killercat" // str 一个字符串对象的引用
document.write(str.length)

通过对象的引用加上"."再加上属性名,可以访问到这个属性,也可以修改这个属性,甚至是添加一个属性,比如:

var obj = new Object()
obj.name = "killercat"  // 为对象直接添加一个属性
document.write(obj.name) // 访问对象的属性
obj.name = "kcat" // 修改对象的属性
document.write(obj.name)

枚举属性值:

使用 for ... in 语句可以枚举属性(具体来说就是枚举属性名),前面已经提到过,比如

for(ele in window){
    document.write(ele+"<br />")
}

如何得到属性值?

obj = new Object()
obj.p1 = "a"
obj.p2 = "b"
obj.p3 = "c"
for(ele in obj)
    document.write(obj.ele)  // 这是新手可能犯的错误,obj.ele 的值是undefined

应该这样访问属性值:

document.write(eval("obj."+ele))

未定义的属性:

obj = new Object()
document.write(obj.name)

结果是:undefined

删除属性:

obj = new Object()
obj.name = "killercat"
delete obj.name
document.write(obj.name)

结果是:undefined

理解属性:

我们知道在Java,c++中,属性要么属于某个类(类属性或说是静态属性),要么属于对象,也就是说,同一个类的对象,一定有一样的属性,但是JavaScript不一样,同样是Object的对象,却可以有不同的属性。除了这类的属性,JavaScript中还有静态的属性(变量)。

3) Constructor

源于某些未知原因,有些人似乎不愿意在JavaScript提到classes这个词,取代的是"对象的类型(object types)",甚至有些人直接叫函数,于是可以看见这样的说法:“我们通过预先定义好的函数,产生了一个对象”。本文使用类,这个名词。

JavaScript 定义方法的方式和定义类的方式一模一样:

function User(name,sex){ // 定义了类 User
    this.name = name;
    this.sex = sex;
}
user = new User("kc","man")
document.write(user.name+"<br />"+user.sex)

contructor的作用就是在初始化属性(变量)

4) 方法

源于某些未知原因,有些人似乎不愿意在JavaScript

以下例子引用于<<__JavaScript: The Definitive Guide>>

function Rectangle_area(  ) { return this.width * this.height; }
function Rectangle_perimeter(  ) { return 2*this.width + 2*this.height; }
function Rectangle_set_size(w,h) { this.width = w; this.height = h; }
function Rectangle_enlarge(  ) { this.width *= 2; this.height *= 2; }
function Rectangle_shrink(  ) { this.width /= 2; this.height /= 2; }
function Rectangle(w, h)
{
    this.width = w;
    this.height = h;
    this.area = Rectangle_area;
    this.perimeter = Rectangle_perimeter;
    this.set_size = Rectangle_set_size;
    this.enlarge = Rectangle_enlarge;
    this.shrink = Rectangle_shrink;
}

这种风格可能和Java,c++很不同。方法中的this表示调用它的对象的引用。

5) prototype

prototype是一个对象,每个类都包含一个prototype对象(注意,每个类一个,而不是每个对象一个)。
看看下面的例子:

function User(name)
{
    this.name = name
}
User.prototype.name = "killercat"  // 类名.prototype.属性(或方法)
user = new User("who"+"<br />")
document.write(user.name)
delete user.name
document.write(user.name)

再看一个例子:

function User(name)
{
}
User.prototype.name = "human"
user1 = new User()
user2 = new User()
document.write(user1.name+"<br />")
document.write(user2.name)

结果:
human
human

说明了,每个类一个prototype对象,而不是每个对象单独一个。

obj.x 这条语句的查找顺序是,先在obj中找x属性,假如没有,再进入obj对应的类中找prototype.x,对于方法来说,也一样。因此,不要出现这样的语句: user.prototype.name = "xxx" 必须是 user.name = "xxx" (prototype对象属于一个类,而不是一个对象)

类名.prototype.属性  // 相当于一个实例变量(属性),对方法也一样
类名.属性  // 相当于一个静态变量(属性),对方法也一样,调用的时候必须使用"类名.属性",不能使用"类对象.属性",因为它属于一个类,而不是一个对象。
例如:

function User(name)
{
    this.name = name
}
User.type = "human"
user = new User("kc")
document.write(User.type + "<br />")
document.write(user.type)

结果:
human
undefined

另外,每个prototype都有一个constructor属性,默认用于保存constructor的定义,例如上面的user对象,调用:

user.constructor得到:

function User(name) { this.name = name; }

我们可以通过typeof,知道参数的类型,假如是对象,就返回"object",假如是方法就返回"function"

6) 利用prototype实现类间的继承,例如:

// 父类
function Circle(r){
    this.r = r;
   
}
Circle.PI = 3.14;
Circle.prototype.getArea = function (){   
    return Circle.PI * this.r * this.r;
};
Circle.prototype.toString = function (){   
    if(( typeof this == "object") && (this.constructor == Circle)){
        return "circle with a radius " + this.r ;
    }
    else{
        return "unknown object";
    }   
};
Circle.max = function (c1,c2){
    return c1.r >= c2.r ? c1 : c2;
};
// 子类
function ColorCircle(r,color){
    this.r = r;
    this.color = color;
}
ColorCircle.prototype = new Circle(0);  // 保存父类的对象
ColorCircle.prototype.constructor = ColorCircle;  // 为constructor 改名字
ColorCircle.prototype.toString = function(){
    if(( typeof this == "object") && (this.constructor == ColorCircle)){
        return this.color+" circle with a radius " + this.r ;
    }
    else{
        return "unknown object";
    }   
}
ColorCircle.prototype.getColor = function(){
    return this.color;
}
ColorCircle.prototype.setColor = function(color){
    this.color = color;
}

 也就是,使用prototype保存父类的对象,在构造子类的时候,父类对象同时被构造(因为prototype被构造)。也就是JavaScript继承其实就是让子类的prototype对象保存父类的对象。

标签:面向对象,javascript,编程
0
投稿

猜你喜欢

  • ASP 操作cookies的方法

    2011-03-10 11:24:00
  • 垂直栅格与渐进式行距(下)

    2009-07-09 16:52:00
  • 自适应浏览器位置的div效果

    2008-05-29 13:15:00
  • 支持中文的Len, Left, Right函数

    2008-03-18 13:50:00
  • Sql server 2005 找出子表树

    2008-11-24 15:23:00
  • MySQL 连接与管理

    2011-09-10 15:52:42
  • ASP实例:处理多关键词查询实例代码

    2008-11-24 12:56:00
  • AspJpeg 2.0组件使用教程(GIF篇)

    2008-12-16 19:37:00
  • JavaScript 中为 Date 类实现 DateAdd 方法

    2008-04-03 16:19:00
  • 关于 Web 字体:现状与未来[译]

    2009-11-24 13:50:00
  • 使用ewebeditor可能会重复提交数据两次的解决办法

    2009-01-09 12:41:00
  • Yahoo!网站性能最佳体验的34条黄金守则——JavaScript和CSS

    2008-05-29 13:34:00
  • CSS3的新特性

    2009-03-23 17:46:00
  • 分类、属性、关键词与Tag

    2009-08-27 12:57:00
  • 如何确定Oracle数据库表重复的记录

    2010-07-26 13:23:00
  • Instr函数与InstrRev函数的区别

    2008-07-07 16:53:00
  • CSS Hack经验总结

    2008-05-01 13:13:00
  • ASP程序直接连接MYSQL数据库

    2008-10-03 12:13:00
  • 如何从SQL数据库中调用图片?

    2009-11-15 19:59:00
  • SQL Server命令行导数据的2种方式

    2010-07-26 14:48:00
  • asp之家 网络编程 m.aspxhome.com