1. 程式人生 > >js的命名空間 && 單體模式 && 變量深拷貝和淺拷貝 && 頁面彈窗設計

js的命名空間 && 單體模式 && 變量深拷貝和淺拷貝 && 頁面彈窗設計

但是 界面 ket 模式 utf 針對 col con prop

說在前面:這是我近期開發或者看書遇到的一些點,覺得還是蠻重要的。

一、為你的 JavaScript 對象提供命名空間

<!DOCTYPE html>
<html>
<head>
    <title>為自己的js對象提供命名空間</title>
</head>
<body>
<div>封裝自己的數據和函數,防止和其他的庫搞混了</div>
<script>
    var jscbObject = {

  // return element
  getElem : function
(identifier) { return document.getElementById(identifier); }, stripslashes : function(str) { return str.replace(/\\/g, ‘‘); }, removeAngleBrackets: function(str) { return str.replace(/</g,‘&lt;‘).replace(/>/g,‘&gt;‘); } }; var sample = "<div>testing\changes</div>";
var result = jscbObject.stripslashes(sample); result = jscbObject.removeAngleBrackets(result); console.log(result); //&lt;div&gt;testingchanges&lt;/div&gt; </script> </body> </html>

以上例子, jscbObject 提供了不同的命名空間,封裝了函數 getElem() 、stripslashes() 、removeAngleBrackets(),防止和其他庫的函數重名。其實很簡單,很多人也寫過類似的代碼,但是不知道這種方式的含義。即使會寫,面試的時候,不一定能答得出來“什麽是命名空間?”。

二、單體模式

這個問題在C++、JAVA的面試題中都出現過。

好處:

1.可以用它來劃分命名空間。

2.利用分支技術來封裝瀏覽器之間的差異。

3.借助單體模式,可以把代碼組織的更為一致,方便閱讀與維護。

方法一:使用閉包

<!DOCTYPE html>
<html>
<head>
    <title>什麽是單例模式</title>
</head>
<body>
<script>
    var mySingleton = (function () {
 
  // Instance stores a reference to the Singleton
// 返回對象的引用 var instance; function init() {//創建實例的構造函數 // Singleton // Private methods and variables function privateMethod(){ console.log( "I am private" ); } var privateVariable = "Im also private"; var privateRandomNumber = Math.random(); return { // Public methods and variables publicMethod: function () { console.log( "The public can see me!" ); }, publicProperty: "I am also public", getRandomNumber: function() { return privateRandomNumber; } }; }; return { // Get the Singleton instance if one exists // or create one if it doesn‘t
  // 靜態方法獲得實例
getInstance: function () { if ( !instance ) { instance = init(); } return instance; } }; })(); singleA = mySingleton.getInstance(); var singleB = mySingleton.getInstance(); console.log( singleA.getRandomNumber() === singleB.getRandomNumber() ); //true </script> </body> </html>

在該函數中使用var和function關鍵字分別來定義其私有屬性和方法,這些在函數外部(單體對象外部)是無法直接訪問的,因為函數一執行完畢,其內部作用域的空間就會被回收,這也就是能夠利用閉包來模擬私有屬性和方法的原因所在。在該函數(閉包)中,同時最終返回一個對象,這個對象中包含一些公有方法和屬性,在外部可以直接調用,同時這些公有方法由於定義在函數內部,所以可以調用其私有屬性和方法,但是外界只能通過返回的公有方法和屬性來完成某些操作,不能夠直接調用Singleton.privateMethod 和 Singleton.privateVariable 這些屬性。這就使得該單體對象既隔離了外界去直接訪問其私有屬性和方法,又提供給外界一些共有屬性和方法去完成某些操作。

js載入的時候就創建了這個對象。在單體模式中,針對一個對象只能創建一個實例。單體可以在一個特定的時間實例化,而不是作為一個解決方案中所定義的一個靜態的構造而存在。上面示例中的單體使用一個立即調用的函數表達式(IIFE)將對象包裝起來,IIFE會立即返回對象的一個實例。但是,不只是任何的實例,如果已經存在一個實例,它不會返回一個新的實例。這個特性在後續代碼中得到了展示:

singleA = mySingleton.getInstance();
var singleB = mySingleton.getInstance();
console.log( singleA.getRandomNumber() === singleB.getRandomNumber() ); //true

