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,'<').replace(/>/g,'>');
}
}; var sample = "<div>testing\changes</div>"; var result = jscbObject.stripslashes(sample);
result = jscbObject.removeAngleBrackets(result); console.log(result); //<div>testingchanges</div> </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的命名空间 && 单体模式 && 变量深拷贝和浅拷贝 && 页面弹窗设计的更多相关文章
- JS设计模式——5.单体模式
JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html 单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...
- JS设计模式之单体模式(Singleton)
单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对 ...
- JS设计模式——5.单体模式(用了这么久,竟全然不知!)
单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? 1.可以用它来划分命名空间(这个就是就是经常用的了) 2.利用分支技术来封装浏览器之间的差异(这个还真没用过,挺新鲜) 3.借 ...
- js 中数组或者对象的深拷贝和浅拷贝
浅拷贝 : 就是两个js 对象指向同一块内存地址,所以当obj1 ,obj2指向obj3的时候,一旦其中一个改变,其他的便会改变! 深拷贝:就是重新复制一块内存,这样就不会互相影响. 有些时候我们定义 ...
- C#原型模式(深拷贝、浅拷贝)
原型模式就是用于创建重复的对象,当想要创建一个新的对象但是开销比较大或者想将对象的当前状态保存下来的时候,我们就可以使用原型模式. 创建原型 public abstract class Base { ...
- 基于 Vue.js 2.0 酷炫自适应背景视频登录页面的设计『转』
本文讲述如何实现拥有酷炫背景视频的登录页面,浏览器窗口随意拉伸,背景视频及前景登录组件均能完美适配,背景视频可始终铺满窗口,前景组件始终居中,视频的内容始终得到最大限度的保留,可以得到最好的视觉效果. ...
- 如何做JS 单体模式的设计---->>js设计模式<<-------单体模式
1. 单体模式是js中最基本 单最有用的模式之一,非常常用. 单体模式的基本结构如下: var Person = { name: 'lilu', age:', sayHi: function(){ a ...
- 使用单体模式设计原生js插件
----------基于上次写的jquery插件进行改造 http://www.cnblogs.com/GerryOfZhong/p/5533773.html 背景:jQuery插件依赖jQuery ...
- js设计模式--单体模式
GOF里的23种设计模式, 也是在软件开发中早就存在并反复使用的模式. 如果程序员没有明确意识到他使用过某些模式, 那么下次他也许会错过更合适的设计 (这段话来自<松本行弘的程序世界>). ...
随机推荐
- PaddlePaddle Perceptron Example
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...
- 【leetcode】14-LongestCommonPrefix
problem Longest Common Prefix 挨个比较每个字符串的元素是否相同,连续对应位置字符都相同,则为共同字符:否则不是. code class Solution { public ...
- spring事务管理-Spring 源码系列(6)
Spring事务抽象的是事务管理和事务策略.而实现则由各种资源方实现的.我们最常用的数据库实现:DataSourceTransactionManager 尝试阅读一下spring 的实现代码,由3个核 ...
- Templates中的macro和include标签
1.macro标签 1.作用:相当于在模板中声名函数 2.使用方法: 语法:{% macro 名称(参数列表) %} xxx {% endmacro %} 创建 macro.html 模板文件 - ...
- Lua在Windows下的配置、安装、运行
Windows下安装.运行Lua! 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1↓ 进入Lua官网:h ...
- Tree Recovery
#include<stdio.h> #include<string.h> void build(int n,char*s1,char*s2) { )return ; ])-s2 ...
- LA3510 Pixel Shuffle
题意 PDF 分析 思路挺简单的,题目中的每个命令(包括命令的逆)相当于一个置换. 用\(O(n^2k)\)的时间复杂度从右往左求出这些置换的乘积A,然后求m使Am = I(I为全等置换) 还是先把A ...
- 刚开始学java和刚去工作的时候,1.path路径 2.classpath路径 还有JAVA_HOME相当于/dgs这个路径
把里面bin文件夹下面的可执行文件都配置到path路径下了,以后只要在Dos窗口输入命令就可以运行 无论是在dos窗口下还是在eclispe中只需要配置这个path变量,不需要配置classpath ...
- Scalable MySQL Cluster with Master-Slave Replication, ProxySQL Load Balancing and Orchestrator
MySQL is one of the most popular open-source relational databases, used by lots of projects around t ...
- tile38 server 密码保护
默认tile38 是没有密码保护的,我们可以通过配置指定密码,类似redis 的,但是redis 的一般我们是配置在 配置文件中的 环境准备 docker-compose 文件 version: ...