• js的命名空间 && 单体模式 && 变量深拷贝和浅拷贝 && 页面弹窗设计


    说在前面:这是我近期开发或者看书遇到的一些点,觉得还是蛮重要的。

    一、为你的 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>testingchanges</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;
             100%;
            height: 100%;
            background-color: rgba(0,0,0,0.5);
            display: none;
            color: #888;
    }
        #win{
            display:none;
             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;
             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>

    差不多是这样子

    希望能帮到别人,喜欢就麻烦点个赞鼓励鼓励哈^_^

  • 相关阅读:
    ArrayList,HashSet以及HashMap(2019年10月23日)
    (面试题)String,Random,Math 等一些Object对象(2019年10月22日)
    南开大学2014年硕士研究生入学考试高代试题(回忆版)
    南开大学2014年高等代数部分试题解答
    搜集到的数学分析例题(不断更新)
    武汉大学2012年数学分析试题解答
    分析力学复习笔记(更新中)
    电子结构引论读书笔记:第三章-Hartree-Fock近似
    电子结构引论读书笔记:第二章-多电子波函数和算符
    DNA电荷转移:电阻的计算公式 & Marcus电子转移理论
  • 原文地址:https://www.cnblogs.com/catherinezyr/p/7426912.html
Copyright © 2020-2023  润新知