пятница, 31 июля 2015 г.

Обновленный способ создания классов в JavaScript

// Extend
function extend (child, parent) {
    var key;
    function F () {}
    if (isTypeOf(child, 'Object') && isTypeOf(parent, 'Object')) {
        for (key in parent) {if (parent.hasOwnProperty(key)) {child[key] = parent[key];}}
    } else if (isTypeOf(child, 'Function') && isTypeOf(parent, 'Object')) {
        child.prototype = parent;
        child.prototype.constructor = child;
    } else if (isTypeOf(child, 'Function') && isTypeOf(parent, 'Function')) {
        for (key in parent) {if (parent.hasOwnProperty(key)) {child[key] = parent[key];}}
        F.prototype = parent.prototype;
        child.prototype = new F();
        child.prototype.constructor = child;
    }
}

// Mixin
function mixin (child) {
    var mixins = Array.prototype.slice.call(arguments, 1);
    if (not(isEmpty(mixins))) {
        if (isTypeOf(mixins[0], 'Array')) {mixins = mixins[0];}
        forEachIn(mixins, function(mixinClass){
            forEachIn(mixinClass, function(propertyInClass, propertyName){if (mixinClass.hasOwnProperty(propertyName)) {child[propertyName] = propertyInClass;}});
            forEachIn(mixinClass.prototype, function(propertyInPrototype, propertyName){if (propertyName !== 'constructor') {child.prototype[propertyName] = propertyInPrototype;}});
        });
    }
}

// Class
function ParentClass (initVar) {
    this.initVar = initVar;
    this.defaultVar = 'ParentClass default var inside constructor.';
    this._x = 0;
    document.addEventListener('click', this._eventFunction, false);
}

// Static
ParentClass.staticMethod = function () {return 'ParentClass static method.'};

// Default
ParentClass.prototype.defaultVar = 'ParentClass default var inside prototype.';

// Public
ParentClass.prototype.destroy = function () {document.removeEventListener('click', this._eventFunction, false);};
ParentClass.prototype.publicMethod = function () {return 'ParentClass public method.';};

// Private
ParentClass.prototype._privateMethod = function () {return 'ParentClass private method call ' + this.initVar;};
ParentClass.prototype._eventFunction = function () {alert(1);};

// Getters and Setters
Object.defineProperty(ParentClass.prototype, "x", {
      get: function () {return this._x;}
    , set: function (value) {this._x = value;}
    , enumerable: true
    , configurable: true
});

// Tests
var parentObject = new ParentClass('ParentClass init var');
console.dir(ParentClass);
console.dir(ParentClass.prototype);
console.log(parentObject.constructor.name);
console.log(parentObject.defaultVar);
delete parentObject.defaultVar;
console.log(parentObject.defaultVar);
console.log(parentObject.initVar);
console.log(parentObject.publicMethod());
console.log(parentObject._privateMethod());
console.log(ParentClass.staticMethod());
parentObject.x = 1;
console.log('ParentClass getter x=' + parentObject.x);
setTimeout(function () {console.log('Object destruction.'); parentObject.destroy(); parentObject = null; }, 5000);

console.log('---------------------------------------------');

// Class
function MixinClass() {}

// Static
MixinClass.mixinStaticMethod = function () {return 'MixinClass static method.';};

// Public
MixinClass.prototype.mixinPublicMethod = function () {return 'MixinClass public method.';};

// Class
function ChildClass (initVar) {
    if (ChildClass.instance) {return ChildClass.instance;} ChildClass.instance = this;
    ParentClass.call(this, initVar);
    this._y;
    var privateVar = 'ChildClass private var.';
    function privateFunction() {return 'ChildClass private function can show ' + privateVar + ' and ' + ParentClass.prototype._privateMethod.call(ChildClass.instance);}
    console.log(privateFunction());
    return ChildClass.instance;
}

// Extend
extend(ChildClass, ParentClass);

// Mixin
mixin(ChildClass, MixinClass);

// Singleton
ChildClass.instance = undefined;

// Override
ChildClass.prototype.destroy = function () {console.log('ChildClass destroyed.');};
ChildClass.prototype.publicMethod = function () {return 'ChildClass public method.';};

// Getters and Setters
Object.defineProperty(ChildClass.prototype, "y", {
      get: function () {return this._y;}
    , set: function (value) {this._y = value;}
    , enumerable: true
    , configurable: true
});

