zoukankan      html  css  js  c++  java
  • 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>

    差不多是这样子

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

  • 相关阅读:
    MVC3、如何应用EntityFramework 连接MySql 数据库 Kevin
    DEV EXPRESS Summary Footer 不显示 Kevin
    装饰模式 Kevin
    Dev 控件 GridControl 控件 二次绑定数据源的问题。 Kevin
    System.InvalidOperationException 异常 Kevin
    LINQ to XML Kevin
    代理模式——代码版“吊丝的故事” Kevin
    VS2012 中的设备 面板 Kevin
    maven 学习笔记(三)创建一个较复杂的 eclipse+android+maven 工程
    maven 学习笔记(一)eclipse+android+maven
  • 原文地址:https://www.cnblogs.com/catherinezyr/p/7426912.html
Copyright © 2011-2022 走看看