2013-06-26 4 views
0

Когда я развиваюсь в JS, я часто сталкиваюсь с выбором между захватом переменных с внутренней функцией (закрытием) и использованием объекта.Организация памяти js - закрытие объектов или объектов?

Внутренняя функция:

var x = ...; 
var f = function() { 
    // use x here 
} 

Объект:

obj.x = ...; 
obj.f = function() { 
    // use x here 
} 

Внутренняя функция подход «чувствует себя» более естественным, но мне было интересно - есть влияние на производительность, чтобы беспокоиться о делать это так или другой, и каков самый идиоматический способ сделать это?

+1

Значит, 'x',' f' и 'obj' будут в некоторой локальной области? Пожалуйста, заявите об этом. Если нет, этот вопрос будет касаться только пространства имен. Кроме того, как вы получаете доступ к 'x' во втором варианте? – Bergi

+1

Микро-оптимизации практически не стоит беспокоиться. Если ** ** ** или разница между двумя методами - это микро-управление памятью, тогда вы должны просто использовать какой-либо метод, который вы предпочитаете. Для меня обычно есть четко определенные причины использовать закрытие vs.размещение свойств объекта. Память никогда не является фактором для меня в определении того, какой подход использовать, поскольку вы на самом деле не управляете памятью в javascript, как вы можете на других языках. –

+0

Эта статья может представлять интерес: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management –

ответ

2

В эпоху, когда средний компьютер имеет 8 ГБ ОЗУ, использование памяти затворами по сравнению с объектными свойствами кажется несущественным. В любом случае в нетривиальном приложении крайне маловероятно, что имеет смысл использовать только закрытие или только значения свойств.

Если у вас есть модуль кода, имеет смысл использовать замыкания для переменных, которые используются только с помощью методов этого модуля. Также имеет смысл использовать свойства для значений, которые необходимо разделить между модулями, без использования геттеров и сеттеров (например, если вы хотите использовать obj.property, а не obj.getProperty()).

Кроме того, доступ к ресурсу намного эффективнее, чем использование функции для извлечения значения, но геттеры и сеттеры могут обеспечить значительную функциональность (например, проверку достоверности и проверку целостности) за простое чтение или присвоение значения.

Как всегда, используйте то, что подходит вашему приложению, в зависимости от того, какие критерии кажутся подходящими (скорость, удобство обслуживания, надежность, поддержка кросс-браузера и т. Д.).

+0

Я довольно много думал, что не будет большого воздействия на производительность для большинства приложений. Спасибо за то, что вы описали варианты использования каждого из них. Похоже, в целом нет единого мнения о том, что один лучше или хуже, просто доволен. – Dan

+0

Это не имеет ничего общего с доступной оперативной памятью, поскольку вы не просто получите все это для своей вкладки. Например, в Chrome вы имеете ограничение 1gb. Это связано с давлением в ГК, и чем больше памяти вы используете, тем медленнее получаете. Вы будете не сможете делать приложения на стороне сервера или любые приложения с поддержкой javascript (игры, редакторы, видеофайлы, а не форумы или CRUD). Заявки на вызовы методов также в значительной степени ошибочны , потому что вы можете легко писать код таким образом, чтобы приглашать функцию вложения для таких случаев. – Esailija

+0

@ Esailija - дело в том, что с учетом объема доступной ОЗУ разница в использовании памяти между затворами и свойствами объекта не имеет отношения к большинству целей. Что вы подразумеваете под «этим»? Вы говорите о встроенной функции на уровне кода или компилятора? Можно ли использовать в качестве общей стратегии для геттеров и сеттеров как доступ ко всем общим данным (т. Е. Как внутри, так и через модули)? – RobG

1

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

Функции являются объектами первого класса в JS, и легко забыть, что в любое время вы видите function(){}, что выделяет новый объект функции, который является относительно жирным. Вы могли бы подумать об этом, увидев, что new Function() называется , если это делает выделение объектов более очевидным для вас.

Это вредно только тогда, когда у вас есть «конструктор», который определяет функции внутри него и возвращает объект, указывающий на эти функции. Каждая из этих функций представляет собой отдельный объект, созданный поверх объекта, который вы создаете из конструктора. Функции будут легко получать на 10-100 раз больше памяти, чем объект и его данные, в зависимости от данных и количества методов, конечно.

Если вы пишете приложение, легко подумать о том, будете ли вы когда-либо беспокоиться об этом. Если вы знаете , ваше приложение никогда не создаст много объектов, а потеря памяти не так уж плоха в увеличенной картине. Если вы являетесь , пишите библиотеку общего назначения и т. Д., Пожалуйста, не делайте эти предположения для разработчиков приложений, чьи потребности вы не можете предсказать .