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循 ...
随机推荐
- JavaScript动态广告弹出框
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 一组西门子S7 报文
03 00 00 16 11 E0 00 00 00 01 00 C1 02 10 00 C2 02 03 01 C0 01 0A(第一次握手报文) 03 00 00 16 11 D0 00 01 0 ...
- 为 Mac Finder 增加右键文件打包压缩(免费)
在 Windows 上用惯了 7-Zip 和 WinRAR,来到 Mac 却突然发现没有类似的工具?Mac 自带的 Zip 工具确实让人吐糟无力,压缩率低就不说了,因为 Mac 上文件名是 Unico ...
- 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj
原文 将 WPF.UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj 写过 .NET Standard 类库或者 .NET Core 程序的 ...
- 正定矩阵(definite matrix)
1. 基本定义 在线性规划中,一个对称的 n×n 的实值矩阵 M,如果满足对于任意的非零列向量 z,都有 zTMz>0. 更一般地,对于 n×n 的 Hermitian 矩阵(原矩阵=共轭转置, ...
- IT该忍者神龟Oracle 树操作(select…start with…connect by…prior)
oracle树查询的最重要的就是select-start with-connect by-prior语法了.依托于该语法.我们能够将一个表形结构的以树的顺序列出来. 在以下列述了oracle中树型查询 ...
- BigTable读后笔记
BigTable读后笔记 GFS可能出现重复记录或者padding,Bigtable如何处理这种情况使得对外提供强一致性模型? ANS: Bigtable写入GFS的数据分为两种: 1)操作日志,当T ...
- cocos2d-x 源代码分析 : Ref (CCObject) 源代码分析 cocos2d-x内存管理策略
从源代码版本号3.x.转载请注明 cocos2d-x 总的文件夹的源代码分析: http://blog.csdn.net/u011225840/article/details/31743129 1.R ...
- 【转载】如何使用docker部署c/c++程序
原文地址:https://blog.csdn.net/len_yue_mo_fu/article/details/80189035 Docker介绍 Docker是一个开源的容器引擎,它有助于更快地交 ...
- 图像滤镜艺术---Glow Filter发光滤镜
原文:图像滤镜艺术---Glow Filter发光滤镜 Glow Filter发光滤镜 Glow Filter发光滤镜是一种让图像产生发光效果的滤镜,它的实现算法如下: 1,对原图P进行高斯模糊得到图 ...