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“命名空间”的费曼输出[原创]的更多相关文章

  1. javascript循环遍历数组输出key value

    javascript循环遍历数组输出key value用$.each方法肯定不行的 所以采用如下方法<pre> markers = []; markers[2]=3; markers[3] ...

  2. javascript 命名空间与运用(前端基础系列)

    所谓代码,当你随便命名一个变量:var name = "ukerxi"; 就是一句代码:但当你的代码写出来后,对于后续维护及阅读的人,就可以看出代码是否,易读,易理解:优雅的代码总 ...

  3. javascript 命名空间的实例应用

    /** * 创建全局对象MYAPP * @module MYAPP * @title MYAPP Global */ var MYAPP = MYAPP || {}; /** * 返回指定的命名空间, ...

  4. 1.JavaScript:写入 HTML 输出

    ①JavaScript 是可插入HTML页面的编程代码 ②JavaScript插入HTML页面后,可有所有的现代浏览器执行 ※提示:您只能在 HTML 输出中使用 document.write.如果您 ...

  5. JavaScript:一句代码输出重复字符串(字符串乘法)

    看到一个题目要求写一个函数times,输出str重复num次的字符串. 比如str:bac     num:3 输出:abcabcabc 除了利用循环还有几种方法,我学习研究之后记下以下三种方法. 1 ...

  6. JavaScript命名空间的理解与实现

    命名空间有效防止函数名/类名和其他人的冲突,在使用多个第三方框架或类库的时候,一旦冲突,唯一能作的就是放弃其中一个.从事Web开发不可避免要接触JavaScript,目前最新版本的JavaScript ...

  7. 使用 JavaScript 用循环嵌套输出乘法表。外循环控制行数,内循环控制当前行要输出的乘法表达式,在页面上输出九九乘法表

    查看本章节 查看作业目录 需求说明: 在页面上输出九九乘法表,实现效果如图所示 实现思路: 创建HTML页面 在页面中嵌入 <script type="text/javascript& ...

  8. JavaScript 命名空间

    <script type="text/javascript"> Namespace=new Object(); Namespace.register=function( ...

  9. JavaScript学习笔记-循环输出菱形,并可菱形自定义大小

    var Cen = 6;//定义菱形中部为第几行(起始值为0) //for循环输出菱形 document.write("<button onclick='xh()'>点我for循 ...

随机推荐

  1. OpenCL基本概念

    OpenCL程序同CUDA程序一样,也是分为两部分,一部分是在主机(以CPU为核心)上运行,一部分是在设备(以GPU为核心)上运行.在设备上运行的程序被称为核函数.但是对于核函数的编写,CUDA一般直 ...

  2. Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践

    原文:Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践 环境 本地 win7 服务器:Virtual Box 上的Centos ssh工具: Xshell 文件传输 ...

  3. Application中数据传递及内存泄漏问题

    原文地址:http://android.tgbus.com/Android/tutorial/201107/359474.shtml Application的使用 Application和Actovo ...

  4. End-to end provisioning of storage clouds

    Embodiments discussed in this disclosure provide an integrated provisioning framework that automates ...

  5. 44个 Javascript 变态题解析——分分钟让你怀疑人生

    原题来自: http://javascript-puzzlers.herokuapp.com/ 第1题 ["1", "2", "3"].ma ...

  6. 机器学习:scikit-learn 做笑脸识别 (SVM, KNN, Logisitc regression)

    scikit-learn 是 Python 非常强大的一个做机器学习的包,今天介绍scikit-learn 里几个常用的分类器 SVM, KNN 和 logistic regression,用来做笑脸 ...

  7. Expression Design与Blend制作滚动的小球动画教程

    原文:Expression Design与Blend制作滚动的小球动画教程 一,开发工具 Microsoft Expression Design & Blend 4.0 (3.0亦可). 这两 ...

  8. ListView、TreeView和DataGrid。

    原文:ListView.TreeView和DataGrid. 1.ListView. ListView继承自简单的没有特色的ListBox,并使用View属性进行扩展.增加了对基于列显示的支持,并增加 ...

  9. WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参

    原文:WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参 ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataC ...

  10. SICP 关于递归迭代的重新理解以及尾递归的引入...

    看了线性的递归和迭代以及树形递归迭代这部分的内容,感觉对递归和迭代又有了新的理解...所以记录一下,也算对这部分内容的总结吧. 首先书中提到的递归与迭代和我以前想的有点不一样,我感觉书中提到的递归和迭 ...