// Tests
var childObject = new ChildClass('ChildClass init var');
var childObject2 = new ChildClass('ChildClass init var 2');
console.dir(ChildClass);
console.dir(ChildClass.prototype);
console.log('Is singleton? ' + (childObject === childObject2));
console.log(childObject.constructor.name);
console.log(childObject.defaultVar);
console.log(childObject.initVar);
console.log(childObject.publicMethod());
console.log(childObject._privateMethod());
console.log(ChildClass.staticMethod());
childObject.x = 2;
console.log('ChildClass getter x=' + childObject.x);
childObject.y = 5;
console.log('ChildClass getter y=' + childObject.y);
console.log(childObject.mixinPublicMethod());
console.log(ChildClass.mixinStaticMethod());
setTimeout(function () {console.log('Object destruction.'); childObject.destroy(); childObject = null;}, 5000);

JavaScript Enum

function Enum () {
    var i, len = arguments.length;
    for (i = 0; i < len; i++) {
        this[arguments[i]] = i;
        this['' + i] = arguments[i];
    }
}

var Colors = new Enum ('Red', 'Green', 'Blue');

console.dir(Colors);

console.log(Colors[0]);

console.log(Colors.Red);

JavsScript Invert all colors on a webpage including images and CSS

(function() {
    var css = 'html {-webkit-filter: invert(100%); -moz-filter: invert(100%); -o-filter: invert(100%); -ms-filter: invert(100%);}'
      , head = document.getElementsByTagName('head')[0]
      , style = document.createElement('style');
    if (!window.counter) {
        window.counter = 1;
    } else {
        window.counter++;
        if (window.counter % 2 == 0) {
            css = 'html {-webkit-filter: invert(0%); -moz-filter: invert(0%); -o-filter: invert(0%); -ms-filter: invert(0%);}'
        }
    }
    style.type = 'text/css';
    if (style.styleSheet) {
        style.styleSheet.cssText = css;
    } else {
        style.appendChild(document.createTextNode(css));
    }
    head.appendChild(style);
})();

среда, 29 июля 2015 г.

JavaScript Emoticons Variable names


var Ƹ̵̡Ӝ̵̨̄Ʒ = 'butterfly';

function ლಠ_ಠლ  () {console.log('Settle down');}
ლಠ_ಠლ ();

function a  (゚ー゚) {console.log('Cool');}

function a  (ツ) {console.log('lol i dunno');}

function a  (ლಠ_ಠლ) {console.log(ლಠ_ಠლ);}

function a  (ᵔʖᵔ) {return '';}

function a  (ლಠ益ಠლ) {return 'Rage';}

function a  (ლಠ‿ಠლ) {return '';}

function a  (ಠ益ಠ) {return '';}

function a  (゚ヮ゚) {return '';}

пятница, 24 июля 2015 г.

JavaScript Unicode variable names

// How convenient!
var π = Math.PI;

// Sometimes, you just have to use the Bad Parts of JavaScript:
var ಠ_ಠ = eval;

// Code, Y U NO WORK?!
var ლ_ಠ益ಠ_ლ = 42;

// How about a JavaScript library for functional programming?
var λ = function() {};

// Obfuscate boring variable names for great justice
var \u006C\u006F\u006C\u0077\u0061\u0074 = 'heh';

// …or just make up random ones
var Ꙭൽↈⴱ = 'huh';

// While perfectly valid, this doesn’t work in most browsers:
var foo\u200Cbar = 42;

// This is *not* a bitwise left shift (`<<`):
var 〱〱 = 2;
// This is, though:
〱〱 << 〱〱; // 8

// Give yourself a discount:
var price_9̶9̶_89 = 'cheap';

// Fun with Roman numerals
var Ⅳ = 4,
    Ⅴ = 5;
Ⅳ + Ⅴ; // 9

// Cthulhu was here
var Hͫ̆̒̐ͣ̊̄ͯ͗͏̵̗̻̰̠̬͝ͅE̴̷̬͎̱̘͇͍̾ͦ͊͒͊̓̓̐_̫̠̱̩̭̤͈̑̎̋ͮͩ̒͑̾͋͘Ç̳͕̯̭̱̲̣̠̜͋̍O̴̦̗̯̹̼ͭ̐ͨ̊̈͘͠M̶̝̠̭̭̤̻͓͑̓̊ͣͤ̎͟͠E̢̞̮̹͍̞̳̣ͣͪ͐̈T̡̯̳̭̜̠͕͌̈́̽̿ͤ̿̅̑Ḧ̱̱̺̰̳̹̘̰́̏ͪ̂̽͂̀͠ = 'Zalgo';

Create JavaScript Function Dynamically

function createFunction (name, args, body) {
    var argumentsLength = arguments.length
        , name
        , args
        , body
        , isString = function (element) {return Object.prototype.toString.call(element) === '[object String]';};
    if (argumentsLength === 0) {
        name = '';
        args = '';
        body = '';
    } else if (argumentsLength === 1) {
        name = name;
        args = '';
        body = '';
        if (!isString(name)) {throw new Error('Function name must be a string.');}
    } else if (argumentsLength === 2) {
        name = name;
        body = args;
        args = '';
        if (!isString(name)) {throw new Error('Function name must be a string.');}
        if (!isString(body)) {throw new Error('Function body must be a string.');}
    } else if (argumentsLength === 3) {
        name = name;
        args = args;
        body = body;
        if (!isString(name)) {throw new Error('Function name must be a string.');}
        if (!isString(args)) {throw new Error('Function arguments must be a string.');}
        if (!isString(args)) {throw new Error('Function body must be a string.');}
    }
    return (new Function('return function ' + name + ' (' + args + ') {' + body + '};'))();
}

var func = createFunction ();
console.log(func.toString());
console.log(func());

var func = createFunction ('a');
console.log(func.toString());
console.log(func());

var func = createFunction ('a', 'return 1;');
console.log(func.toString());
console.log(func());

var func = createFunction ('a', 'b, c', 'return b + c;');
console.log(func.toString());
console.log(func(2, 3));

четверг, 23 июля 2015 г.

Упрощенный способ создания классов в JavaScript как в Java

<!DOCTYPE html>
<html>
<meta charset="utf-8" />
<head><title>JavaScript Class</title></head>
<body>
<script type="text/javascript">

function class_ (cls) {
    if (Object.prototype.toString.call(cls) !== '[object Function]') {throw new Error('Class constructor must be a function.');}
    return cls();
}

function extend_ (child, parent) {
    var key;
    function F () {}
    if (Object.prototype.toString.call(child) === '[object Object]' && Object.prototype.toString.call(parent) === '[object Object]') {
        for (key in parent) {if (parent.hasOwnProperty(key)) {child[key] = parent[key];}}
        return;
    }
    if (Object.prototype.toString.call(child) === '[object Function]' && Object.prototype.toString.call(parent) === '[object Object]') {
        child.prototype = parent;
        child.prototype.constructor = child;
        child.super_ = parent;
    }
    if (Object.prototype.toString.call(child) === '[object Function]' && Object.prototype.toString.call(parent) === '[object Function]') {
        for (key in parent) {if (parent.hasOwnProperty(key)) {child[key] = parent[key];}}
        F.prototype = parent.prototype;
        child.prototype = new F();
        child.prototype.constructor = child;
        child.super_ = parent.prototype;
    }
}

function mixin_ (child) {
    var mixins = Array.prototype.slice.call(arguments, 1)
        , i, key, len = mixins.length;
    if (len) {
        for (i = 0; i < len; i++) {
            for (key in mixins[i]) {if (mixins[i].hasOwnProperty(key)) {child[key] = mixins[i][key];}}
            for (key in mixins[i].prototype) {child.prototype[key] = mixins[i].prototype[key];}
        }
    }
}

function singleton_() {return {for_: function (cls) {cls.instance_ = undefined;}}}

function create_singleton_ (cls) {
    if (cls.instance_ !== undefined) {return cls.instance_;} else {return cls.instance_ = new cls();}
}

function constructor_ (func) {return {for_: function (cls) {cls.new_ = func;}}}

function destructor_ (func) {return {for_: function (cls) {cls.prototype.destroy_ = func;}}}

function default_ (propName, propValue) {return {for_: function (cls) {cls.prototype[propName] = propValue;}}}

function public_ (propName, propValue) {return {for_: function (cls) {cls.prototype[propName] = propValue;}}}

function private_ (propName, propValue) {return {for_: function (cls) {
        if (propName.substring(0, 1) !== '_') {throw new Error('Private property name must starts from symbol "_".');}
        cls.prototype[propName] = propValue;
    }}
}

function override_ (propName, propValue) {return {for_: function (cls) {cls.prototype[propName] = propValue;}}}

