2014-01-12 3 views
0

Я создаю структуру, упрощающую кодирование ориентированных объектов с помощью прототипов. Но я обдумываю с наследованием в JavaScript.JavaScript расширяет объекты и прототипы

По умолчанию, чтобы расширить объект, мы пишем:

var B = function() { /*...*/ } ; 
B.prototype = new A() ; 

Но что функция конструктора требует параметра?

var A = function(args) { 
    if (!args) throw "Arguments required." ; 
} ; 

Или, может быть функция конструктор может также выполнять нежелательные вещи, прежде чем B был instancied.

Что вы предложите заменить по умолчанию наследование? (я думал о хранении всех членов всех «классов», чтобы скопировать наследуя или Примеси.)

ответ

3

Если вы хотите, чтобы наследовать от прототипа без вызова конструктора, вы можете использовать Object.create() сделать что-то вроде этого :

var B = function() { /*...*/ }; 

B.prototype = Object.create(A.prototype); 
B.prototype.constructor = B; 

в выше, Object.create(A.prototype) возвращает новый объект, прототип задается A.prototype, и делает это без вызова A(). Вторая строка там, так что вы можете найти свойство конструктора в любых экземплярах B, и оно будет указывать на B().

Следует отметить, что Object.create() относительно новый, поэтому для старых браузеров вам может потребоваться полиполк. Вы можете найти один здесь, наряду с подробной информацией:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

1

Я обычно использую defclass функцию полезности для определения «классы» в JavaScript:

function defclass(base, body) { 
    var uber = base.prototype; 
    var prototype = Object.create(uber); 
    var constructor = (body.call(prototype, uber), prototype.constructor); 
    constructor.prototype = prototype; 
    return constructor; 
} 

Затем я использую его следующим образом:

var A = defclass(Object, function() { 
    this.constructor: function (arg1, arg2) { 
     this.arg1 = arg1; 
     this.arg2 = arg2; 
    } 

    this.log = function (which) { 
     console.log(which ? this.arg1 : this.arg2); 
    }; 
}); 

Наследование мертв прост:

var B = defclass(A, function (uber) { 
    this.constructor = function (arg1, arg2, arg3) { 
     uber.constructor.call(this, arg1, arg2); 
     this.arg3 = arg3; 
    }; 

    this.log = function (which) { 
     uber.log.call(this, which); 
     console.log(this.arg3); 
    }; 
}); 

Как вы можете видеть, когда мы расширяем «класс», мы используем Object.create. Это новый способ наследования. Использование new устарело. В конструкторе B мы передаем аргументы конструктору A с использованием uber.constructor.call.

Если вам нравится этот рисунок, вы должны взглянуть на библиотеку augment.

+0

Интересная библиотека. Но я не люблю определять атрибуты и методы с помощью 'this.prop = value;' всюду. – Tot

Смежные вопросы