В чем разница и какие недостатки (если они есть) у такой записи в прототип?

Рейтинг: 0Ответов: 1Опубликовано: 25.10.2014

В чем разница между двумя этими видами записи и какие у второго подхода недостатки перед первым? Почему все советуют первый вариант, когда второй в десять раз быстрее?

var REPEAT = 5;
var ITERATION = 10000000;

function runTest(){
    while(REPEAT-- > 0)
    {
        console.log(speed());
    }
    return;
}

function A( ){}
A.prototype = { run: function( ){}};

function B( ){}
B.prototype.run = function( ){};

var a = new A( ); // 260
var b = new B( ); // 25

function speed(){

    var startTime = new Date();
    for (var i = 0; i < ITERATION; i++) {
        b.run( );
    };

    var finishTime = new Date();
    return 'Время выполнения - ' + (finishTime.getTime() - startTime.getTime()) + '.' 
}

runTest();

Ответы

▲ 1Принят

Ну, давайте разберем механизм работы JavaScript на простом примере.

Создадим наши два объекта, использую консоль браузера хром.

function a(){}
a.prototype = {
    a : function(){},
    b : function(){}
}

function b(){}
b.prototype.a = function(){}
b.prototype.b = function(){}

После этого выполним дамп их прототипов, получим такой результат:

› a.prototype
▼ Object {a: function, b: function}
    ► a: function (){}
    ► b: function (){}
    ► __proto__: Object

› b.prototype
▼ b {a: function, b: function}
   ► a: function (){}
   ► b: function (){}
   ► constructor: function b(){}
   ► __proto__: Object

Единственное различие между двумя объектами - это наличие свойства constructor со ссылкой на саму функцию. В общем-то это легко поправить:

function a(){}
a.prototype = {
    a : function(){},
    b : function(){},
    constructor: a
}

› a.prototype
▼ a {a: function, b: function}
   ► a: function (){}
   ► b: function (){}
   ► constructor: function a(){}
   ► __proto__: Object

То есть результат в обоих случаях будет совершенно одинаковый, за исключением свойства constructor, который в данном случае не влияет на производительность вызова других функций и его можно легко добавить. Почему nodejs у Вас так себя повел, я не знаю, но скорее всего дело в элементарной погрешности.

Что же касается рекомендуемого кода:

function a(){}
a.prototype = {
    a : function(){},
    b : function(){}
}

Он, с точки зрения проектирования, намного нагляднее разбросанных по файлу определения новых полей, поскольку они аккуратно сгруппированы в одном месте.

P.S. По поводу теста - 30 итераций не дают никакого результата, надо было ставить несколько сотен тысяч и какой-нибудь простой код внутрь функций.