javascript 命名空間與運用(前端基礎系列)


所謂代碼,當你隨便命名一個變量:var name = "ukerxi"; 就是一句代碼;但當你的代碼寫出來后,對於后續維護及閱讀的人,就可以看出代碼是否,易讀,易理解;優雅的代碼總是遵守一定的規范,這篇文章就說說幾種命名空間的運用,運用好了,可以有利於多人開發,模塊化代碼,代碼解耦有一定的作用!

先來看看一個錯誤的示范:

// 定義一些數據
var name = "ukerxi";
var version = "1.0.0";
var hobby = "riding";
sessionStorage.data = 'test';
sessionStorage.text = 'test';
sessionStorage.name = 'test';

利用命名空間進行重構:

var men = {
  name: 'ukerxi',
  version: '1.0.0',
  hobby: 'riding'
}
// 由於 sessionStorage 只支持字符型的數據,所以必須將數據進行JSON化處理 
sessionStorage.message = JSON.stringify({
  data: 'test',
  text: 'test',
  name: 'test',
});

重構后只產生了兩個全局變量,減少了命名沖突的概率,對於全局變量的使用,必須盡量減少,特別是單頁面開始時;而sessionStorage等本地存儲的使用更加注意,由於它們在多頁面之間可以互相訪問,很容易造成命名沖突;一下更具體的介紹幾種命名空間的使用:

 

一、使用單例對象進行包裹(單例模式)

var myObj = {
    name: "ukerxi"
};
myObj.fn = function{
   // do something
};

多人開發時,可以根據自己的名字進行命名一個對象,然后自己寫的變量及函數都放進這個命名空間中,這樣就避免與他人沖突;在實際開發時,還會遇到多個文件之間共享一個命名空間,可以使用命名空間檢測,避免重復或覆蓋;例如:

// 方法一
if (typeof myObj === "undefined") {
    var myObj = {};
}

// 方法二(推薦)
var myObj = myObj || {};

當你只是想對一個命名空間進行擴展,形如,對插件進行擴展,在JQuery.extend() 方法的擴展;

var myObj=(function(o){
        o.addFn = ""; // 實現擴展屬性功能
        return  o;
})(window.myObj || {});  // 必須或上空對象,以便在沒有事先聲明而使用引起的錯誤

 

二、閉包實現變量的包裹,減少全局變量

var myObj = (function () {
    // 私有變量
    var name = "ukerxi";

    // 返回get方法
    return {
        getName: function () {
            return name;
        }
    };
}());

// 可以變通成更加通用的命名空間
var commonObject = (function(){
    var _data = {
        name: "ukerxi",
        version: "1.0"
    }
    //返回get/set方法
    return {
        get: function(key){
            return _data[key];
        },
        set: function(key, value){
            // 檢測是否存在要設置的值在不在原本的數據中,這樣做是不添加新數據
            //如果要添加新數據,這句可以不加
            if(typeof _data[key] != "undefined"){
                _data[key] = value;
            }else{
                return false;
            }
        }
    }
}());

通過返回的getter、setter方法進行讀取及設置值,這樣就不用擔心變量命名沖突;

 

三、使用構造函數&原型方法,可以構造出更加強大的命名空間

function CommonObj(name) {
    // 私有變量
    // 此處可以不用定義內部的_name變量,因為參數也是私有變量
    var _name = name;
    // 公用方法
    this.getName = function () {
        return _name;
    };
}
CommonObj.prototype = (function () {
    //靜態私有變量,所有實例方法共享這個數據
    var _static = "static";
    // 
    return {
        getStatic: function () {
            return _static;
        }
    };
}());

var newObj1 = new CommonObj("obj1");
var newObj2 = new CommonObj("obj2");
// 測試輸出
console.log(newObj1.getName()); // -- "obj1"
console.log(newObj2.getName()); // -- "obj2"
console.log(newObj1.getStatic); // -- "static"
console.log(newObj2.getStatic); // -- "static"

最終每次實例化 CommonObj 構造函數時可以進行賦值,然而原型上的屬性是共享的;上面代碼看起來還是分散的,可以進一步進行改進;

var CommonObj = (function () {
    // 靜態私有變量
    var _static = "";
    function _fn(name) {
         // 公用方法
        this.getName = function () {
            return name;
        };
    }
    
    // 定義原型方法
    _fn.prototype ={
         getStatic: function () {
            return _static;
        }
    }
    // 返回真正的構造函數
    return _fn;
   
}());


var newObj1 = new CommonObj();
var newObj2 = new CommonObj();
// 測試輸出
console.log(newObj1.getName()); // -- "obj1"
console.log(newObj2.getName()); // -- "obj2"
console.log(newObj1.getStatic); // -- "static"
console.log(newObj2.getStatic); // -- "static"

 

四、函數的靜態調用與非靜態調用

主要特性是,通過類自身定義的屬性是不會被實例化函數擁有及繼承的,故也可以看做是一種命名空間,后續結合設計模式的“建造者”模式,可以創造出強大的一種運用形式;

// 構造函數
var MyObj = function (name) {
    this.name = name;
};

// 靜態方法
MyObj.getName = function () {
    console.log("test");
};

// 原型方法
MyObj.prototype.getName = function () {
    console.log(this.name);
};

// 靜態調用
MyObj.getName(); // "test"
// 實例化調用
var fn = new MyObj("ukerxi");
fn.getName(); // ukerxi
一種特別的自執行方式形成的命名

 

五、最后再介紹一種特別的自執行方式形成的命名空間

var CommonObj = ({
    fn: function() {console.log("test");},
    name: "ukerxi",
    init: function(){
        console.log(this.name);
        return this;
    }
}).init();

上面例子相當於新建一個對象,然后執行 init方法,最后返回 this 指向這個對象,最后CommonObj 就包含了新建對象的引用;當然實際運用中不建議這樣用,只是用來裝大神的;

 

【結束語】

   系列文章,包括了原創,翻譯,轉載等各類型的文章;一方面是為了自己總結,另一方面頁希望可以共享知識;在技術方面有輸入,也要有所輸出,才能更進一步!文章基於自己的實踐、閱讀及理解,如有不合理及錯誤的地方,煩請各大佬評論指出,以便改正,感謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM