Чи є JavaScript-об'єкти "відкритими", як Ruby?

У ruby я можу додавати та змінювати функціональні можливості будь-якого класу, об'єкта або методу, використовуючи один і той же синтаксис, який я хотів оголосити моїм власним, оскільки ruby має "відкриті класи".

Чи є такий JavaScript?

.

Як приклад...

У моєму випадку я хочу змінити спосіб, яким Google Apps Script обробляє URL-адреси, тому що кожен раз, коли я оцінюю об'єкт URL-адреси, сам URL-адреса сам переконаний, що він починається з протоколу://(за адресою http://за замовчуванням).

3
Прикладом є Object.defineProperty
додано Автор simonzack, джерело
Прикладом є Object.defineProperty
додано Автор simonzack, джерело
Прикладом є Object.defineProperty
додано Автор simonzack, джерело
У сучасних сценаріях JavaScript можна захистити властивості об'єкта від модифікації.
додано Автор Pointy, джерело

9 Відповіді

Так.

З застереженням, що, як ви визначаєте "клас", це дуже відрізняється від 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"
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"
3
додано

Так, ви можете вільно змінювати об'єкти. Ви можете змінити певний об'єкт Object.overridenProperty = ... або змінити всі об'єкти, отримані з певного класу через його прототип властивість 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;
    }());
}());
3
додано

Так, ви можете вільно змінювати об'єкти. Ви можете змінити певний об'єкт Object.overridenProperty = ... або змінити всі об'єкти, отримані з певного класу через його прототип властивість 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;
    }());
}());
3
додано

Так, ви можете вільно змінювати об'єкти. Ви можете змінити певний об'єкт Object.overridenProperty = ... або змінити всі об'єкти, отримані з певного класу через його прототип властивість 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;
    }());
}());
3
додано

Дивіться цей клас з геттером і сетером:

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

1
додано

Дивіться цей клас з геттером і сетером:

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

1
додано

Дивіться цей клас з геттером і сетером:

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

1
додано

Ви спеціально вказали Google Apps Script у своєму запиті. Оскільки GAS є варіантом JavaScript , застосовуються "звичайні способи" визначення об'єкта та розширення, як описано в інших відповідях .

Однак існує одне жахливо виняткове: Ви не можете розповсюджувати прототипи класів Google. Ви можете знайти коментарі про це в трекера проблем: Випуск 708 . Це було позначено як "не буде виправлено".

1
додано
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram