Ruby / JS实例变量范围之间的区别

时间:2012-11-26 09:52:52

标签: javascript ruby

尝试学习Ruby,在教程中,我在page上看到了这段代码:

class Greeter
  def initialize(name = "World")
    @name = name
  end
  def say_hi
    puts "Hi #{@name}!"
  end
  def say_bye
    puts "Bye #{@name}, come back soon."
  end
end

我还被告知@name变量是一个实例变量,它的作用域是类中的所有方法(在本例中为Greeter)。我对JS很熟悉,并且在范围界定方面有点混乱。让我澄清一下。以下是我对JS中代码的理解:

function Greeter (name){
    name = (typeof name === "undefined") ? "World" : name;

    function say_hi (name){
        alert('Hi ' + this.name);
    };

    function say_bye (name){
        alert('Bye ' + this.name + ', come back soon.');
    };
};

所以在ruby示例中,似乎有一个名为initialize的方法,我想在ruby中,他们可以在参数中定义变量吗?在initialize中,它定义了var @name。在JS示例中,我通过将name声明为名称WITHIN this.name&来明确地抽象var say_hi的命名。 say_bye。我理解这是良好的编码实践,以区分范围,即使在这种情况下name在整个代码中保持相同,如果传递空参数则为“世界”,或者传递的人的名称作为参数。无论哪种方式,我都不确定Ruby中的作用域是如何工作的,因为我不知道这在JS中是可行的。获取上面的JS代码,并将其与以下内容进行比较:

function Greeter (name){

    function say_hi (name){
        this.name = (typeof name === "undefined") ? "World" : name;
        alert('Hi ' + this.name);
    };

    function say_bye (name){
        this.name = (typeof name === "undefined") ? "World" : name;
        alert('Bye ' + this.name + ', come back soon.');
    };
};

如果我未能在子方法中声明this.name,则可能表示Greeter类变量name,而不是say_hisay_bye变量name

问题:

1 - 是@@name所需的能力,以便能够让类中的所有方法都可见,或者这个惯例是什么?如果是惯例,@表示什么? (我将此等同于JQuery中声明为$this的变量,其中表示变量是JQuery元素,与$('whatever')查询时不同

2 - 方法initialize的作用类似于Greeter类中的getter / setter方法吗?

3 - 非常欢迎您对我的逻辑,代码和问题的假设做出任何其他评论!

2 个答案:

答案 0 :(得分:1)

@与javascript中的this大致相同,它指的是当前实例。类中的initialize方法是构造函数,而不是getter / setter。

function Greeter( name ) { 
    /*Functions called with `new` return objects
     with their proto link pointing to the object
     pointed at function's .prototype property at the time of instanciation. */
    this.name = arguments.length < 1 ? "World" : name; //No real way to do optional arguments
}

Greeter.prototype.say_hi = function() {
    alert( "Hi " + this.name + "!" ); //Methods are defined outside on the `.prototype` object
};

Greeter.prototype.say_bye = function() {
    alert( "Bye " + this.name + ", come back soon." );
};

答案 1 :(得分:0)

  1. @必须将@name声明为实例变量,在js中声明为{name : 'foo'};
  2. initialize的行为类似于Constructor中的new Constructor(foo, bar)。在new Constructor(foo, bar)时,ruby将使用参数Constructor#initializefoo调用bar
  3. 我认为将js与红宝石进行比较并不是最好的选择。 ruby是基于类的OOP,类似于C ++和Java。