javascript对象是否像Ruby一样“开放”?

时间:2013-06-26 20:52:12

标签: javascript google-apps-script

在Ruby中,我可以使用与声明我自己的语法相同的语法来添加和修改任何类,对象或方法的功能,因为Ruby具有“开放类”。

javascript是这样的吗?

作为一个例子......

就我而言,我想改变Google Apps脚本处理网址对象的方式,这样每次评估网址对象时,网址对象本身都会确保它以协议开头://(默认情况下为http://) )。

4 个答案:

答案 0 :(得分:3)

是的,您可以自由修改对象。您可以修改特定对象Object.overridenProperty = ...,或通过其prototype属性Object.prototype.inheritedMethod = ...修改从给定派生的所有对象。

请记住,重新定义方法可能很棘手,因为新定义不会与原始定义共享相同的范围:

var BaseClass;

(function(){
    var defaults = { ... };

    BaseClass = function(){
        this.someValue = defaults.someValue;
    };
}());

也可能发生类定义位于闭包内,并且您没有实际的方法来覆盖方法或属性,因为它生成了JIT。在这种情况下,您需要覆盖您感兴趣的每个对象的属性:

(function(){
    var defaults = { ... },
    BaseObject = (function(){
        var obj = function(){
            this.someValue = defaults.someValue;
        };

        return obj;
    }());
}());

答案 1 :(得分:2)

需要注意的是,如何定义“类”与Ruby相比有很大不同。但是你可以达到同样的效果。

这个红宝石:

#ruby
class Foo
  # no methods yet
end

foo = Foo.new

class Foo
  def bar
    'bar'
  end
end

foo.bar #=> 'bar'

将具有此等效的JavaScript实现:

// js
var Foo = function() {};

var foo = new Foo();

Foo.prototype.bar = function() {
  return 'bar';
};

foo.bar(); // 'bar'

您甚至可以轻松覆盖事物:

var oldBar = Foo.prototype.bar;
Foo.prototype.bar = function() {
  return "Called oldBar and got: "+ oldBar.call(this);
};

foo.bar(); // "Called oldBar and got: bar"

答案 2 :(得分:1)

使用getter和setter查看此类:

function User(){
this._name = "";
}
User.prototype.setName = function(name){this._name = name;}
User.prototype.getName = function(){return this._name;}
user = new User();
user.setName("somename");
alert(user.getName(););

JSfiddle Example

答案 3 :(得分:1)

您在问题中特别提到了Google Apps脚本。由于GAS是variant of JavaScript,因此对象定义和扩展的“常用方法”适用,如其他答案所述。

但是,有一个非常烦人的例外:您无法扩展Google类的原型。您可以在问题跟踪器Issue 708上找到有关此问题的评论。它被标记为“不会修复”。