JavaScript中的自定义对象(custom Object)和继承(inheritance)

快速浏览一下JavaScript,发现它还是和c++这类传统一点的语言有很大不同。本文着重描述一下custom Object和inheritance(我是JavaScript新手,没有用过JavaScript)

我不喜欢开门见山,所以我想一点点地举例,引入说明这两个问题。

1、JavaScript中的类型系统

JavaScript中有五种类型的变量:boolean, number, string, object, function。有趣吧,function也是一种类型。

在JavaScript中,一切皆对象。这和Python的思想是一样的。看来这类动态脚本语言都是差不多的。

1.3333333.toFixed(2) // ’1.33’
7..toString() // ’7’

必要时,boolean, number, 和string都可以隐式转换为Object。这是需要调用全局的特殊构造函数,然后手工调用之:

typeof 1. // ’number’
typeof new Number(1.) // ’object’
typeof new String(’Hi!’) // ’object’

函数是一种特殊的对象(Object)。与其他对象不同的是,它可以被调用。属性可以动态添加到函数上:

function f(x) { return f.A x * x }
f.A = 2.7
function Buffer() {}
Buffer.MAX_LINE_LENGTH = 4096

通常这类属性作为全局常量,因此写成大写比较好。


2、 对象和函数

对象创建有两种方法:对象文字和new运算符

使用对象文字创建对象:

var p = { x: 0.1, y: 0.2 }

对象就是属性的动态集合(set)。新的属性可以通过赋值运算符添加进去。也可以使用delete运算符删除之。可以使用in运算符查询属性:

’z’ in p // false
p.z = 0.3 // introduce new property ’z’
’z’ in p // true
delete p.z // remove ’z’ from p
p.z // undefined

属性的值可以是任意一种类型,包括function类型。当一个函数(function)当做方法(method)被调用时,他会隐含得到一个this参数,指向function对象:

p.move = function(x, y) {
this.x = x
this.y = y
}
p.move(1, 1) // invoke a method

3、基于原型(prototype)的继承

创建对象的第二种方法就是使用new运算符,new后面跟着构造函数。

var p = new Object
p.x = 0.1
p.y = 0.2

这个new运算符分配空间给新的对象,并且调用所给出的构造函数(这里就是Object构造函数)初始化这个对象。构造函数传递新创建的对象作为隐含的this参数。

在JavaScript中没有类这个概念,但是有构造函数。通常,构造函数的首字母大写,用来区分普通的函数:

function Point(x, y) {
this.x = x
this.y = y
}
var p = new Point(1, 2)

在JavaScript中只要和new结合的函数都是构造函数。为了支持继承,每个函数都有一个默认的属性prototype。使用构造函数对象创建时从构造函数的prototype中继承了所有的属性:

function Point(x, y) {
this.x = x
this.y = y
}
Point.prototype = new Object // can be omitted here
Point.prototype.translate = function(dx, dy) {
this.x += dx
this.y += dy
}

首先,定义构造函数Point用来初始化point对象。然后给构造函数的prototype添加添加一个空对象。被point对象所共享的属性应该赋给prototype。这个例子中,我们添加了translate方法给prototype,所有point对象都可以使用prototype了:

var p0 = new Point(1, 1)
var p1 = new Point(0, 1)
p1.translate(1, -1)
p0 === p1 // false
p0.translate === p1.translate // true

p1和p2有他们自己的属性x和y,但是他们共享translate方法。当对象根据属性名查询属性值时,JavaScript引擎首先查看当前对象自己的属性,如果没有找到,继续查找对象的prototype。每个对象都有构造函数的prototype的一份拷贝。

下面我们使用构造函数进行继承:

function Point(x, y) {
this.x = x
this.y = y
}
Point.prototype = {
move: function(x, y) {
this.x = x
this.y = y
},
translate: function(dx, dy) {
this.x += dx
this.y += dy
},
area: function() { return 0; }
}
function Ellipsis(x, y, a, b) {
Point.call(this, x, y)
this.a = a
this.b = b
}
Ellipsis.prototype = new Point
Ellipsis.prototype.area = function() { return Math.PI this.a * this.b; }
function Circle(x, y, r) {
Ellipsis.call(this, x, y, r, r)
}
Circle.prototype = new Ellipsis

这里我们建立三个构造函数:Point, Ellipsis, Circle。每个构造函数都设置prototype。对象中的属性的继承主要靠这个prototype。下面看看circle对象时怎么找到move属性的:

var circle = new Circle(0, 0, 1)
circle.move(1, 1)

首先,JavaScript引擎在circle对象中查找move属性,发现没有,那好,就去找circle的prototype吧。而circle的prototype是Ellipsis构造函数构造的,他也没有prototype属性。继续查找Ellipsis的prototype,这个prototype是Point构造的,在point中发现了move属性,这才调用上move。看起来好艰辛噢。这种内部prototype引用称作prototype chain。


4、JavaScript中的数据封装。

function Point(x, y) {
this.getX = function() { return x; }
this.setX = function(x2) { x = x2; }
this.getY = function() { return y; }
this.setY = function(y2) { y = y2; }
}

当Point构造函数被调用时,对象创建了get方法和set方法。在这两个方法的作用域内可以可以访问Point构造函数的作用域内的x和y成员。只有getter和setter才能访问x,y,除此之外别无他法。这就是JavaScript中的私有成员机制,表现出了数据封装的作用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值