2016-10-07 2 views
0

У меня есть эти два примера функций на строки, которые делают точно то же самое:В чем разница между унаследованным методом (прототипом) и статическим методом (выражение)?

//ex1 - inherited method 
String.prototype.slugLower = function() { 
    return this.split(' ').join('-').toLowerCase(); 
} 

"hello World".slugLower(); 


//ex2 - static method 
String.slugLower = function(str) { 
    return str.split(' ').join('-').toLowerCase(); 
} 

String.slugLower("hello World"); 

И вернутся "hello-world". В чем разница между ними? Я имею в виду производительность/лучшие практики.

Thanks

ответ

3

Первый - это метод, прикрепленный к прототипу. Второй способ - это метод, прикрепленный к объекту String. В классическом языке OO они будут называться «унаследованным методом» и «статическим методом» соответственно.

Разница в производительности крохотная, и на самом деле это не имеет значения. Что должно быть: если вы считаете, что метод является поведением каждого объекта в классе объектов, он должен быть прототипным (унаследованным) методом. Если вы считаете, что это должно быть поведение, связанное с несколькими объектами класса или самого класса, вы должны использовать второй шаблон. Например, «мочиться» или «лаять это громко» - это поведение каждой собаки: Dog.prototype.peeOn, Dog.prototype.barkWithVolume; «Сколько собак в мире?» или «создать новую собаку» - это не поведение каждой собаки, а «собака» и пара собак соответственно: Dog.census и Dog.spawnPuppy.

+0

Мне нравится сравнение с 'static' и' inherited' в языках на основе классов. Аналогия немного ломается, потому что экземпляр «inherited» разделяется всеми экземплярами объекта. Но все-таки хорошая параллель. –

2

Метод, определенный в прототипе, будет доступен во всем объекте. Для большинства случаев использования наилучшей практикой будет 'your object'.protoype.

Другой пример:

var myObject = function monObject() { 
    /*...*/ 

    this.function1 = function function1() { 
     /*...*/ 
    }; 
}; 

myObject.prototype.function2 = function function2() { 
    /*...*/ 
}; 

Затем, если вы создаете 2 объекта

var obj1 = new myObject(); 
var obj2 = new myObject(); 

Тогда у вас есть это:

obj1.function1 !== obj2.function1 

но:

obj1.function2 === obj2.function2 

function1() создается на каждом новом myObject. Это ясно?

+0

Надеюсь, вы не имели в виду буквально «Объект», когда вы написали «Для большинства случаев использования« Object.protoype »станет лучшей практикой». Я не хочу, чтобы мой метод мочи моей собаки был на «Объекте», должен быть на «Собаке». – Amadan

+0

Теперь (хотя и точный), этот ответ не относится к примеру OP 'ex2'. –

+0

@ Амадан, да, я имею в виду «ваш объект». Прототип! –

0

Лучше всего определить функцию, чтобы сделать это

function slugLower(str){ 
    return str.split(' ').join('-').toLowerCase(); 
} 

Оба ваши примеры изменят объект String, есть некоторые побочные эффекты, первый пример instance method, второй является static function

+0

Зачем создавать внешнюю функцию, если она может быть применена только к объекту String. –

+0

Вы измените объект String, в большинстве случаев экземпляры String не нуждаются в этом методе, с которыми вы столкнулись, они несут что-то, что им не нужно. – Byron

+2

@SandrinaPereira: Рассмотрим, если в один прекрасный день комитет экстренной комиссии, как представляется, вводит новый метод в «String», который имеет то же имя, что и ваш метод, но ведет себя совершенно по-разному (возможно, нужно аргумент или произвести другой вывод). Прежде чем вы скажете, что теоретически помните, что это ** произошло раньше: в библиотеке prototype.js. Prototype.js предполагал, что они могут улучшить javascript, расширив прототипы собственных объектов. Затем es5 сломал свою библиотеку (которая была очень популярной BTW, поскольку она была включена по умолчанию с Ruby on Rails) – slebetman

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