function final_ (propName, propValue) {return {for_: function (cls) {cls.prototype[propName] = propValue;}}}

function static_ (propName, propValue) {return {for_: function (cls) {cls[propName] = propValue;}}}

function implementation_ (cls, propArray) {
    for (var i = 0, len = propArray.length; i < len; i++) {propArray[i].for_(cls);}
}

function interface_ (intfc) {
    if (Object.prototype.toString.call(intfc) !== '[object Function]') {throw new Error('Interface constructor must be a function.');}
    return intfc();
}

function impliment_(cls, intfc) {
    var key, errorMessage = 'Class does not implement the interface correctly for "';
    for (key in intfc) {if (!(key in cls)) {throw new Error(errorMessage + key + '".');}}
    for (key in intfc.prototype) {if (!(key in cls.prototype)) {throw new Error(errorMessage + key + '".');}}
}

var AbstractClass = class_(function(){
    function AbstractClass () {}
    implementation_(AbstractClass, [
          constructor_(function () {var instance = new AbstractClass(); return instance;})
        , destructor_(function () {})
    ]);
    AbstractClass.super_ = Object.prototype;
    return AbstractClass;
});

var ParentClass = class_(function(){
    function ParentClass () {}
    extend_(ParentClass, AbstractClass);
    implementation_(ParentClass, [
          constructor_(function (initVar) {
                var instance = new ParentClass();
                instance.initVar = initVar;
                var privateVar = 'ParentClass private var';
                function privateFunction () {return 'ParentClass private function can show ' + privateVar + ' and ' + instance._privateMethod();}
                instance.eventFunction = function () {alert(privateFunction());}
                document.addEventListener('click', instance.eventFunction, false);
                return instance;
          })
        , destructor_(function () {
                document.removeEventListener('click', this.eventFunction, false);
                console.log('ParentClass destroyed.');
          })
        , default_('defaultVar', 'ParentClass default var.')
        , public_('publicMethod', function () {return 'ParentClass public method.';})
        , private_('_privateMethod', function () {return 'ParentClass private method.';})
        , final_('finalMethod', function () {return 'ParentClass final method.';})
        , static_('staticMethod', function () {return 'ParentClass static method.';})
    ]);
    return ParentClass;
});

var parentObject = ParentClass.new_('ParentClass init var');
console.log(parentObject.constructor.name);
console.log(parentObject.defaultVar);
console.log(parentObject.initVar);
console.log(parentObject.publicMethod());
console.log(parentObject.finalMethod());
console.log(ParentClass.staticMethod());
setTimeout(function(){parentObject.destroy_(); parentObject = null;}, 5000);

console.log('----------------------------------------');

var MixinClass = class_(function(){
    function MixinClass () {}
    implementation_(MixinClass, [
          public_('mixinPublicMethod', function () {return 'MixinClass public method.';})
        , static_('mixinStaticMethod', function () {return 'MixinClass static method.';})
    ]);
    return MixinClass;
});

var ChildClass = class_(function(){
    function ChildClass () {}
    extend_(ChildClass, ParentClass);
    implementation_(ChildClass, [
          constructor_(function (initVar) {
                var instance = new ChildClass();
                instance.initVar = initVar;
                return instance;
          })
        , destructor_(function () {console.log('ChildClass destroyed.');})
        , override_('publicMethod', function () {return 'ChildClass public method.';})
    ]);
    mixin_(ChildClass, MixinClass);
    return ChildClass;
});

var childObject = ChildClass.new_('ChildClass init var');
console.log(childObject.constructor.name);
console.log(childObject.defaultVar);
console.log(childObject.initVar);
console.log(childObject.publicMethod());
console.log(childObject.finalMethod());
console.log(ChildClass.staticMethod());
console.log(childObject.mixinPublicMethod());
console.log(ChildClass.mixinStaticMethod());
setTimeout(function(){childObject.destroy_(); childObject = null;}, 5000);

console.log('----------------------------------------');

var SingletonClassInterface = interface_(function(){
    function SingletonClassInterface () {}
    implementation_(SingletonClassInterface, [
          singleton_()
        , constructor_()
        , destructor_()
        , default_('defaultVar')
        , public_('publicMethod')
        , private_('_privateMethod')
        , final_('finalMethod')
        , static_('staticMethod')
        , public_('mixinPublicMethod')
        , static_('mixinStaticMethod')
    ]);
    return SingletonClassInterface;
});

