javascript - Private prototype methods that can share scope and access the instance -
i'm looking pattern both allows me create private scope function prototype has access , need able access instance within scope.
for example, how achieving "private methods" (disregard code does, @ structure.)
function infopreview() { this.element = document.createelement('div'); } //private methods infopreview.prototype.__newline = function () { this.element.appendchild(createelement({tagname:'br'})); }; infopreview.prototype.__padleft = function(level) { var padding = createelement({tagname: 'span'}); this.element.appendchild(padding); $(padding).width(level * 10); }; infopreview.prototype.__print = function(string) { var span = createelement({ tagname: 'span', textcontent: string }); this.element.appendchild(span); this.element.style["margin-right"]='10px'; }; infopreview.prototype.__puts = function(string) { this.__print(string); this.__newline(); }; //public methods infopreview.prototype.update = function(info) { $(this.element).empty(); (var record in info) { this.__puts(record); } };
notice not creating private methods @ all, utilizing naming convention. additionally notice have no way cache chain-lookups, such this.element
.
i create private scope utilizing revealing module pattern, this:
infopreview.prototype = (function() { var self = this, //<- `this` global object now. el = self.element; var newline = function () { el.appendchild(createelement({tagname:'br'})); }; var padleft = function(level) { var padding = createelement({tagname: 'span'}); el.appendchild(padding); $(padding).width(level * 10); }; var print = function(string) { var span = createelement({ tagname: 'span', textcontent: string }); el.appendchild(span); el.style["margin-right"]='10px'; }; var puts = function(string) { print(string); newline(); }; var update = function(info) { $(el).empty(); (var record in info) { puts(record); } }; return { update: update }; })();
the above approach doesn't work however, because value of this
within iife global object, not instance. need way access instance.
is there downside of using constructor pattern?
function foo(constructorarg) { /* private variables */ var privvar = 'i private', carg = constructorarg; /* public variables */ this.pubvar = 'i public'; /* private function */ function privfunc() { return 'i private function'; } /* public function */ this.publicfunc = function() { return 'i public function , call privvar->"' + privvar + '" , privfunc->"' + privfunc() + '"'; } } var foo = new foo('something'); console.log('foo.pubvar', foo.pubvar); //ok console.log('foo.publicfunc()', foo.publicfunc()); // ok console.log('foo.privvar', foo.privvar); // undefined console.log('foo.privfunc', foo.privfunc()); //error
why should use (as requested in comments):
simply put, because (sane) way of creating "true private scope", question.
the alternative using convention tell developers properties , methods private, prefixing them underscore _
, implemented disliked.
note constructor , prototype different things , enable different stuff. nothing prevents mixing both up.
memory usage
regarding memory usage, in modern js engines, such google's v8 javascript engine, the constructor pattern might faster.
v8 has hidden types created internally objects @ runtime; objects same hidden class can use same optimized generated code.
for example:
function point(x, y) { this.x = x; this.y = y; } var p1 = new point(11, 22); var p2 = new point(33, 44); // @ point, p1 , p2 have shared hidden class p2.z = 55; // warning! p1 , p2 have different hidden classes!
prototype chaining require 2 lookups, might tiny inny little bit slower. note: can't on this, jsperf.com down!
constructor pattern dirty (sic)
performance reason. hadn't realized that. still feels dirty me
i don't know why feel constructor pattern dirty. maybe it's because has "specifics", limitations , potential pitfalls should aware
this
can mean different things- it's easy forget new keyword causing weird , hard debug bugs due shared state
- you can't split object across multiple files (without resorting build tool or 3rd party injector)
however, 1 , 2 true prototype declaration style so...
if feel not adequate, might want @ module pattern.
Comments
Post a Comment