javascript“命名空间”的费曼输出[原创]
Javascript由于没有命名空间的概念,所以好多的框架或库就用了某些“命名空间”的技巧。在学习作为函数的命名空间时,我翻阅了好多的书本和blog,很多的概念和说明都是要么过于烦杂或过于简单。现在由我来进行一个的系统的描述和介绍。
一、浏览器启动后的初步理解
1.我们要上网,就要打开浏览器,输入网址,浏览器就负责渲染和相应用户的鼠标动作。而打开浏览器这个进程后,浏览器的网络线程负责解析网址为ip地址,去网页服务器下载网页文件到本地硬盘,我就称这个线程是network线程;另外一个线程是负责解析网页文件的html和css代码,渲染界面,我就称这个线程是view线程;还有一个线程是负责解析javascript的代码,我称这个线程是js虚拟机线程,该js虚拟机线程会根据Window构造函数,实例化一个window对象。注意这个Window和window是不同的,Window是一坨在未运行的代码,而window是加载到js虚拟机里的“活”的代码,简称实例。
二、所谓的js全局变量和函数都是建立在浏览器window这个进程里
下面的这些是我们常规写js的代码例子:
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> alert('hello'); </script> </html> |
这个例子里面alert是一个警告函数,它的对象是window,以上的代码也能改写为如下:
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> window.alert('hello'); </script> </html> |
我们通过打开浏览器的F12,在source下的Watch输入window这个实例,就能观察到alert这个函数是在window下的
下一步,我们改造下上面的代码如下:
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> var aaa={}; </script> </html> |
上面定义了个aaa的这个变量,它的类型是Object,刷新上面的watch跟踪,就能看到aaa是window实例下的一个属性值了。
下面我又添加了个function
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> var aaa={}; function a_fun(){ console.log('a_fun'); } </script> </html> |
刷新watch如下:
可以总结出,在<script></script>里面定义的变量和函数,都是挂接在window下的,成为了window实例的属性。
三、js要引入所谓“命名空间”这个概念背后的原因
我一直在baidu和查资料,搜索到结果都是为了避免变量名字冲突,造成不必要的异常。对此,我的理解是如下:
1、为了避免名称冲突,人类好聪明,考虑到了用字母加符号的方式来拼接,形式可以是如下表:
car-bmw-china 中横杠式 car_bmw_china 下横杠式 carBmwChina 驼峰式 car.bmw.china 点连式 |
2、为何“命名空间”基本是趋于“点连式”呢?原因写代码的程序员都习惯了java的包的命名规律,所以自然而然就考虑使用这个方式。另外javascript也是支持obj.xxx这种属性或方法访问的,所以“xxx.yyy.zzz”会被聪明的程序员成为“命名空间”。
3、命名空间最后的简化,我理解就是window下的某个用户自定义的变量,这个变量的类型是Object
四、几种“命名空间”的建立演示(含代码和window的watch截图)
1、对象式的定义法1:定义aaa.index的命名空间,此空间下包含login和submit的方法
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> var aaa={};//创建aaa这个“命名空间” --[实际是aaa的Object的对象] aaa.index={};//这个是在aaa"命名空间",建立aaa.index这个对象 aaa.index.login=function(){ //为aaa.index.login绑定一个匿名函数 console.log('login'); }; aaa.index.submit=function(){ //为aaa.index.submit绑定一个匿名函数 console.log('submit'); }; </script> </html> |
在控制台下就能访问到aaa.index这个“命名空间”了,实际它就是一个aaa.index的对象
2、对象式的定义法2:
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> var aaa={ index:{ login:function(){ console.log('login'); }, submit:function(){ console.log('submit'); }, }, }; </script> </html> |
截图如下:
*由于以上2种对象定义法虽然能引入“命名空间”的效果,但是,在分析代码时,不便于分析哪些是业务用的变量,哪些是“命名空间”的变量。所以聪明的程序员就用了某些技巧如匿名函数运行来创建容易理解的“命名空间”
3、匿名函数运行后的“命名空间”演示:
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> var aaa={}; aaa.index=function(){ //其实是简化了aaa.index={} return { login:function(){ console.log('login'); }, submit:function(){ console.log('submit'); }, }; }(); </script> </html> |
这段代码里面用到了function(){}()这个匿名函数的执行语句,核心是那个return返回了个对象,对象里面有login和submit这2个绑定了实际匿名函数的方法。
但上面的方式还是不太直观,因为java的程序里面,最前面是引用的各类命名空间包的,鉴于此,有些高手的程序员对上面的定义做了如下的改造,自动按照命名空间字符串来建立“命名空间”对象:
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> var $={};//这个是一个普通对象,只是以$号为命名而已。 $.namespace = function() { //这个是$这个变量的一个方法,用途是自动按照输入的字符串参数返回“命名空间”对象 var a=arguments, o=null, i, j, d; for (i=0; i<a.length; i=i+1) { d=a[i].split("."); o=window; for (j=0; j<d.length; j=j+1) { o[d[j]]=o[d[j]] || {}; o=o[d[j]];//把新产生的对象加入window实例。 } } return o; }; $.namespace('aaa.index');//作用是建立aaa.index这个"命名空间"对象 aaa.index={ login:function(){ console.log('login'); }, submit:function(){ console.log('submit'); }, }; </script> </html> |
因为核心的代码,
aaa.index={ login:function(){ console.log('login'); }, submit:function(){ console.log('submit'); }, }; |
有时会被人误认为定义对象,所以会用function(){return {}}()来包裹上面的定义代码,为的是为后面维护代码的人知道这个是“命名空间”的代码,
于是按上面的规律,代码变成如下:
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>title</title> </head> <body> <h1>hello world</h1> </body> <script> var $={};//这个是一个普通对象,只是以$号为命名而已。 $.namespace = function() { //这个是$这个变量的一个方法,用途是自动按照输入的字符串参数返回“命名空间”对象 var a=arguments, o=null, i, j, d; for (i=0; i<a.length; i=i+1) { d=a[i].split("."); o=window; for (j=0; j<d.length; j=j+1) { o[d[j]]=o[d[j]] || {}; o=o[d[j]];//把新产生的对象加入window实例。 } } return o; }; $.namespace('aaa.index');//作用是建立aaa.index这个"命名空间"对象 aaa.index=function(){ return { login:function(){ console.log('login'); }, submit:function(){ console.log('submit'); }, }; }(); </script> </html> |
五、我的初步总结:
1、javascript是没有“命名空间”的概念的,这个概念只是参考了java等面向对象语言的概念做到名字变量的不冲突。
2、Javascript的function(){}()包裹的“命名空间”代码只是方便后期维护代码时,不会看成是普通json式对象的定义而已。
3、Javascript的核心根本是基于window线程虚拟机的编程。
javascript“命名空间”的费曼输出[原创]的更多相关文章
- javascript循环遍历数组输出key value
javascript循环遍历数组输出key value用$.each方法肯定不行的 所以采用如下方法<pre> markers = []; markers[2]=3; markers[3] ...
- javascript 命名空间与运用(前端基础系列)
所谓代码,当你随便命名一个变量:var name = "ukerxi"; 就是一句代码:但当你的代码写出来后,对于后续维护及阅读的人,就可以看出代码是否,易读,易理解:优雅的代码总 ...
- javascript 命名空间的实例应用
/** * 创建全局对象MYAPP * @module MYAPP * @title MYAPP Global */ var MYAPP = MYAPP || {}; /** * 返回指定的命名空间, ...
- 1.JavaScript:写入 HTML 输出
①JavaScript 是可插入HTML页面的编程代码 ②JavaScript插入HTML页面后,可有所有的现代浏览器执行 ※提示:您只能在 HTML 输出中使用 document.write.如果您 ...
- JavaScript:一句代码输出重复字符串(字符串乘法)
看到一个题目要求写一个函数times,输出str重复num次的字符串. 比如str:bac num:3 输出:abcabcabc 除了利用循环还有几种方法,我学习研究之后记下以下三种方法. 1 ...
- JavaScript命名空间的理解与实现
命名空间有效防止函数名/类名和其他人的冲突,在使用多个第三方框架或类库的时候,一旦冲突,唯一能作的就是放弃其中一个.从事Web开发不可避免要接触JavaScript,目前最新版本的JavaScript ...
- 使用 JavaScript 用循环嵌套输出乘法表。外循环控制行数,内循环控制当前行要输出的乘法表达式,在页面上输出九九乘法表
查看本章节 查看作业目录 需求说明: 在页面上输出九九乘法表,实现效果如图所示 实现思路: 创建HTML页面 在页面中嵌入 <script type="text/javascript& ...
- JavaScript 命名空间
<script type="text/javascript"> Namespace=new Object(); Namespace.register=function( ...
- JavaScript学习笔记-循环输出菱形,并可菱形自定义大小
var Cen = 6;//定义菱形中部为第几行(起始值为0) //for循环输出菱形 document.write("<button onclick='xh()'>点我for循 ...
随机推荐
- JPEG图像扩展信息读取和修改
最近,项目需要使用jpg图像信息被写入(非水印),经过研究发现,Android已封装的读者jpg图片扩展信息api(ExifInterface). 通讯api住址:http://developer.a ...
- AlertDialog通过反射机制阻止Dialog关闭
在开发Android应用程序时,我们可能会用到需要用户输入的Dialog,如登录对话框等.这时候,如果用户没有输入登录信息而点击<确定>按钮时,我们并不希望登录Dialog消失,而是采用一 ...
- 停止学习Wireshark
下载和安装好Wireshark之后,启动Wireshark而且在接口列表中选择接口名,然后開始在此接口上抓包.比如.假设想要在无线网络上抓取流量,点击无线接口.点击Capture Options能够配 ...
- Method of Seamless Integration and Independent Evolution of Information-Centric Networking via Software Defined Networking
A method of transferring data between a software defined network (SDN) and an information-centric ne ...
- Windows 10 子系统Linux重启(不重启Win10)
Using CMD (Administrator) net stop LxssManager net start LxssManager
- Asp.net固定功能位充满了零(解决,演示样本)!
Asp.net固定功能位充满了零(解决.演示样本)! 在发展,其中,数实现出现8数字.但是,需要使用0加厚.例如:123,代表:0000123. 真实的比例,如下: decimal aaa = 123 ...
- 参数方法(parameter)与非参数方法(nonparameter)
参数方法表示参数固定,不随数据点的变化而变化: 非参数方法并不意味着没有参数,而是说,参数的数目随数据点而变化, 1. 参数方法举例 logistic regression:p(y=1|x,α)=11 ...
- 正定矩阵(definite matrix)
1. 基本定义 在线性规划中,一个对称的 n×n 的实值矩阵 M,如果满足对于任意的非零列向量 z,都有 zTMz>0. 更一般地,对于 n×n 的 Hermitian 矩阵(原矩阵=共轭转置, ...
- Oracle 已有则更新,没有则插入
使用merge merge into 表名 t1 using (select '数据数据' 字段1,'数据数据' 字段2 from dual) t2 on (t1.字段1 = t2.字段1) when ...
- Cocos2d-x 脚本语言Lua介绍
Cocos2d-x 脚本语言Lua介绍 本篇博客记录Lua学习.学习来自eoe论坛,Lua语言开发Cocos2d-x游戏入门视频教程,猛戳下面地址: http://www.eoeandroid.com ...