2013-06-26 44 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上找到關於此問題的評論。它被標記爲「不會修復」。

相關問題