var SingletonClass = class_(function(){
    function SingletonClass () {}
    extend_(SingletonClass, ChildClass);
    implementation_(SingletonClass, [
          singleton_()
        , constructor_(function (initVar) {
                if (SingletonClass.instance_) {return SingletonClass.instance_;}
                var instance = create_singleton_(SingletonClass);
                instance.initVar = initVar;
                return instance;
          })
        , destructor_(function () {console.log('SingletonClass destroyed.');})
    ]);
    impliment_(SingletonClass, SingletonClassInterface);
    return SingletonClass;
});

var singletonObject1 = SingletonClass.new_('SingletonClass init var 1');
var singletonObject2 = SingletonClass.new_('SingletonClass init var 2');
console.log('Is singleton? ' + (singletonObject1 === singletonObject2));
console.log(singletonObject1.constructor.name);
console.log(singletonObject1.defaultVar);
console.log(singletonObject1.initVar);
console.log(singletonObject1.publicMethod());
console.log(singletonObject1.finalMethod());
console.log(SingletonClass.staticMethod());
console.log(singletonObject1.mixinPublicMethod());
console.log(SingletonClass.mixinStaticMethod());
setTimeout(function(){singletonObject1.destroy_(); singletonObject1 = null; singletonObject2 = null;}, 5000);

console.log('----------------------------------------');

function Enum () {
    var i, len = arguments.length, allValues;
    for (i = 0; i < len; i++) {
        this[arguments[i]] = i;
    }
    this.allValues = Array.prototype.slice.call(arguments);
}

Enum.prototype.values = function () {
    return this.allValues;
};

var Color = new Enum('RED', 'GREEN', 'BLUE');

console.log(Color.RED);
console.log(Color.GREEN);
console.log(Color.BLUE);
console.log(Color.values());

console.log('----------------------------------------');

function class_2 (cls) {
    var classFunction;
    function AbstractClass () {}
    AbstractClass.new_ = function () {var instance = new AbstractClass(); return instance;};
    AbstractClass.prototype.destroy = function () {};
    AbstractClass.super_ = Object.prototype;
    if (cls && cls.name_ && cls.body_) {
        classFunction = (new Function('return function ' + cls.name_ + ' () {}'))();
        if (cls.extends_) {extend_(classFunction, cls.extends_);} else {extend_(classFunction, AbstractClass);}
        implementation_(classFunction, cls.body_);
        if (cls.mixin_) {mixin_(classFunction, cls.mixin_);}
        if (cls.impements_) {impliment_(classFunction, cls.impements_);}
        return classFunction;
    } else {
        throw new Error('Class name and body must be specified.');
    }
}

function interface_2 (intfc) {
    return class_2(intfc);
}

var SingletonClassInterface2 = interface_2({
      name_: 'SingletonClassInterface2'
    , extends_: SingletonClassInterface
    , body_: [
          singleton_()
        , constructor_()
        , destructor_()
        , default_('defaultVar')
        , public_('publicMethod')
        , private_('_privateMethod')
        , final_('finalMethod')
        , static_('staticMethod')
        , public_('mixinPublicMethod')
        , static_('mixinStaticMethod')
    ]
});

var ParentClass2 = class_2({
      name_: 'ParentClass2'
    , extends_: ParentClass
    , impements_: SingletonClassInterface2
    , mixin_: MixinClass
    , body_: [
          singleton_()
        , constructor_(function (initVar) {
                if (ParentClass2.instance_) {return ParentClass2.instance_;}
                var instance = create_singleton_(ParentClass2);
                instance.initVar = initVar;
                return instance;
          })
        , destructor_(function () {console.log('ParentClass2 destroyed.');})
        , override_('publicMethod', function () {return 'ParentClass2 public method.';})
      ]
});

var singletonParentObject21 = ParentClass2.new_('Singleton ParentClass2 init var 1');
var singletonParentObject22 = ParentClass2.new_('Singleton ParentClass2 init var 2');
console.log('Is singleton? ' + (singletonParentObject21 === singletonParentObject22));
console.log(singletonParentObject21.constructor.name);
console.log(singletonParentObject21.defaultVar);
console.log(singletonParentObject21.initVar);
console.log(singletonParentObject21.publicMethod());
console.log(singletonParentObject21.finalMethod());
console.log(ParentClass2.staticMethod());
console.log(singletonParentObject21.mixinPublicMethod());
console.log(ParentClass2.mixinStaticMethod());
setTimeout(function(){singletonParentObject21.destroy_(); singletonParentObject21 = null; singletonParentObject22 = null;}, 5000);

