javascript JS OOP方式 - Zdrojak.cz

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript JS OOP方式 - Zdrojak.cz相关的知识,希望对你有一定的参考价值。

/// 1. Jediná globální proměnná /// 

var myApplication =  (function(){
        function(){
            /*...*/
        },
        return{
            /*...*/
        }
})();
/// 2. Zápis objektovým literálem ///
var myApplication = {
    getInfo:function(){ /**/ },

    // můžeme rozšířit náš objektový literál a připravit
    // další vložené objekty, které mohou obsahovat
    // opět cokoli:
    models : {},
    views : {
        pages : {}
    },
    collections : {}
};

//Můžeme si rovněž zvolit cestu přímého přidávání vlastností do jmenného prostoru:
myApplication.foo = function(){
    return "bar";
}

myApplication.utils = {
    toString:function(){
        /*..*/
    },
    export: function(){
        /*..*/
    }
}


// Nekontroluje existenci 'myApplication' v globálním
// jmenném prostoru. To je špatný postup, při kterém
// snadno poškodíme existující proměnnou / NS stejného jména
var myApplication = {};

/*
Následující možnosti kontrolují existenci proměnné či namespace.
Pokud je definována, použijeme ji, jinak vytvoříme nový
objektový literál myApplication.
Možnost 1: var myApplication = myApplication || {};
Možnost 2  if(!MyApplication) MyApplication = {};
Možnost 3: var myApplication = myApplication = myApplication || {}
Možnost 4: myApplication || (myApplication = {});
Možnost 5: var myApplication = myApplication === undefined ? {} : myApplication;
*/


/* Existuje samozřejmě spousta variant jak a kde použít objektové literály k organizaci a strukturování kódu. U menších aplikací, kde chcete vystavit vnořené API konkrétního uzavřeného modulu, lze použít následující techniku, kdy vracíme rozhraní, které mohou využít další vývojáři. Je to obdoba vzoru pro moduly, kde jádro vzoru tvoří IIFE (viz další text) a vrácené rozhraní je objektový literál: */
var namespace = (function () {

    // definováno v lokálním scope
    var privateMethod1 = function () { /* ... */ }
    var privateMethod2 = function () { /* ... */ }
    var privateProperty1 = 'foobar';
    return {

        // vrácený objekt může být zanořen
        // do více úrovní, ačkoli, jak tu už zaznělo,
        // je tento způsob vhodnější pro malé aplikace
        // (alespoň podle mého)

        publicMethod1: privateMethod1,

        //zanořený jmenný prostor s veřejnou vlastností
        properties:{
            publicProperty1: privateProperty1
        },

        //testujeme další jmenný prostor
        utils:{
            publicMethod2: privateMethod2
        }
        ...
    }
})();


// config example

var myConfig = {
    language: 'english',
    defaults: {
        enableGeolocation: true,
        enableSharing: false,
        maxPhotos: 20
    },
    theme: {
        skin: 'a',
        toolbars: {
            index: 'ui-navigation-toolbar',
            pages: 'ui-custom-toolbar'
        }
    }
}

/// 3. Vnořené jmenné prostory ///
var myApp =  myApp || {};

// při definování potomků uděláme stejný test
myApp.routers = myApp.routers || {};
myApp.model = myApp.model || {};
myApp.model.special = myApp.model.special || {};

// vnořené jmenné prostory mohou být tak komplexní, jak je třeba:
// myApp.utilities.charting.html5.plotGraph(/*..*/);
// myApp.modules.financePlanner.getSummary();
// myApp.services.social.facebook.realtimeStream.getLatest();

//Stejně tak můžete vytvářet nové vnořené prostory pomocí indexovaných vlastností, např.:

myApp["routers"] = myApp["routers"] || {};
myApp["models"] = myApp["models"] || {};
myApp["controllers"] = myApp["controllers"] || {};
///  Immediately-invoked Function Expressions (IIFE)s ///

// Nejjednodušší verze IIFE může vypadat třeba takto:

// (anonymní) bezprostředně vyvolaný funkční výraz
(function(){ /*...*/})();

// pojmenovaný bezprostředně vyvolaný funkční výraz
(function foobar(){ /*..*/}());

// "self-executing function" by vypadala spíš takto, což je velký rozdíl
function foobar(){ foobar(); }

// ------------- //

// Lehce rozšířená verze prvního příkladu může vypadat třeba takto:
var namespace = namespace || {};

// zde je objekt "namespace" předán jako parametr funkce
// k němuž dodáme patřičné metody a vlastnosti
(function( o ){
    o.foo = "foo";
    o.bar = function(){
        return "bar";
    };
})(namespace);

console.log(namespace);

// ------------- //

// namespace (jméno našeho prostoru) a undefined jsou zde předávány
// proto, abychom se ujistili, že 1. prostor bude modifikován lokálně
// a není přepisován zvnějšku
// 2. aby hodnota "undefined" byla v našem kontextu opravdu nedefinovaná.
// Důvodem jsou problémy s undefined, který ve verzích před ES5 bylo možné
// změnit.
(function ( namespace, undefined ) {

    // soukromé vlastnosti
    var foo = "foo",
        bar = "bar";

    // veřejné metody a vlastnosti
    namespace.foobar = "foobar";
    namespace.sayHello = function () {
        speak("hello world");
    };

    // soukromá metoda
    function speak(msg) {
        console.log("You said: " + msg);
    };

    // zkontrolujeme, jestli "namespace" existuje v globálním objektu window
    // pokud ne, přiřadíme do window.namespace
    // prázdný objekt
}(window.namespace = window.namespace || {});

// otestujeme veřejné metody a vlastnosti
console.log(namespace.foobar); // foobar
namescpace.sayHello(); // hello world

// přidáme nové
namespace.foobar2 = "foobar";
console.log(namespace.foobar2);


// ------------- //
// pojďme přidat nové funkce do jmenného prostoru
(function( namespace, undefined ){
    // veřejná metoda
    namespace.sayGoodbye = function(){
        console.log(namespace.foo);
        console.log(namespace.bar);
        speak('goodbye');
    }
}( window.namespace = window.namespace || {});

namespace.sayGoodbye(); //goodbye
/// 5. Namespace injection , něco jako DI ///

var myApp = myApp || {};
myApp.utils =  {};

(function() {
    var val = 5;
    this.getValue = function() {
        return val;
    };
    this.setValue = function(newVal) {
        val = newVal;
    }
    // přidáme také nový jmenný prostor
    this.tools = {};
}).apply(myApp.utils);

// Přidáme novou funkci do prostoru tools
// který jsme definovali výše
(function(){
    this.diagnose = function(){
        return 'diagnosis';
    }
}).apply(myApp.utils.tools);

// všimněte si, že stejný postup může být použitý
// i u obyčejného IIFE, kdy předáme kontext jako parametr
// a budeme modifikovat tento kontext namísto implicitního
// 'this'

// testy
console.log(myApp); //the now populated namespace
console.log(myApp.utils.getValue()); // test get
myApp.utils.setValue(25); // test set
console.log(myApp.utils.getValue());
console.log(myApp.utils.tools.diagnose());

以上是关于javascript JS OOP方式 - Zdrojak.cz的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript之OOP

javascript 更好的JS-oop.js

OOP in Javascript

javascript JS OOP 101 for WCS

javascript JS OOP 101 for WCS,第2部分

JavaScript面向对象——JS OOP基础与JS 中This指向详解