2014-10-23 4 views
-1

Я играл с идеей использования IFFE внутри объявления объекта вместо метода init(), который я должен вручную вызывать в конце объявления. Единственная проблема, с которой я, похоже, сталкиваюсь, заключается в том, что я не знаю, как получить доступ к приватным свойствам из IFFE. Рассмотрим следующий пример:Как получить доступ к частной собственности из IFFE в javascript

function Obj() { 

    this.prop = 'Public property'; 
    var _prop = 'Private property'; 

    (function(that) { 

     console.log(that.prop); 
     console.log(that._prop); // Returns undefined 

    })(this); 

} 

obj = new Obj(); 

пропусканием this в IFFE я могу получить доступ к this сферы, но частные свойства не кажутся обложению через это. Я знаю, что могу вручную передавать отдельные свойства, но я бы предпочел решение, позволяющее мне получить доступ ко всем приватным свойствам.

Каков наилучший способ решить эту проблему?

+1

Что делает 'console.log (_prop)' дать вам? – andrew

+1

* ", но частные свойства, кажется, не могут быть оценены через' this' "* В этом весь смысл. Если бы вы могли получить к ним доступ через 'this', тогда все, у кого есть ссылка на объект, могли (на самом деле, вы делаете это с помощью' this.prop'). «Частные свойства» - это не что иное, как локальные переменные. Как вы получаете доступ к переменным? –

+0

Это переменная. В JavaScript нет такой вещи, как «частная собственность». –

ответ

0

Потому что:

var _prop = 'Private property'; 

создает локальную переменную и

console.log(that._prop); // Returns undefined 

пытается получить доступ к _prop собственностью , что (ака это). Переменные не являются объектными свойствами *. Использование:

console.log(_prop); // Returns Private property 
  • Ну, переменные свойства VariableEnvironment, которая принадлежит к LexicalEnvironment, вид объекта (в ECMA-262-е изд 3 он назывался variable object), но вы не можете получить доступ к тем, кто непосредственно в способе доступа к переменным в качестве свойств global или Окно объект.
1

IIFE путь как модуля Pattern реализован. (См The Module Pattern)

Любого объект, объявленный внутри функции изолирована от внешней области, Манинг, что частного переменных являются недоступной. Если вам нужно изменить частные объекты, вы можете пересмотреть, используя IIFE.

Теперь посмотрим на код, переменная _prop объявляется в том же closure где IFFE определяется, что означает, что вы можете получить доступ к этому объекту в IIFE, например,

function Obj() { 
    var _private = 1; 

    //IIFE 
    (function() { 
     console.log("_private: ", _private); 
    }()); 
} 

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

function Obj() { 
    var _seed = 0; 
    this.setSeed = function (seed) { 
     _seed = seed; 
    }; 
    this.getSeed = function() { 
     return _seed; 
    }; 
} 

Или вы можете определить геттер/сеттер в экземпляре прототип, но этот подход имеет тот недостаток, чтобы иметь более низкую производительность, например,

function Obj() { 
    var _seed = 0; 
    Object.defineProperty(this, "seed", { 
     get: function() { return _seed; }, 
     set: function (seed) { 
      //ensure to be a numeric value 
      if (+seed || seed === 0) _seed = +seed; 
     } 
    }); 
} 

Или создать модуль с loose augmentation

//begin IIFE 
var module = (function (module) { 
    var _private = 1; 

    function getPrivate() { 
     return _private; 
    } 

    function setPrivate(value) { 
     _private = value; 
    } 

    function printPublicMember() { 
     console.log(module.publicMember); 
    } 

    //public mudule API 
    module = { 
     "publicMember": "I am public!!", 
     "printPublicMember": printPublicMember, 
     "getPrivate": getPrivate, 
     "setPrivate": setPrivate 
    }; 

    return module; 

}(window.module || {})); 
//end IIFE 
1

Как @jherax сказал, что цель с помощью IFFE является приближенная сферу на уровне блоков в JavaScript поэтому доступ к частной собственности за пределами IFFE побеждает цель иметь его.

Однако вы можете создать API рода, вернув объект, который указывает на свойства, о которых идет речь. Используется ненадлежащим образом, это немного взломать и, как правило, обескураживает.

function Obj() { 

this.prop = 'Public property'; 
var _prop = 'Private property'; 

    (function(that) { 

    console.log(that.prop); 
    console.log(that._prop); // Returns undefined 

    })(this); 
    return { 
    accessPoint: _prop //gives you a getter of sorts to _prop 
    }; 
} 

obj = new Obj(); 
obj.accessPoint; 
0

IIFE внутри вашего конструктора не имеет никакого значения. Это в точности эквивалентно простому написанию содержимого. Цель IIFE - создать замкнутую область с локальными переменными, которых у вас нет.

Каким образом этот IFFE должен избегать вызова функции init? Конструктор уже является функцией init по-своему.

Причина, по которой вы не можете получить доступ к that._prop из вашего IIFE, заключается в том, что нет свойства экземпляра под названием _prop. Существует локальная переменная, называемая _prop. Чтобы получить к ней доступ, просто скажите _prop, а не this._prop или that._prop.

+0

Я написал этот вопрос совсем недавно. Я все еще соглашался с тем, как область работы вложенных функций. Согласился, что эта конкретная функция не делает ничего важного, поскольку никакие переменные не объявлены. Вероятно, это потому, что я сильно упростил пример, чтобы попытаться помочь мне понять, что я не понимаю. Спасибо за ваш ответ. – McShaman

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