Pertanyaan Bagaimana cara mendeklarasikan namespace di JavaScript?


Bagaimana cara membuat namespace di JavaScript sehingga objek dan fungsi saya tidak ditimpa oleh objek dan fungsi lain yang bernama sama? Saya telah menggunakan yang berikut:

if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}

Apakah ada cara yang lebih elegan atau ringkas untuk melakukan ini?


919
2018-05-19 08:11


asal


Jawaban:


Saya suka ini:

var yourNamespace = {

    foo: function() {
    },

    bar: function() {
    }
};

...

yourNamespace.foo();

713
2018-05-19 08:22



saya menggunakan pendekatan yang ditemukan di situs jQuery Enterprise:

Berikut adalah contoh mereka yang menunjukkan cara mendeklarasikan properti dan fungsi pribadi & umum. Semuanya dilakukan sebagai fungsi anonim yang mengeksekusi diri sendiri.

(function( skillet, $, undefined ) {
    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }
}( window.skillet = window.skillet || {}, jQuery ));

Jadi jika Anda ingin mengakses salah satu anggota publik, Anda cukup pergi skillet.fry() atau skillet.ingredients.

Apa yang benar-benar keren adalah Anda sekarang dapat memperluas namespace menggunakan sintaks yang sama persis.

//Adding new Functionality to the skillet
(function( skillet, $, undefined ) {
    //Private Property
    var amountOfGrease = "1 Cup";

    //Public Method
    skillet.toString = function() {
        console.log( skillet.quantity + " " +
                     skillet.ingredient + " & " +
                     amountOfGrease + " of Grease" );
        console.log( isHot ? "Hot" : "Cold" );
    };
}( window.skillet = window.skillet || {}, jQuery ));

Ketiga undefined argumen

Ketiga, undefined Argumen adalah sumber variabel nilai undefined. Saya tidak yakin apakah itu masih relevan hari ini, tetapi ketika bekerja dengan browser yang lebih tua / standar JavaScript (ecmascript 5, javascript <1.8.5 ~ firefox 4), variabel lingkup global undefined dapat ditulis, sehingga siapa pun dapat menulis ulang nilainya. Argumen ketiga (ketika tidak lulus nilai) membuat variabel bernama undefined yang di-scoped ke namespace / function. Karena tidak ada nilai yang dilewatkan ketika Anda membuat ruang nama, defaultnya adalah nilai undefined.


1015
2018-05-10 08:28



Cara lain untuk melakukannya, yang saya anggap sebagai sedikit lebih membatasi daripada bentuk literal objek, adalah ini:

var ns = new function() {

    var internalFunction = function() {

    };

    this.publicFunction = function() {

    };
};

Di atas sangat mirip pola modul dan Apakah Anda suka atau tidak, memungkinkan Anda untuk mengekspos semua fungsi Anda sebagai publik, sambil menghindari struktur kaku objek literal.


334
2018-05-19 08:39



Apakah ada cara yang lebih elegan atau ringkas untuk melakukan ini?

Iya nih. Sebagai contoh:

var your_namespace = your_namespace || {};

maka Anda dapat memilikinya

var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg) 
{
    alert(arg);
};
with(your_namespace)
{
   Bar(Foo.toAlert);
}

154
2018-05-26 11:34



Saya biasanya membangunnya dalam penutupan:

var MYNS = MYNS || {};

MYNS.subns = (function() {

    function privateMethod() {
        // Do private stuff, or build internal.
        return "Message";
    }

    return {
        someProperty: 'prop value',
        publicMethod: function() {
            return privateMethod() + " stuff";
        }
    };
})();

Gaya saya selama bertahun-tahun telah mengalami perubahan halus sejak menulis ini, dan saya sekarang menemukan diri saya menulis penutup seperti ini:

var MYNS = MYNS || {};

MYNS.subns = (function() {
    var internalState = "Message";

    var privateMethod = function() {
        // Do private stuff, or build internal.
        return internalState;
    };
    var publicMethod = function() {
        return privateMethod() + " stuff";
    };

    return {
        someProperty: 'prop value',
        publicMethod: publicMethod
    };
})();

Dengan cara ini saya menemukan API publik dan implementasi lebih mudah dipahami. Pikirkan pernyataan kembali sebagai antarmuka publik untuk implementasi.


88
2018-05-20 20:07



Karena Anda dapat menulis file yang berbeda dari JavaScript dan kemudian menggabungkan atau tidak menggabungkannya dalam aplikasi, masing-masing perlu dapat memulihkan atau membangun objek namespace tanpa merusak pekerjaan file lain ...

Satu file mungkin berniat menggunakan namespace namespace.namespace1:

namespace = window.namespace || {};
namespace.namespace1 = namespace.namespace1 || {};

namespace.namespace1.doSomeThing = function(){}

File lain mungkin ingin menggunakan namespace namespace.namespace2:

namespace = window.namespace || {};
namespace.namespace2 = namespace.namespace2 || {};

namespace.namespace2.doSomeThing = function(){}

Kedua file ini dapat hidup bersama atau terpisah tanpa bertabrakan.


55
2017-11-09 04:27



Begini cara Stoyan Stefanov melakukannya dalam bukunya Pola JavaScript buku yang saya temukan sangat bagus (itu juga menunjukkan bagaimana dia melakukan komentar yang memungkinkan untuk dokumentasi API yang dihasilkan secara otomatis, dan bagaimana cara menambahkan metode ke prototipe objek khusus):

/**
* My JavaScript application
*
* @module myapp
*/

/** @namespace Namespace for MYAPP classes and functions. */
var MYAPP = MYAPP || {};

/**
* A maths utility
* @namespace MYAPP
* @class math_stuff
*/
MYAPP.math_stuff = {

    /**
    * Sums two numbers
    *
    * @method sum
    * @param {Number} a First number
    * @param {Number} b Second number
    * @return {Number} Sum of the inputs
    */
    sum: function (a, b) {
        return a + b;
    },

    /**
    * Multiplies two numbers
    *
    * @method multi
    * @param {Number} a First number
    * @param {Number} b Second number
    * @return {Number} The inputs multiplied
    */
    multi: function (a, b) {
        return a * b;
    }
};

/**
* Constructs Person objects
* @class Person
* @constructor
* @namespace MYAPP
* @param {String} First name
* @param {String} Last name
*/
MYAPP.Person = function (first, last) {

    /**
    * First name of the Person
    * @property first_name
    * @type String
    */
    this.first_name = first;

    /**
    * Last name of the Person
    * @property last_name
    * @type String
    */
    this.last_name = last;
};

/**
* Return Person's full name
*
* @method getName
* @return {String} First name + last name
*/
MYAPP.Person.prototype.getName = function () {
    return this.first_name + ' ' + this.last_name;
};

46
2018-04-22 15:44