Posts

Showing posts with the label prototype

A Safer JS Environment

Oh well, apparently I wasn't joking here and I went even further ... so here I am with a weird hack you probably never thought about before ;) A Globally Frozen Environment Have you ever thought about this in the global context? Object.freeze(this); Apparently not even browser vendors such Chrome or Safari since this condition, today, is always false: Object.isFrozen(Object.freeze(this)); , and even if it works as expected after freezing. Firefox and node.js got it right while Opera Next throws an error .. but latter a part ... Stop Any Global Pollution That's right, if you freeze the window or global object, guess what happens here: Object.freeze(this); var a = 123; alert(this.a); // undefined alert(a); // error: a is not defined We cannot even by mistake create a global variable ... there's no lint that could miss that. Moreover, if you are worried about malicious code able to change some global function or constructor, you can stop worrying with proposed freeze call: t...

Array extras and Objects

When Array extras landed in JavaScript 1.6 I had, probably together with other developers, one of those HOORRAYYY moment ... What many libraries and frameworks out there still implement, is this sort of universal each method that supposes to be compatible with both Arrays and Objects. A Bit Messed Up What I have never liked that much about these each methods is that we have to know in advance in any case if the object we are passing is an Array, an ArrayLike one, or an Object. In latter case, the callback passed as second argument will receive as second argument the key , and not the index , which simply means we cannot trust a generic callback unless this does not check per each iterated item the second argument type, or unless we don't care at all about the second argument. In any case I always found this a bad design. If we think about events, as example, it's totally natural to expect a single argument as event object and then we can act accordingly. This let us reuse c...

bind, apply, and call trap

quick one out of ECMAScript ml var // used to trap function calls via bind invoke = Function.call, // normal use cases bind = invoke.bind(invoke.bind), apply = bind(invoke, invoke.apply), call = bind(invoke, invoke) ; What Is It This is a way to trap native functions method in a handy way. Used in a private scope, it can address these methods once so that we can rely nobody can possibly change them out there for some script injection and only if we are sure the script has been loaded at the very beginning. How To Use Them Here few examples: // secure hasOwnProperty var hasOwnProperty = bind(invoke, {}.hasOwnProperty); // later on hasOwnProperty({key:1}, "key"); // true hasOwnProperty({}, "key"); // false // direct slice var slice = bind(invoke, [].slice); slice([1,2,3], 1); // 2,3 slice(arguments); // array // direct call call([].slice, [1,2,3], 1); // 2,3 // direct apply apply([].slice, [1,2,3], [1]); // 2,3 // bound method var o = {name:...

ES5 Common Design Patterns Examples - Part 1

// Abstract Factory /* ({}).createInstance() (function (a, b, c) { this.sum = a + b + c; }).createInstance([1, 2, 3]) */ Object.defineProperty( // (C) WebReflection - Mit Style License Object.prototype, "createInstance", { value: (function (create) { return function createInstance(args) { var self = this, isFunction = typeof self == "function", obj = create(isFunction ? self.prototype : self) ; isFunction && args != null && self.apply(obj, args); return obj; }; }(Object.create)) } ); // Abstract Builder /* var person = Object.builder({ setup: function (name) { this.create(); this.instance.name = name; } }); person.setup("WebReflection"); alert(person.instance.name); person.create(); person.instance.name = "Andrea"; alert(person.instance.name); */ Object.defineProperty( // (C) WebReflection - Mit Style License Function.prototype, "builder", { ...

Constructorification

