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线程虚拟机的编程。

原文地址:https://www.cnblogs.com/qkabcd/p/10802834.html

时间: 2024-10-09 11:26:54

javascript“命名空间”的费曼输出[原创]的相关文章

JavaScript:写入 HTML 输出

<!DOCTYPE html><html><body> <p>JavaScript 能够直接写入 HTML 输出流中:</p><script>document.write("<h1>This is a heading</h1>");document.write("<p>This is a paragraph.</p>");</script&g

javascript命名空间

命名空间:命名空间有助于减少程序中所需要的全局变量的数量,并且同时还有助于避免命名冲突或过长的名字前缀. var MYAPP = MYAPP || {}; MYAPP.namespace = function(ns_string){ var parts = ns_string.split('.'), parent = MYAPP, i; if( parts[0] === 'MYAPP'){ parts = parts.slice(1); } for(var i=0; i<parts.length

JavaScript示例一(输出元素属性)

很久以前学过一阵子javascript,没怎么实际用,也不太以为然,觉得挺小众的.没想到几年之间屌丝逆袭成高富帅了.javascript俨然成了跨平台的通用web语言.无奈只得从头恶补.参考书籍就是<JavaScript 高级程序设计>和<JavaScript语言精粹>.结合书的内容,整理了一些自己的理解和代码示例,记录在这里留着随时回顾. 输出元素属性: <html> <head> <title> 输出元素属性 </title> &

Javascript:基础(输出/编辑内容、编辑属性、事件响应、输入验证)

Javascript是目前最流行的服务器脚本语言,使用Javascript可以为网页添加丰富的逻辑和更加复杂动态效果. 代码整理自w3school:http://www.w3school.com.cn 效果图: 示例代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"

JavaScript命名空间、函数参数类型重载的实现

突然心血来潮写的东西,可以考虑在func({arg1: xxx, arg2: xxx})不适用的情况下使用. <!DOCTYPE html> <html lang="zh"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <title>命名空间.参数类型重载</title>

javascript 命名空间的实例应用

/** * 创建全局对象MYAPP * @module MYAPP * @title MYAPP Global */ var MYAPP = MYAPP || {}; /** * 返回指定的命名空间,如果命名空间不存在则创建命名空间. * 备注:命名时需小心,注意保留关键字,可能在一些浏览器无法使用. * * @method namespace * @param {String *} 至少需要创建一个命名空间 * @return {Object} 最后一个命名空间创建的对象的引用 */ MYAP

JavaScript中常见的输出方式

Javascript中有三种常见的输出方式: 1,通过弹窗的形式来输出,其中又分为三种,它们之间存在着一些细微的区别: 1.1,alert(需要输出的内容); 例如:alert("Hello World"); 1.2,confirm("需要输出的内容"); 例如:confirm("Hello CTl !"); 1.3,prompt("需要输出的内容"); 例如:prompt("Hello China!"):

javascript 命名空间,学习

一. (function(){ var _NS=function(){ } _NS.prototype.alert=function(){ console.log('test'); } window.NS=new _NS(); })(); 二. // 声明一个全局对象Namespace,用来注册命名空间 Namespace = new Object(); // 全局对象仅仅存在register函数,参数为名称空间全路径,如"Grandsoft.GEA" Namespace.regist

基于Javascript的二叉树实现【原创】

转载请注明出处 2016.7.7 by Totooria Hyperion http://demo.th-shr.com:9999/ 目前实现了: 前序遍历 中序遍历 后序遍历 层次遍历 求叶子节点的个数 求树的高度 对称树 判断某一节点是否在某一树种 求两节点的最近公共父节点 其他算法以后再慢慢补 首先是用了自己写的Class: http://www.cnblogs.com/Totooria-Hyperion/p/5645096.html 二叉树声明如下: Class("BinTree&quo