console.log('----------------------------------------');

function ClassicalClass (initVar) {
    this.initVar = initVar;
}

ClassicalClass.staticMethod = function () {return 'ClassicalClass static method.';};

ClassicalClass.prototype = {
      defaultVar: 'ClassicalClass default var.'
    , publicMethod: function () {return 'ClassicalClass public method.';}
    , _privateMethod: function () {return 'ClassicalClass private function can show ' + this.initVar;}
    , destroy: function () {console.log('ClassicalClass destroyed.');}
    , constructor: ClassicalClass
}

var classicalObject = new ClassicalClass('ClassicalClass init var.');
console.log(classicalObject.constructor.name);
console.log(classicalObject.defaultVar);
console.log(classicalObject.initVar);
console.log(classicalObject.publicMethod());
console.log(classicalObject._privateMethod());
console.log(ClassicalClass.staticMethod());
setTimeout(function(){classicalObject.destroy(); classicalObject = null;}, 5000);

console.log('----------------------------------------');

</script>
</body>
</html>

Dynamic function name in JavaScript

'use strict';
var name = 'foo';
var func = new Function('return function ' + name + ' () {alert("sweet!");}')();

//call it, to test it
func();

// returns the function named with the passed name
function namedFunction (name, fn) {
    return new Function('fn', 'return function ' + name + ' () {return fn.apply(this, arguments);}';
)(fn)

вторник, 21 июля 2015 г.

JavaScript - Loading JavaScript source code synchronously

function loadJS (file) {
    var js = $.ajax({
          type: 'GET'
        , url: file
        , async: false
    }).responseText; // No need to append
}

console.log('Test is loading...');
loadJS('test.js');
console.log('Test was loaded:', window.loadedModule); // loadedModule come from test.js

среда, 15 июля 2015 г.

Unminify JavaScript

Сайт для форматирования сжатого JavaScript-кода: unminify.com

JavaScript RegExp tester

Сайт для тестирования регулярных выражений: regexr.com

Оптимизация jQuery (optimization)

jQuery optimize selector performance

Best way

var $arms = $( "#container" ).find( "div.robotarm" );

or

var $arms = $( ".containers" ).find( "div.robotarms" );

or

var $radioButtons = $( ".category ).find( input:radio" );

Use ID selector with find().
Use tag.class if possible on your right-most selector, and just tag or just .class on the left.
Avoid Excessive Specificity. Better: Drop the middle if possible.
Avoid the Universal Selector *.

Append Outside of Loops

var myHtml = "";
$.each( myArray, function( i, item ) {
    myHtml += "<li>" + item + "</li>";
});
$( "#ballers" ).html( myHtml );

Cache Length During Loops

var myLength = myArray.length;
for ( var i = 0; i < myLength; i++ ) {
    // do stuff
}

Detach Elements to Work with Them.
The DOM is slow. Use detach() to remove an element from the DOM while you work with it.

var table = $( "#myTable" );
var parent = table.parent();

table.detach();
// ... add lots and lots of rows to table
parent.append( table );

Don’t Act on Absent Elements

// Bad: This runs three functions before it
// realizes there's nothing in the selection
$( "#nosuchthing" ).slideUp();

// Better:
var elem = $( "#nosuchthing" );
if ( elem.length ) {
    elem.slideUp();
}

// Best: Add a doOnce plugin.
jQuery.fn.doOnce = function( func ) {
    this.length && func.apply( this );
    return this;
}

$( "li.cartitems" ).doOnce(function() {

    // make it ajax!
});

Use Stylesheets for Changing CSS on Many Elements.

// Fine for up to 20 elements, slow after that:
$( "a.swedberg" ).css( "color", "#0769ad" );

// Much faster:
$( "<style type=\"text/css\">a.swedberg { color: #0769ad }</style>").appendTo( "head" );

Beware Anonymous Functions

// BAD
$( document ).ready(function() {

    $( "#magic" ).click(function( event ) {
        $( "#yayeffects" ).slideUp(function() {
            // ...
        });
    });

    $( "#happiness" ).load( url + " #unicorns", function() {
        // ...
    });

});

// BETTER
var PI = {

    onReady: function() {
        $( "#magic" ).click( PI.candyMtn );
        $( "#happiness" ).load( PI.url + " #unicorns", PI.unicornCb );
    },

    candyMtn: function( event ) {
        $( "#yayeffects" ).slideUp( PI.slideCb );
    },

    slideCb: function() { ... },

    unicornCb: function() { ... }

};

$( document ).ready( PI.onReady );

Code Organization Concepts

// Using an object literal for a jQuery feature
var myFeature = {
    init: function( settings ) {
        myFeature.config = {
            items: $( "#myFeature li" ),
            container: $( "<div class='container'></div>" ),
            urlBase: "/foo.php?item="
        };

        // Allow overriding the default config
        $.extend( myFeature.config, settings );

        myFeature.setup();
    },

    setup: function() {
        myFeature.config.items
            .each( myFeature.createContainer )
            .click( myFeature.showItem );
    },

    createContainer: function() {
        var item = $( this );
        var container = myFeature.config.container
            .clone()
            .appendTo( item );
        item.data( "container", container );
    },

    buildUrl: function() {
        return myFeature.config.urlBase + myFeature.currentItem.attr( "id" );
    },

    showItem: function() {
        myFeature.currentItem = $( this );
        myFeature.getContent( myFeature.showContent );
    },

    getContent: function( callback ) {
        var url = myFeature.buildUrl();
        myFeature.currentItem.data( "container" ).load( url, callback );
    },

    showContent: function() {
        myFeature.currentItem.data( "container" ).show();
        myFeature.hideContent();
    },

    hideContent: function() {
        myFeature.currentItem.siblings().each(function() {
            $( this ).data( "container" ).hide();
        });
    }
};

$( document ).ready( myFeature.init );

The Module Pattern

// The module pattern
var feature = (function() {

    // Private variables and functions
    var privateThing = "secret";
    var publicThing = "not secret";

    var changePrivateThing = function() {
        privateThing = "super secret";
    };

    var sayPrivateThing = function() {
        console.log( privateThing );
        changePrivateThing();
    };

    // Public API
    return {
        publicThing: publicThing,
        sayPrivateThing: sayPrivateThing
    };
})();

feature.publicThing; // "not secret"

// Logs "secret" and changes the value of privateThing
feature.sayPrivateThing();

// Using the module pattern for a jQuery feature
$( document ).ready(function() {
    var feature = (function() {
        var items = $( "#myFeature li" );
        var container = $( "<div class='container'></div>" );
        var currentItem = null;
        var urlBase = "/foo.php?item=";

        var createContainer = function() {
            var item = $( this );
            var _container = container.clone().appendTo( item );
            item.data( "container", _container );
        };

        var buildUrl = function() {
            return urlBase + currentItem.attr( "id" );
        };

        var showItem = function() {
            currentItem = $( this );
            getContent( showContent );
        };

        var showItemByIndex = function( idx ) {
            $.proxy( showItem, items.get( idx ) );
        };

        var getContent = function( callback ) {
            currentItem.data( "container" ).load( buildUrl(), callback );
        };

        var showContent = function() {
            currentItem.data( "container" ).show();
            hideContent();
        };

        var hideContent = function() {
            currentItem.siblings().each(function() {
                $( this ).data( "container" ).hide();
            });
        };

        items.each( createContainer ).click( showItem );

        return {
            showItemByIndex: showItemByIndex
        };
    })();

    feature.showItemByIndex( 0 );
});

jQuery plugins

$.fn.greenify = function() {
    this.css( "color", "green" );
    return this;
}

$( "a" ).greenify().addClass( "greenified" ); // Makes all the links green.

// Protecting the $ Alias and Adding Scope
(function( $ ) {

    $.fn.showLinkLocation = function() {

        this.filter( "a" ).each(function() {
            var link = $( this );
            link.append( " (" + link.attr( "href" ) + ")" );
        });

        return this;

    };

}( jQuery ));

// Usage example:
$( "a" ).showLinkLocation();

пятница, 10 июля 2015 г.

JavaScript name style

Use:
functionNamesLikeThis
variableNamesLikeThis
ClassNamesLikeThis
EnumNamesLikeThis
methodNamesLikeThis
CONSTANT_VALUES_LIKE_THIS
foo.namespaceNamesLikeThis.bar
file-names-like-this.js
_privatePropertyNamesLikeThis
protectedPropertyNamesLikeThis
$jqueryObjectNamesLikeThis