Is it possible to have private properties in a model? Like the locally declared variables in a (constructor) function, not attached to this
, but declared locally and visible only by whatever is defined in the (constructor)function.
Example without BB View:
function MyView(aModel){
var $internalInput = $('<input>');
this.render: function($where){
$internalInput.val(aModel.get('SomeProperty'));
$where.append($('<div class="inputWraper">').append($internalInput));
};
this.toggleReadonly: function() {
toggle $internalInputs readonly attribute
}
...
+ Code to bind input.val to some aModel property(ies) and setup events
...
}
Note that internalInput
is not accessible to outside world and aModel
is also not accessible (through MyView at least).
So if I want to use Backbone.View to implement the above MyView, how would i do it and keep $internalInput 'private'?
Is it possible to have private properties in a model? Like the locally declared variables in a (constructor) function, not attached to this
, but declared locally and visible only by whatever is defined in the (constructor)function.
Example without BB View:
function MyView(aModel){
var $internalInput = $('<input>');
this.render: function($where){
$internalInput.val(aModel.get('SomeProperty'));
$where.append($('<div class="inputWraper">').append($internalInput));
};
this.toggleReadonly: function() {
toggle $internalInputs readonly attribute
}
...
+ Code to bind input.val to some aModel property(ies) and setup events
...
}
Note that internalInput
is not accessible to outside world and aModel
is also not accessible (through MyView at least).
So if I want to use Backbone.View to implement the above MyView, how would i do it and keep $internalInput 'private'?
- 1 Note the only thing "private" achieves is making your code slower. – Raynos Commented Jan 19, 2012 at 12:05
- Can u elaborate please? I just want it for info hiding purposes so tha t I can change it in the future, without fearing someone might depend on it by having used it directly. But if this means slowing the code then it is an issue. Where can i find more info on your claim? – Paralife Commented Jan 19, 2012 at 12:52
-
1
Closures have massive overhead, Private state is expensive but can be done better. My personal remendation is use
_foo
for internal properties that are likely to change. Also if someone depends on internal properties it's their problem when your API changes, not your problem – Raynos Commented Jan 19, 2012 at 13:11
5 Answers
Reset to default 10You should be able to achieve private data by passing an IIFE to extend
when defining your Backbone objects, rather than just a plain object. For example:
var Thing = Backbone.Model.extend((function () {
var foo = "Private data!";
return {
bar: function () {
console.log(foo);
}
};
})());
You'd better off with
var Thing = Backbone.Model.extend(
{
constructor : function ()
{
var _value = "Private data!";
this.getValue = function ()
{
return _value;
};
this.setValue = function (value)
{
_value = value;
};
}
});
Javascript is fun!
var Thing = (function () {
var number_of_things = 0;
return function (options) {
var value = "Private data!";
return new ( Backbone.Model.extend({
constructor: function constructor () {
number_of_things += 1;
},
getValue: function getValue () {
return value;
}
}) )();
};
}());
I'm a little concerned by the fact that every instance of this "Thing" is also a subclass, in the OOP lingo.
In the context of using Broserify.js with Backbone (and really any above medium project) I found the following way to have private vars and functions:
myView.js
'use strict';
var config = require('../config.js'),
private_var = 'private variable',
my_private_fn = function() {
...
};
module.exports = Backbone.Model.extend({
initialize: function() {
this.my_public = 'public variable');
console.log('This is my' + this.my_public);
console.log('This is my' + my_private);
},
});
The idea to take here is go with Browserify :P
The simplest way is the following:
...
initialize:function(properites){
// Init the logic with private and public methods/variable
this.logic.initFirst(this);
// Use public methods
this.logic.doSomething();
},
logic:{
initFirst:function(modelOrView){
// Do not continue if already initiated
if( this.instance !== undefined ) return;
// Write all logic here
this.instance = (function(logic, modelOrView){
// Private variables
var private = "private";
// Public methods
logic.doSomething = function(){
console.log(private, modelOrView);
};
// Private methods
function hidden(){
}
}(this, modelOrView));
}
},