javascript - 鸭子类型(duck typing) : Translating Ruby Code into Javascript Utilizing Duck Typing

标签 javascript ruby oop duck-typing

这是《Practical Object-Oriented Design in Ruby》书中的一个示例。我有兴趣将这个 ruby​​ 代码翻译成 javascript,以便更好地理解 JS 中的鸭子类型(duck typing)。谁能帮助翻译这段代码,以阐明如何最好地用 Javascript 编写这段代码,或者至少帮助我开始?

这里的行程类充当其他类(Mechanic、Trip_Coordinator、Driver)的接口(interface)。其中Trip类中的prepare方法使用Duck类型的准备器。

class Trip
    attr_reader :bicycles, :customers, :vehicle

    def prepare(preparers)
      preparers.each {|preparer|
         preparer.prepare_trip(self)}
    end
 end

class Mechanic
  def prepare_trip(trip)
    # Does something with trip.bicycles
  end
end


class Trip_Coordinator
  def prepare_trip(trip)
    # Does something with trip.customers
  end
end

class Driver
  def prepare_trip(trip)
    # Does something with trip.vehicle
  end
end

更新:

我添加了我认为可能是上面 Ruby 代码的翻译的代码。但是,当我运行代码时,我得到以下输出和错误:

mountain
2
jeep

/home/ubuntu/user/tests/trip.js:3
       preparer.prepare_trip(this)

TypeError: Object [object Object] has no method 'prepare_trip'

为了进一步提高对 JS 中鸭子类型(duck typing)的理解,我们将不胜感激。

Javascript代码:

var Trip = function(preparers){
    return preparers.forEach(function(preparer){
       preparer.prepare_trip(this)
    }
)};

var Mechanic = function(trip){
    // does something with trip.bicycles                                                                                                                                                           
    prepare_trip: console.log(trip.bicycles);
};

var TripCoordinator = function(trip){
    //does something with trip.customers                                                                                                                                                           
    prepare_trip: console.log(trip.customers);
};

var Driver = function(trip){
    //does something with trip.vehicle                                                                                                                                                             
    prepare_trip: console.log(trip.vehicle);
};

// customer wants to go on a trip for two and needs a car                                                                                                                                          
var planA = {
    bicycles: "mountain",
    customers: 2,
    vehicle: "jeep"
};

//customer wants to go a trip for one and only ride a bike                                                                                                                                         
var planB = {
    bicycles: "road",
    customers: 1
};

Trip([new Mechanic(planA), new TripCoordinator(planA), new Driver(planA)]);
Trip([new Mechanic(planB), new TripCoordinator(planB)]);

更新2

根据下面 fgb 的解决方案和建议,我在下面列出了我的问题的最终解决方案。我添加了一个代理,以消除调用者在创建旅行计划时必须知道他们需要做什么准备的依赖。

var Agent = function(plan){
    if("bicycles" && "customers" && "vehicle" in plan){
        Trip([new Mechanic(plan), new TripCoordinator(plan), new Driver(plan)]);
    }
    else if(!("vehicle" in plan) && "bicycles" && "customers" in plan){ //A driver is not needed                                                                                                                                        
        Trip([new Mechanic(plan), new TripCoordinator(plan)]);
    }
};

var Trip = function(preparers){
    return preparers.forEach(function(preparer){
       preparer.prepare_trip(this)
    }
)};
var Mechanic = function(trip){
    // does something with trip.bicycles                                                                                                                                                           
    this.prepare_trip = function() {
        console.log(trip.bicycles);
    }
};

var TripCoordinator = function(trip){
    //does something with trip.customers                                                                                                                                                           
    this.prepare_trip = function() {
        console.log(trip.customers);
    }
};

var Driver = function(trip){
    //does something with trip.vehicle                                                                                                                                                             
    this.prepare_trip = function() {
        console.log(trip.vehicle);
    }
};

// customer wants to go on a trip for two and needs a car                                                                                                                                          
var planA = {
    bicycles: "mountain",
    customers: 2,
    vehicle: "jeep"
};

//customer wants to go a trip for one and only ride a bike                                                                                                                                         
var planB = {
    bicycles: "road",
    customers: 1
};

Agent(planB);

相关SO讨论Example of Javascript Duck Typing?

最佳答案

代码几乎是正确的,但是您混淆了构造函数和对象文字的语法。当你这样做时:

var Driver = function(trip){
    //does something with trip.vehicle                                                                                                                                                             
    prepare_trip: console.log(trip.vehicle);
};

“prepare_trip:”实际上是 label ,并且不定义对象的属性。

解决这个问题的一种方法是:

var Driver = function(trip){
    //does something with trip.vehicle                                                                                                                                                             
    this.prepare_trip = function() {
        console.log(trip.vehicle);
    };
};

另请注意,该代码与 Ruby 代码并不完全相同:

preparer.prepare_trip(this);

这里,this是全局对象而不是行程对象,并且方法中没有使用该参数。在您的代码中,行程参数改为在准备器的构造函数中传递。

关于javascript - 鸭子类型(duck typing) : Translating Ruby Code into Javascript Utilizing Duck Typing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26188802/

相关文章:

java - 无法访问 struts 操作类中的 JSON 请求对象

ruby - Ruby 的 PostgreSQL 适配器的正确名称是什么?

ruby - 方法如何在 Ruby 中使用散列参数?

ruby-on-rails - 停止 AASM 过渡的最佳方法是什么

php - 将 mysql 结果与 php 类一起使用的最有效方法

java - 在 Java 中从外部访问父类(super class)

javascript - AngularJS - 如何使用 $routeParams 生成 templateUrl?

javascript - 组合 JS 库

javascript - 在Panorama GUI中找到三个JS坐标?

javascript - 除了JS之外,其他语言是否按照加载顺序执行代码?