浏览模式: 标准 | 列表分类:Javascript
Submitted by gouki on 2008, December 24, 11:04 PM
说实话,我看到这个标题的时候没有看懂,确实没有理解本文的标题想表达什么意思。看完之后我是理解了。先贴上原文,再谈我的理解。。。
原文地址:http://www.cn-cuckoo.com/2008/12/24/shallow-or-deep-copy-and-pass-by-value-or-reference-270.html
内容如下:
XML/HTML代码
- 这个标题念起来有点拗口,但却是理解数据结构的关键。标题中的4个术语,对应的英文分别是:shallow copy(注意,不是shadow copy)、deep copy、pass by value、pass by reference(或pass by address)。传址和传引用是一回事。
-
- 一门编程语言的核心是数据结构,粗略来讲,可以把数据结构分成不可变类型(immutable)和可变类型(mutable)。为什么这么分呢?这涉及到内存分配问题。对于不可变类型,只要分配有限的内存空间即可,而对于不可变类型,理论上则要分配没有大小限制的空间。因此,这么分是出于合理利用系统资源的考虑。实际上,堆内存和栈内存分别用于保存不可变类型值和可变类型值。
-
- 什么是不可变类型?就是该值一旦赋予某个变量,就只属于某个变量,不能同属于其他变量。如:
-
- var stringValue = “I’m immutable data structure, mean you can’t modify me!”;
- var anotherStringValue = stringValue;
- stringValue = “I have changed”;
-
- 此时,anotherStringValue中保存的值会不会也变成“I have changed”?不会。因为
-
- var anotherStringValue = stringValue;
-
- 照stringValue中保存的字符串的原样,复制一个字符串(相应地,在内存中分配一块新空间),并将该字符串赋给 anotherStringValue。换句话说,这两个变量虽然保存的值相同,但它们的值并不在一块内存中。因此,修改任何一个变量,都不会影响另一个变量。即
-
- stringValue = “I have changed”;
-
- 只会影响stringValue的值。但是,确切来讲,stringValue = “I have changed”;并不是修改stringValue,而是创建了一个新字符串(相应地,在内存中分配一块新空间),然后让stringValue引用该字符串——更像是替换变量的值;原来的字符串呢?因为没有变量引用它,也就成为垃圾了(当然,垃圾所占用的内存会被回收)。
-
- 由此可见,赋值操作对于不变类型而言,传递的是内存中的值本身。那么,对于可变类型呢?当然,传递的是内存中值的引用(或者说地址),而且无论传递多少次,内存中始终都只有一份原始值——毕竟可变类型大小莫测,只保存一份原始值能最大限度节省内存空间。例如:
-
- var objectValue = {1:1,’s’:’string’,'innerObject’:{’innerArray’ : [1,2,3]}};
- var anotherObjectValue = objectValue;
- objectValue[1] = 100;
- anotherObjectValue[1]; //100
-
- 不言自明,这里的anotherObjectValue通过赋值操作,从objectValue那里只获得了对原始对象( {1:1,’s’:’string’,'innerObject’:{’innerArray’ : [1,2,3]}})的引用,也就是该对象在内存中的地址,或者说“门牌号码”。因此,修改通过objectValue修改原始对象的第一个元素(objectValue[1] = 100;),结果当然会在anotherObjectValue[1]这里得到反映了。
-
- 在JavaScript中,给函数传递参数是按照上述默认约定——即对不可变类型,传值;对可变类型,传址——进行的。如:
-
- function example(str, obj){
- ……
- }
- example(stringValue,objectValue);
-
- 调用example函数时,第一个参数传递的是实际的字符串值,第二参数传递的是对象的引用(内存地址)。
-
- 在PHP中,定义函数时可以指定相应参数是传值还是传址——通常是传值。其实,这也很容易理解:假如函数要求为某个可变类型参数传值,而不是传址,那么也就意味着内存中会因此多出一份该类型值的副本。相应地,在函数中修改这份新副本,不会影响函数外的原副本。因为新旧副本在内存中就不是同一个地址。说到这,也就引出了浅复制和深复制的概念。事实上,浅复制和深复制的区别恰恰在于复制可变类型时,是传值还是传址。如果是像往常一样传址(传引用),那么就是浅复制。如果是传值,那么就是深复制。浅复制和深复制到底有什么区别呢?以下面的Python代码为例:
-
- >>> x = {’username’: ‘admin’, ‘machines’: [’foo’, ‘bar’, ‘baz’]}
- >>> y = x.copy()
- >>> y[’username’] = ‘mlh’
- >>> y[’machines’].remove(’bar’)
- >>> y
- {’username’: ‘mlh’, ‘machines’: [’foo’, ‘baz’]}
- >>> x
- {’username’: ‘admin’, ‘machines’: [’foo’, ‘baz’]}
-
- 调用字典x的copy方法返回一个新字典并赋值给y,新字典中带有与原字典相同的键-值对。注意,copy方法采用浅复制创建的新字典,与原字典有区别也有联系。区别体现在,对于原字典中不可变的值,如数字、字符串、元组等,会在新字典中重新生成一份新副本;因此,修改(实际上是替换,或者说是重新赋值)这些键的值(y[’username’] = ‘mlh’)不会影响原字典。联系体现在,对于原字典中可变的值,如列表、字典,不会在新字典中生成新副本,而只复制值的引用,即新字典中相应的键保存的是引用,当然,原字典中相应的键保存的也是引用,而且这两个引用都指向同一块内存地址。这就是所谓的浅复制。因此,如果修改的是可变类型的值(y[’machines’].remove(’bar’)),就一定会影响引用该值的原字典项了。
-
- 深复制则不然。深复制是实实在在地把原字典中所有的值全都照原样子重新创建一遍,无论是不变类型值,还是可变类型值。执行深复制后,内存中会存在两份完全一样的数据段,但分别处于不同内存空间中,即地址不同。而且,分别由不同变量(原字典、新字典)引用。因此,经过深复制后修改一个字典,不会影响另一个字典。Python的copy模块中的deepcopy函数可以实现深复制:
-
- >>> from copy import deepcopy
- >>> d = {}
- >>> d[’names’] = [’Alfred’, ‘Bertrand’]
- >>> c = d.copy()
- >>> dc = deepcopy(d)
- >>> d[’names’].append(’Clive’)
- >>> c
- {’names’: [’Alfred’, ‘Bertrand’, ‘Clive’]}
- >>> dc
- {’names’: [’Alfred’, ‘Bertrand’]}
-
- 显然,修改深复制得到的新值不会影响原值;而修改浅复制得到的“新”值,在某种程度上仍然会影响原值。
作者想表达的意思应该是在javascript中变量的复制和赋值,对于普通的变量而言,赋值仅仅是一个复制,而对于对象而言,赋值则是一个引用。
比如:var a=1;var b=a;
在这里,b其实是a的一个复制,所以b=1,正因为是复制,所以复制完后,b和a就没有任何关系了,当a重新赋值的时候,对于b则没有影响,同样,对于b再重新赋值,对a也没有影响 。
但是,如果a是一个对象,那就不一样了
例如var test ={a:1,b:2};var test1 =test;
在这样的情况下,test1就不再是test的复制了,而是直接取了test的地址,所以对于Test的值的改变,也影响到了test1,比如我test.a = 2,那么我test1.a的值也就自动变成了2
这点其实在PHP5里面已经也这样了,在PHP4的时候,对象的赋值也是一个复制,所以我们为了保证只有一个实例,往往都是采用:$a = &$b ;但是从5开始则不一样,对于对象而言,如果没有特别指定的操作,那么就相当于是对地址的一个引用。效果和上面的JS代码类似。
作者在最后举了一个PYTHON的例子来说明深复制,其实也就是为对象也做一个拷贝而不是采用引用,这个,当然在PHP里也有,clone就是实现的这个效果。HOHO
Tags: javascript, copy, reference
Javascript | 评论:0
| 阅读:23857
Submitted by gouki on 2008, December 23, 8:09 PM
The jQuery team has been working hard on the new release of the jQuery library and it’s ready for some in-depth testing! jQuery 1.3 is not ready for production use yet but we need help to weed out any bugs that might’ve snuck through.
看上去jQuery团队们都很辛苦,所以,小白鼠们,你们也辛苦一点,把BUG测试的多一点,我们在以后的项目中才敢正常的应用啊。
自己也是用jQuery的,应该也会测试一些,特别是针对这次更新的功能:
- Selector Engine - The selector code has undergone a complete rewrite - it’s likely that some edge cases still exist here.
- DOM Manipulation (append/prepend/before/after) - This code has also undergone a large rewrite along with some of the logic for executing inline script elements.
- .offset() - Another method that has been completely rewritten.
- Event Namespaces - The logic for handling namespaced events has been completely rewritten.
- Event Triggering - When triggering an event the event now bubbles up the DOM - this is likely to cause some problems.
选择器改写,DOM控制器又是大的改写,.offset改写,事件命名空间改写,不知道改写后效率会怎么样,当然,估计改写也应该是冲着效率而去的,否则改写的意义也不是特别大了。
事件触发,针对DOM的事件触发?估计问题也会挺多,他们也是这么认为的。DOM太难控制了,毕竟不是每个页面都是按照规范来写的。
如果你写了一些代码,并认为它触发了这些BUG,你可以提交到:http://dev.jquery.com/ ,当然提交的代码尽量是简短一些,提交的时候也需要将你的mail写上,这样,jQuery Team可能在修改后会通知你的哦。
Tags: javascript, jquery, beta, new release
Javascript | 评论:0
| 阅读:19284
Submitted by gouki on 2008, December 22, 10:44 PM
能够用厚厚的PDF来解释jQuery的人不多,但确实是有一个。看到这篇文章也是一个意外,是从订阅的某个人的博客里找到的。他看到这篇文章也很意外,于是乎,我也就很意外的转载了一下。
原文地址:http://jljlpch.javaeye.com/blog/234218
作者:jljlpch
原文中的PDF下载地址:
我会做个镜象的。。。
原文如下:
jQuery是一个非常优秀的JS库,与Prototype,YUI,Mootools等众多的Js类库相比,它剑走偏锋,从web开发的实用角度 出发,抛除了其它Lib中一些中看但不实用的东西,为开发者提供了优美短小而精悍的类库。其使用简单,文档丰富,而且性能高效,能极大地提高web系统的 开发效率。因此可以说是web应用开发中最佳的Js辅助类库之一。大部分开发者正在抛弃Prototype,而选择Jquery做为他们进行web开发的 JS库。
如是开发人员仅仅只知道文档中的简单的使用方法,却不明白Jquery的运行原理和内部机制,在使用jquery时,肯定会碰到许多的问题。这些问 题有一部分是Jquery的Bug。大部分是自身的使用不当而造成的。而文档的简单的使用说明很难解决问题。在调试基于jQuery的web应用时,很多 时候都要跟踪进入jQuery对象分析其运行状态以了解出错的原因。
如果对于web的应用的页面运行性能和效率有所要求的话,那么我们更应该去明白其运行机理和核心源码。但是jQuery源码不像其它的类库那样,它 有点晦涩,难懂。这就是本源码分析的原因,让所有使用jQuery的读者,能快速上手jQuery的源码,并在开发中得心应用。
Jquery的网络资源丰富,但Baidu了很久,很难找到那种完全深入地分析Jquery源码的文稿。倒是Jquery的开发者,John Resi的《Pro Javascript Techniques》涉及到Jquery的源码的分析,但是其主指还是在于JavaScript的使用。那本书并不能使我们完全细致地了解Jquery 的源码。
写个这个源码分析的理由其实很简单,在工作中使用jquery经常出问题,不得不分析其源码,我把分析的源码放在blog。其标题是jquery core 源码分析。结果有一网友竟评论说打到标题党,可见还是有很多人像我这样想完全了解jquery的core代码。
从自己能看懂,到自己写出来。发现自己有一个质的提高。但是由于水平有限,分析过程的难免有错误。请大家多多指教。不过嘴下能留情就最好了。有什么问题可以到blog:jljlpch.javaeye.com去访问和评论。附件附有打包的源码。
分析源码,最难的地方不是你能理解,你能分析得出来。如果把所有的分析都写在源文件中,我想很多人看不了多少行就会中止的。很难有人有兴趣对得源码一行行地去分析。何把源码有机地组合起来,串成一条线是本教程的最为头疼的地方。
读书的最高境界是厚积薄发。分析源码也是一样。对于4,5千行的jquery源码,我们如何做到心中有数,知道什么功能在什么函数里内 呢? 什么函数用在什么地方呢?这样就得把所有的函数有机分类地重组起来,想着Jquery的主要目的和自己对于js方面的理解。我把整个Jquery薄发成三 个单词 query-->manipulate-->expand。
jquery一个很紧缩的lib,它的主要目的就是对dom元素进行操作。那么dom元素的从哪里?
到dom树中去找。这就是 query。$(),Jquery的构建就是一个query的过程。我们可以把这个query范围放大一点,它不光是从dom中查找的CSS selector,还有可能是从html的片断中去寻找的dom元素生成,更进一步就是直接的dom元素(集)。$()的构建就是从这里出发的。
query到元素集,这个query的过程还没有最终完成。因为这些结果集不一定满足我们的要求,那么就要筛选,要过滤。要进行数组方面的相关的操作。这就涉及到jquery对象的类数组的特征。我们就可以把这些类数组的相关的函数放在一起来分析。
当最终的需求的集合形成,我们要的完成我们真正要做的,对集合中的dom元素进行操作。
怎么操作?操作什么呢?不就是对dom元素的attribute,class, style,css,event等进行操作吗?
细化一下:
1、我们可以把attribute,class,style都看作是是属性的操作,还有expando的自定义的属性。这就涉及到jquery.data。
2、对dom元素的内容。什么是内容。innerHtml是。all childNodes也是,value也可以算。对于内容的操作就有追加,插入,前插,后插,内部前插和内部后插。那当然不能少了clone,remove这些操作。
3、 CSS是可以在dom元素中单独出来分成一块来做分析的。对于css的操作,不就是 height,width,innerHeight,innerWidth,out(height,widith)的操作,还有元素的位置 (position,offset),display or not。这就是对于CSS的操作。
4、Event也是元素的操作中的一部分。这一部分除了addEvent,fireEvent,removeEvent,和domready就没有别的啦。
5、Ajax是给元素从服务器中找内容填充的。真正用到最多不还是load吗,对于getScript,getJson之类全都是在jQuery.ajax的函数的基础而出来。
6、 Fx可以看做是CSS的操作。但是其又高于CSS。对于FX,最基本不就show,hide,slide(down,up),fade(in,out)这 几种用法。无论什么用法,都基于时间的长短映射到元素CSS的属性值的对对应比率的大小。采用setInterval间隔来运行就形成了动画。这就 animate()函数。所有效果的发源地。
想想整个jquery就是这么简单。当然如果没有去身体力行去自己分析,无论什么教程都是没有用的。
其实query-->manipulate是表层的东西。还有一个高层的就是expand。这涉及到一个lib的架构与设计。
这部分我们可以从源码的角度去解读对于js lib的架构。
除了扩展性(extend)之后,一个lib肯定是要花大力气去考虑它的性能。
考虑它的内存使用。
这是站在设计Jquery的角度去分析。
想了很久,但是这一部分还没有写入目前的源码分析中。
镜象PDF下载:
jquery1.2.6源码分析.rar
Tags: jquery, javaeye, 详解
Javascript | 评论:0
| 阅读:19738
Submitted by gouki on 2008, December 18, 6:44 PM
平时我们取得location的search的时候,往往都是要用location.search,然后根据取回的结果集再处理
1、先判断第一位是否是“?”,如果是则从?开始往后面处理
2、写程序以&开始分隔,当然得先用unescape,或者用那个urldecode(具体的名字不记得了)处理一下,把&之类的处理一下
3、以=分隔,这样才能可以取得一一对应的值。
现在方便了。jQuery有这样的插件了。。。。
原文来自:http://www.cssrain.cn/article.asp?id=1204
内容如下:
例如 当前你的URL是:
http://www.cssrain.cn/index.php?test=1&kk=2
如果想获取test,则可以引入插件后,
用如下方法获取:
var test = $.query.get('test');
如果参数有多个相同的名称 ,则可以这样:
var arr = $.query.get('testy');
输出: [ 值1 , 值2, 值3...]
如果要获取多个相同名称中的某一个,可以这样:
var arrayElement = $.query.get('testy[1]');
此插件不仅能获取参数,也能设置参数。
设置一个参数:
var newUrl = $.query.set("section", 5).toString();
输出 : "?section=5"
设置两个参数:
var newUrl = $.query.set("section", 5).set("action", "do").toString();
输出 : "?action=do§ion=5"
删除一个参数:
var oldQueryAgain = $.query.REMOVE("type");
清空所有参数:
var emptyQuery = $.query.empty();
复制所有参数:
var stillTheSame = $.query.copy();
插件地址:
http://plugins.jquery.com/project/query-object
Tags: javascript, jquery, search, location, get
Javascript | 评论:1
| 阅读:47840
Submitted by gouki on 2008, December 18, 1:34 PM
有时候我们不得不通过更改form的action来进行提交数据。当然大多数情况下,我们都是通过隐藏的字段来使action得到不同的数据。比如我们form的action是search.php,那么我们都是通过隐藏字段来使我们通过search.php搜索不同值,比如<input type="hidden" name="action" value="article">然后在search.php里面通过$_POST['action']=='article'来知道我们搜索的内容是文章而不是其他。
但如果我们搜索页面并非只有一个入口search.php怎么办?比如我们的全文搜索是search.php,搜索文章是search_article.php,搜索新闻是search_news.php。怎么办?当然我们可以通过下拉框的值来更改FORM的action,就可以了。
简单代码如下,
XML/HTML代码
- <script type="text/javascript">
- <!--
- function redirectForm( which ){
- var searchModeList = document.getElementById('searchMode');
- var actionFile = '';
- for (var i=0,sml=searchModeList.length; i<sml ; i++ ){
- if( i == searchModeList.selectedIndex ){
- actionFile = searchModeList[i].value;
- }
- }
- if( actionFile == ''){
- return false;
- }else{
- actionFileactionFile = actionFile + '.php';
- }
- which.action = actionFile;
- which.submit();
- }
- //-->
- </script>
- <form method="post" action="" onsubmit="return redirectForm(this);" id='searchForm'>
- <select id="searchMode">
- <option value="search" selected="selected">Default</option>
- <option value="search_article" >Article</option>
- <option value="search_news">News</option>
- </select>
- <input type="submit" />
- </form>
Tags: javascript, form, action
Javascript | 评论:1
| 阅读:37143