... he he, I know the title could not be worst, but after my last post about Arrayfication I have thought: " ... hey, the Thing.ify(object) could be more than handy in many occasions such mixins and duck typing ... ". So, let me introduce the Function.prototype method that nobody will ever use: Function.prototype.ify = function (o) { for (var self = this, p = self.prototype, // find a fucking way to implement this in ES3 // ... uh wait, there's no way to implement // this in ES3 ... // https://bugzilla.mozilla.org/show_bug.cgi?id=518663 m = Object.getOwnPropertyNames(p), i = m.length, n; i--; ) { // methods only m[i] = typeof p[n = m[i]] == "function" ? "o." + n + "=p." + n + ";" : "" ; } m.push("return o"); return (self.ify = Function("p", "return function " + ...

Array.prototype.slice VS Arrayfication

One of the most common operations performed on daily basis directly or indirectly via frameworks and libraries is Array.prototype.slice calls over non Array elements such HTMLCollection , NodeList , and Arguments . Why We Perform Such Operation The Function.prototype.apply works only with object created through the [[Class]] Array or Arguments. In latter case we may like to avoid ES3 arguments and named arguments mess when dealing with indexes. Finally, in most of the case we would like to perform Array operations over ArrayLike objects to filer, map, splice, change, modify, etc etc ... The Slice Cost Let's perform over an ArrayLike object of length 2000, 2000 slice calls (change the length if you have such powerful machine): // create the ArrayLike object for(var arguments = {length:2000}, i = 0; i arguments[i] = i; ; // define the bench function function testSlice(arguments) { var t = new Date; for (var slice = Array.prototype.slice, i = 0, length = arguments.lengt...

Function.prototype.bind

Quick post about a fast Function.prototype.bind implementation. Function.prototype.bind function bind(context:Object[, arg1, ..., argN]):Function { return a callback able to execute this function passing context as reference via this } In few words, if we have a generic object, we don't necessary need to attach a function to create a method: // a generic function function name(name) { if (name == null) return this.name; this.name = name; return this; } // a generic object var wr = {name:"WebReflection"}; // a callback with a "trapped" object var fn = name.bind(wr); alert([ // wr has not been affected wr.name, // WebReflection // fn can always be called fn(), // WebReflection fn("test") === wr, // true fn(), // test wr.name // test ].join("\n")); Designed to ensure the same context whatever way we decide to use the callback, included call, apply, setTimeout, DOM events, etc, Function.proto...

[ES5] Classes As Descriptor Objects

In my latest posts I have talked about current situation for JavaScript " Classes ". In Good Old And Common JS Errors I have introduced a misconception of a generic "Class" function which is usually not able to produce instanceof Class , considering Classes in JS are functions indeed. In Better JS Classes I have explained how to write a meaningful Class factory , avoiding the _super pollution over each extended method, while in the JS _super Bullshit I have explained why the _super/parent concept does not scale with JavaScript prototypal inheritance model. More than a dev, Mr Crockford included, agreed that in JavaScript the classical pattern does not fit/scale/produce expected results, and even worst, it could cause "disasters" during a session and slow down overall performances (and about this topic I have already said that web developers should stop to test their stuff with powerful CPU, read Macs! Buy a bloody Atom based device as I have done and af...

The JavaScript _super Bullshit

I know you already hate the title, but that's how I called one paragraph of my precedent post: Better JavaScript Classes . This post is mainly dedicated for both libraries authors, and those Classic OOP Developers that still think JavaScript should be used in a classic way. _super or parent Are Problematic! It's not just about performances, where " the magic " may need to replace, wrap, and assign runtime everything in order to make it happens, it's about inconsistencies, or infinite loops, or hard debug, or disaster prone approach as well, since as I have already said instances have nothing to do with _super/parent .... so, how are things? Thanks for asking! Real OOP Behavior It's the ABC, and nothing else, if we call a parent/super inside a method, this method will execute with a temporary self/this context. This means that the instance will be still: an instanceof its Class only that method will be executed, it is possible to call other super/parent accord...

[js.php] A JavaScript Object Like PHP Class

PHP 5.3 introduces the Closure class which is really useful and more powerful than good old lambdas via create_function . These are main limits of Closure class: you cannot serialize a Closure instance (and json_encode does not solve the problem at all) you cannot inject scopes via $this unless the closure comes from a class method While with an emulated prototype style class, something I tried months ago as well, the first point could not be a problem, to solve the second one is quite inevitable to use a Python like variable as first argument, called $self , to make the Closure both portable and re-adaptable. JSObject :: JavaScript Object Like PHP Class /** js.php basic JSObject implementation * @author Andrea Giammarchi * @blog WebReflection.blogspot.com * @license Mit Style License */ class JSObject implements ArrayAccess { // public static prototype static public $prototype; // ArrayAccess Interface public function offsetExists($index){return isSet(...

On JavaScript Inheritance Performance and Libraries Troubles

Image
Update: I have replied to myself and developers in a new post . I would like to say a big Thank You to every developer exposed tests, benchmark, traps, and considerations. Please read my last thoughts about the subject, since I deeply reconsidered my position. Update: Please do not get me wrong. I have no intention to say that one or any of cited framework, piece of code, library, is not good or fast enough to extend other classes. This post is about maniac optimization based on personal considerations over some deeper analysis to complete in a way the first benchmark. I am not criticizing libraries, they are great and they offer everything, I am simply showing a specific case, which is particular on purpose, and a specific behavior that, useful or not, could not be respected. About Few days ago Ajaxian published a post about JS inherited methods performances via common libraries strategies. I think the argument is extremely interesting but there's not enough material yet, so her...

Has this constructor been prototyped?

This is a quick post about libraries that uses native constructor in an obtrusive way. Using a Function prototype, that sounds like a non-sense, it is possible to know if a constructor has some property, or method, defined in its prototype. Function.prototype.prototyped = function(){ for(var i in new this) return true; return false; }; Some test example? alert(Array.prototyped()); // false Object.prototype.each = function(){}; alert(Array.prototyped()); // true delete Object.prototype.each; alert(Array.prototyped()); // false Array.prototype.each = function(){}; alert(Array.prototyped()); // true alert(Object.prototyped()); // false Update Has Kangas spotted, there is no reason to create a new instance. We could loop directly the prototype object. But what's up if we have injected privileged methods in the constructor? Array = function(Array){ var prototype = Array.prototype; return function(){ arguments = prototype.slice.call(arguments, 0); ...

JavaScript prototype behaviour with PHP

One cool thing of JavaScript prototype model, is that you can change dynamically one or more method updating automatically every instance of that constructor. Even if classic inheritance and OO Programmers hate this feature, it could be really useful in some case. Another interesting thing, is that thanks to injected scope, you can share a prototype or use one of its defined methods, with every kind of instance. PHP is (still) dynamically limited The concept of injected scope, is absolutely extraneous to PHP developers. Even with a massive usage of Reflection API , it is not possible to use a method of class A with another class B , even if this method contains common usable tasks for both classes. At the same time, it is not possible to use a function as property, because it is not recognized as function, if called directly, and it cannot contain a $this referer, thanks to engine limitation. The light comes from PECL The official repository for PHP extensions, contains a truly inte...

Habemus Array ... unlocked length in IE8, subclassed Array for every browser

History I do not know how many time, during these years, JavaScript Ninjas tried to subclass the native Array to create libraries over its powerful methods without losing performances. I have finally discovered the way to remove locked length from Internet Explorer 8 , and to solve problems with every other browser. We tried to inherit Array instead of Object This is where my last trip started, simply looking at arguments behaviour. It was there, since 2000 when I started to code in JavaScript, and it was so simple that probably few developers thought about them! var o = { length:0, push:Array.prototype.push, toString:Array.prototype.join }; o.push(1,2,3); alert(o); // 1,2,3 arguments, in JavaScript, is an instanceof Object, and not an Array, as is in ActionScript since version 1.0 What we have done all this time, is to use Array.prototype methods injecting a basic object, with a simple length parameter, inside. If an object with a length value can be used as an Arra...