它返回了當時創建對象時候所生成的一個隨機數,並且不管訪問哪一個“實例”,都會返回相同的隨機數。

方法二:對象字面量

var Singleton={
    name: nimei,
    age: 2,
    walk: function(){
        ...
    },
    eat: function(){
        ...
    }
}

這個單體對象的所有屬性和方法都是共有的,外部可隨時訪問和修改。

三、js變量的深拷貝與淺拷貝

JS中的數據類型有:字符串、數字、布爾、數組、對象、Null、Undefined(Undefined 這個值表示變量不含有值,可以通過將變量的值設置為 null 來清空變量)。

對於字符串類型、數字、布爾的淺復制是對值的復制。對於數組和對象來說,淺復制是對對象地址的復制,並沒有開辟新的棧,也就是復制的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另一個對象的屬性也會改變。而深復制則是開辟新的棧,兩個對象對應兩個不同的地址,修改一個對象的屬性,不會改變另一個對象的屬性。

<!DOCTYPE html>
<html>
<head>
    <title>淺拷貝與深拷貝</title>
</head>
<body>
<script>

    var str1 = "Nice to meet you!";
    var str2 = str1;
    str2 = ‘He is called "Bill"‘;
    console.log(" str1  " + str1 +"  str2  " + str2); // str1  Nice to meet you!  str2  He is called "Bill"

    var num1 = 1;      
    var num2 = num1;        
    num2 = 3;
    console.log(‘ num1  ‘ + num1 +"  num2  " + num2); // num1  1  num2  3


    var bool1 = true;
    var bool2 = bool1;
    bool2 = false;
    console.log(‘ bool1  ‘ +bool1 + "  bool2  " + bool2); // bool1  true  bool2  false

    var arr1 = [‘one‘ , ‘two‘ , ‘three‘];
    var arr2 = arr1;
    arr2[1] = ‘change‘;
    console.log(‘ arr1  ‘ + arr1 + "  arr2 " +arr2); // arr1  one,change,three  arr2 one,change,three  

    var obj1 = {
        firstname : "Bill",
        lastname  : "Gates",
        id        :  5566
        };
    var obj2 = obj1;
    obj2.firstname = ‘Bob‘;
    console.log(‘ obj1.firstname  ‘ + obj1.firstname + "  obj2.firstname  " + obj2.firstname); // obj1.firstname  Bob  obj2.firstname  Bob
</script>
</body>
</html>

由以上示例可知,對於數據類型 “字符串、數字、布爾”,直接淺拷貝即可復制。對於數據類型“ 數組、對象”,若要復制變量的值,只能深拷貝。

網上找到一個很好的深拷貝方法:

<!DOCTYPE html>
<html>
<head>
    <title>淺拷貝與深拷貝</title>
</head>
<body>
<script>

    var cloneObj = function(obj){
    var str, newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== ‘object‘){
        return;
    } else if(window.JSON){
        str = JSON.stringify(obj), //系列化對象
        newobj = JSON.parse(str); //還原
    } else {
        for(var i in obj){
            newobj[i] = typeof obj[i] === ‘object‘ ? 
            cloneObj(obj[i]) : obj[i]; 
        }
    }
    return newobj;
};

    var arr1 = [‘one‘ , ‘two‘ , ‘three‘];
    var arr2 = cloneObj(arr1);
    arr2[1] = ‘change‘;
    console.log(‘ arr1  ‘ + arr1 + "  arr2 " +arr2); // arr1  one,two,three  arr2 one,change,three

    var obj1 = {
        firstname : "Bill",
        lastname  : "Gates",
        id        :  5566
        };
    var obj2 = cloneObj(obj1);
    obj2.firstname = ‘Bob‘;
    console.log(‘ obj1.firstname  ‘ + obj1.firstname + "  obj2.firstname  " + obj2.firstname); // obj1.firstname  Bill   obj2.firstname  Bob
</script>
</body>
</html>

可是在拷貝有些很復雜的對象的時候,會出現錯誤:

技術分享

因為上述cloneObj() 中是用來遞歸,如果需要復制的 object 對象太大,遞歸次數太多導致內存被耗費太多,就會出現棧溢出的錯誤,這時候就得根據對象內容重新重新寫clone()函數了。

