2013-06-26 13 views
3

在Ruby中,我可以使用相同的语法添加和修改任何类,对象或方法的功能,因为Ruby具有“打开类”,所以我会声明自己的语法。javascript对象是否像Ruby一样“打开”?

是JavaScript吗?

举个例子...

在我的情况,我想改变谷歌Apps脚本处理URL对象的方式,这样每次我评价一个URL对象,URL对象本身确保它始于协议://(默认为http://)。

+0

在现代JavaScript运行时中,可以保护对象属性不被修改。 – Pointy

+0

一个例子是'Object.defineProperty' – simonzack

回答

3

是的。

有关如何定义“类”的警告与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" 
1

看到这个类与getter和二传:

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

是的,你可以随意修改的对象。您可以修改特定对象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

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

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

相关问题