Ruby和JavaScript对象模型的比较

概要

Ruby和JavaScript都是动态脚本语言,他们有许多地方是类似的。比如函数都是一等对象,都有高阶函数等等。。。但是我觉得最像的要属他们的对象模型,比如:他们的类型不伦不类,对象非要搞得像一个属性槽。

Ruby的对象模型

Ruby,一种为简单快捷面向对象编程而创的脚本语言。 他的最大的特点就是面向对象的模型和元编程的能力,Ruby是完全面向对象的,没有任何的原始类型。要注意的是:Ruby是一门正统的面向对象的编程语 言,而JavaScript就不是。如果用一句话来说Ruby的对象模型就是类即使类也是对象,而对象即使对象也是一个Hash。怎么能怎么说呢?首先看 一看类就是类
class MyClass
  def the_method
    "general method"
  end
end
mc = MyClass.new
mc.the_method

正统的创建类和对象的语法,可以直接翻译成Java代码。但是Ruby的类不仅仅存在于静态的源文件中,他还存在于运行时。因为Ruby的一个类就是Class的一个对象,同时他还是Object的一个子类。好奇葩吧!看代码

[ruby][/ruby] view plaincopyprint?
  1. <pre name=”code” class=”ruby”><pre name=”code” class=”ruby”>C = Class.new
  2. D = Class.new(C) {
  3.     include M
  4.     def the_method
  5.     “general method”
  6.     end
  7. }</pre></pre>

这儿不仅仅可以用创建对象的方法来生成类,还可以实现继承和定义类体。这儿还有更加令人惊讶的,由于类是Class的一个对象,因此类的方法就是 Class的实例方法。而Class继承了Module,Module继承了Object,Object混入了Kernel模块(Object也是一个 类,鸡生蛋还是蛋生鸡?)。因此他们的实例方法都是类的类方法(也叫单例方法),相当于Java的静态方法。

接下来看看对象是一个属性槽。
[ruby][/ruby] view plaincopyprint?
  1. o = Object.new
  2. o.instance_variable_set(:@x, 0) # Note required @ prefix
  3. o.instance_variable_get(:@x) # => 0
  4. o.instance_variable_defined?(:@x) # => true
  5. Object.class_variable_set(:@@x, 1) # Private in Ruby 1.8
  6. Object.class_variable_get(:@@x) # Private in Ruby 1.8
  7. Object.class_variable_defined?(:@@x) # => true; Ruby

除去多余的语法,可以看到一个对象就像一个哈希表那样应付着外界的拷问。下面给这个哈希表添加一个属性。

[ruby][/ruby] view plaincopyprint?
  1. class ClassMethodExample
  2.   def self.foo
  3.     puts ‘class foo’
  4.   end
  5.   class << self
  6.     def bar
  7.       puts ‘class bar’
  8.     end
  9.   end
  10. end
  11. class << ClassMethodExample
  12.   def baz
  13.     puts ‘class baz’
  14.   end
  15. end
  16. def ClassMethodExample.tor
  17.   puts ‘class tor’
  18. end
  19. ClassMethodExample.foo
  20. ClassMethodExample.bar
  21. ClassMethodExample.baz
  22. ClassMethodExample.tor
这就是给类添加类方法的语法(悄悄告诉你:类方法可以被继承),对于纯正的对象也可以定义对象的实例方法。
[ruby][/ruby] view plaincopyprint?
  1. class Person
  2.   def talk
  3.     puts “This is a Person class.”
  4.   end
  5. end
  6. p1=Person.new
  7. p2=Person.new
  8.  #定义单例方法,首先要生成一个实例对象,其次,要在方法名前加上对象名和一个点号“.”
  9.  def p2.talk
  10.    puts “This talk method belongs to p2.”
  11.  end
  12.  def p2.laugh
  13.    puts “laugh method belongs to p2.”
  14.  end
  15.  p1.talk #This is a Person class.
  16.  p2.talk #This talk method belongs to p2.
  17.  p2.laugh #laugh method belongs to p2.

这就让人不得不想到JavaScript的创建对象的语法

[javascript][/javascript] view plaincopyprint?
  1. var person = new Object();
  2. person.name = “Nicholas”;
  3. person.age = 29;
  4. person.job = “Software Engineer”;
  5. person.sayName = function(){
  6.     alert(this.name);
  7. };

下面就来介绍一下JavaScript的对象模型

JavaScript对象模型

JavaScript,一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。注意这儿的原型,原型的意思就是这里没有类只有对象,对象生对象。其实JavaScript还有一些好兄弟,其中就有一个Io(上Google上看看Io Language)。看一下Io创建一个对象的方法
[cpp][/cpp] view plaincopyprint?
  1. Account := Object clone
  2. Account balance := 0
  3. Account deposit := method(amount,
  4.     balance = balance + amount
  5. )
  6. account := Account clone
  7. account deposit(10.00)
  8. account balance println

看看这人的clone和new有多像吧,在原型式编程中对象是克隆的。但是总要有一个地方来共享所有的对象所共有的东西吧。因此,在Io中,一大写字母开 头对象就代表一个类型;而在JavaScript中就有了Prototype,也叫原型。我觉得JavaScript中的原型就是一个类,在原型上定义的 所有方法和属性都会共享。每一个对象也可以有其自己的自定义方法,一旦在对象上定义的方法或者属性和在Prototype定义的同名时,对象上的定义就会覆盖在Prototype上的定义。

[javascript][/javascript] view plaincopyprint?
  1. function Person(){
  2. }
  3. Person.prototype.name = “Nicholas”;
  4. Person.prototype.age = 29;
  5. Person.prototype.job = “Software Engineer”;
  6. Person.prototype.sayName = function(){
  7.     alert(this.name);
  8. };
  9. var person1 = new Person();
  10. var person2 = new Person();
  11. person1.name = “Greg”;
  12. alert(person1.name);//”Greg” – from instance
  13. alert(person2.name);//”Nicholas” – from prototype
  14. delete person1.name;
  15. alert(person1.name);//”Nicholas” – from the prototype

总之:在Ruby中,一个类是一个Class类的实例,也就是说:一个类就是一个对象,事实上累还是一个常 量。既然类也是对象,那么类也可以用Class及其父类中的实例方法。而这些实例方法的定义都是对象通用的方法,这也是为什么类和对象有时会有相等的操 作。同时这也导致了一些方法的差异。比如类上作用的是类方法,而对象上作用的是实例方法。在JavaScript中,JavaScript统一了函数和类 型变量,认为他们都存在于一个容器中,这个容器就叫属性。因此一个对象 就可以认为是一个无序的属性列表。另外一个属性也可以简单的看作一个名字和他的值构成(当然不止这么简单)。这样一个对象也可以看作一个哈列表。

标签