可參考:http://blog.csdn.net/sysuzhyupeng/article/details/70340598

四、頁面彈窗設計

彈窗1:警告框

<!DOCTYPE html>
<html>
<head>
<script>
function myFunction()
{
    alert("你好,我是一個警告框!");//方法一:alert
}
</script>
</head>
<body>

<input type="button" onclick="myFunction()" value="顯示警告框">

</body>
</html>

彈窗2:確認框

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>點擊按鈕,顯示確認框。</p>
<button onclick="myFunction()">點我</button>
<p id="demo"></p>
<script>
function myFunction(){
    var x;
    var r=confirm("按下按鈕!");
    if (r==true){
        x="你按下了\"確定\"按鈕!";
    }
    else{
        x="你按下了\"取消\"按鈕!";
    }
    document.getElementById("demo").innerHTML=x;
}
</script>

</body>
</html>

彈窗3:提示框

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>點擊按鈕查看輸入的對話框。</p>
<button onclick="myFunction()">點我</button>
<p id="demo"></p>
<script>
function myFunction(){
    var x;
    var person=prompt("請輸入你的名字","Harry Potter");
    if (person!=null && person!=""){
        x="你好 " + person + "! 今天感覺如何?";
        document.getElementById("demo").innerHTML=x;
    }
}
</script>
</body>
</html>

彈窗4:模擬百度登錄頁面的彈窗

<!DOCTYPE html>
<html>
<head>
    <title>淺拷貝與深拷貝</title>
    <style type="text/css">
    #mask {
        position:fixed;
        width: 100%;
        height: 100%;
        background-color: rgba(0,0,0,0.5);
        display: none;
        color: #888;
}
    #win{
        display:none;
        width: 300px;
        height: 700px;
        left: 35%;
        position: absolute;
        overflow: auto;
        background-color: #111;
        color: #888;
}
    </style>
</head>
<body height = 100%>
<div id="mask"></div>
<div id="win">
    <p>彈出窗口,父頁面不可點擊,只能操作彈出的頁面,類似於百度的登錄界面。可在彈出框頁面加入表單、按鈕等任何組件。</p>
    <button onclick = "closeWin()">隱藏</button>
</div>
<button onclick = "openWin()">彈出</button>

<script>
            function openWin(){
                document.getElementById("mask").style.display = "block";
                document.getElementById("win").style.display = "block"
            }
            function closeWin(){
                document.getElementById("mask").style.display = "none";
                document.getElementById("win").style.display = "none"
            }
            
</script>
</body>
</html>

技術分享

彈窗5:模擬客戶端的可移動的功能彈窗

<!DOCTYPE html>
<html>
<head>
    <title>淺拷貝與深拷貝</title>
    <style type="text/css">
    #mask {
        position:fixed;
        height: 100%;
        background-color: rgba(0,0,0,0.5);
        display: none;
        color: #888;
}
    #win{
        display:none;
        width: 300px;
        height: 700px;
        left: 35%;
        position: absolute;
        overflow: auto;
        background-color: #111;
        color: #888;
}
    </style>
    <script type="text/javascript" src="jquery-3.2.1.js"></script>
    <script type="text/javascript" src="jquery-ui.min.js"></script>
</head>
<body height = 100%>
<div id="mask"></div>
<div id="win">
    <p>彈出窗口,父頁面可點擊,可同時操作父頁面和彈出頁面。可在彈出框頁面加入表單、按鈕等任何組件。</p>
    <button onclick = "closeWin()">隱藏</button>
</div>
<button onclick = "openWin()">彈出</button>

<script>
            function openWin(){
                document.getElementById("mask").style.display = "block";
                document.getElementById("win").style.display = "block"
            }
            function closeWin(){
                document.getElementById("mask").style.display = "none";
                document.getElementById("win").style.display = "none"
            }
            $(function() {
                $( "#win" ).draggable();
              });
</script>
</body>
</html>

差不多是這樣子

技術分享

希望能幫到別人,喜歡就麻煩點個贊鼓勵鼓勵哈^_^

js的命名空間 && 單體模式 && 變量深拷貝和淺拷貝 && 頁面彈窗設計