`
ericyang
  • 浏览: 5937 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

浅谈JavaScript的面向对象机制

阅读更多
一 引言

    面向对象(Object Oriented 简称OO)的定义是:按人们认识客观世界的系统思维方法,采用基于对象的概念建立的模型,模拟客观世界分析,设计,实现软件的办法。通过面向对象的理念是计算机软件系统能与现实世界中的系统一一对应。
二 面向对象的javaScript

    虽然js支持面向对象机制,但是它并没有正式的类的概念,这使她有别于那些经典的面向对象程序设计语言,如C++和JAVA等。在面向对象的程序设计语言中,共有的概念是强类型和支持以类为基础的继承机制。根据这个判定,很容易将js从真正的面向对象语言中分离出来。但是,我们又发现js中大量的使用了对象,而且还有基于原型链的继承机制,这些又说明js是一种真正的面向对象的语言。可以说,js不是传统的以类为基础的面向对象语言,js的面向对象是通过构造函数和原型对象来模拟典型面向对象所拥有优良特性。比如设计模式。
三 构造函数

    js可以像java一样用new关键字和预定义的构造函数创建并初始化一个新对象,依靠的是js的函数特性。js采用的是函数式编程,函数具有对象的特性,这点儿将在《浅谈JavaScript的函数特性》中解释。构造函数是具有两个特性的JavaScript函数:
1 由new运算符调用
2 传递给它的是一个对新创建得空对象的引用,该引用作为关键字this的值,而且还要对新创建的对象适当的初始化。如:
// 定义构造函数. 
// 注意它在初始化的时候怎样将引用传给this
function Rectangle(w, h)
{
    this.width = w;
    this.height = h;
}
// 初始化对象,并将每个对象的高度和宽度传递给构造函数
var rect1 = new Rectangle(2, 4);
var rect2 = new Rectangle(8.5, 11);

    注意构造函数如何使用它的参数来初始化this关键字所引用的对象的属性,记住,构造函数只是初始化了特定的对象,但并不返回这个对象。

四 对象成员
   
     一个java类的成员有四种:实例属性,实例方法,类属性,类方法。js可以通过原型对象来实现。

function Circle(radius) {   // 用构造函数来模拟类定义!
    // 实例属性的定义方法,虽然js中任何对象属性都是实例属性,而且Js对象属性可以动态声明,但为了真实的模拟面向对象语言,我们说js中的实例属性就是构造函数创建和初始化的属性。
    this.r = radius;
}

// 类属性的定义方法,Circle是构造函数,但js里函数就是对象,所以创建构造函数的属性,就像创建对象的属性方法一样,并且模拟了类属性和对象无关,通过类存取的特性!
Circle.PI = 3.14159;
 
// 实例方法的定义方法,原型对象是该类的副本对象,并在声明构造函数时初始,保持与父类的一个引用,可以修改,也可以用this.method在构造函数中定义实例方法,但是这样每声明一个对象引用,就要初始化这些方法,效率低。所以利用原型链线性搜索机制,先找this.method无果的情况下,接着寻找Class.prototype.method并找到该方法,如果还未定义的话,就寻找父类的prototype.method直到Object类
所以可以看出原型对象可以很好的模拟继承。
Circle.prototype.area = function (){ return Circle.PI * this.r * this.r; }

// 类方法的定义方法,类比类属性,js中函数也有自己的方法。
Circle.max = function(a,b) {
    if (a.r > b.r) return a;
    else return b;
};

// Here is some code that uses each of these fields:
var c = new Circle(1.0);      // Create an instance of the Circle class.
c.r = 2.2;                    // Set the r instance property.
var a = c.area();             // Invoke the area() instance method. 
var x = Math.exp(Circle.PI);  // Use the PI class property in our own computation.
var d = new Circle(1.2);      // Create another Circle instance.
var bigger = Circle.max(c,d); // Use the max() class method.

为了和java对比,将上述Circle类定义用java重写。

class Circle {
Circle(float radius){
this.r = radius;
}
Static final PI = 3.14159;
float area(){
return this.r*this.r*Circle.Pi;
} 
Static final Circle max(Circle c1,Circle c2){
if(c1.r>c2.r) return c1;
else return c2;
}
public static void main(String[] args) {
Circle c = new Circle(1.0);
c.r = 2.2;
float a = c.area();
Circle b = enw Circle(2.0);
Circle bigger = Circle.max(c,b);
}
}


五 继承
    上面提过原型对象可以很好的实现继承机制,只要在定义了子类的构造函数之后,将子类的原型对象从Object对象的引用改为要继承的父类即可。
   
<script type="text/javascript">
  var Name = function(name){
    this.name = name;
  };
  Name.prototype.getName = function(){
    alert(this.name);
  };
  var Fish = function(name,age){
    Name.call(this,name);//调用父类的构造函数
    this.age = age;
  };
  Fish.prototype = new Name();
  Fish.prototype.constructor = Fish;//因为采用父类的引用,多复制了父类的构造信息,所以要重新定义构造信息。
  Fish.prototype.showInfo = function(){
   alert(this.age);
  }
  var ioldFish = new Fish("老鱼",27);
  ioldFish.getName();
</script>



六 尾声
    另外,类似java,Object是js中所有对象的父类,js在Object定义很多类似java的方法,像toString(),valueOf()等等,这样通过原型对象继承起来的所有js对象都有了这些有用地方法,也可以自己修改。
    总之,js是通过构造函数和原型对象来模拟成为java那样的面向对象语言。
2
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics