<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>檬檬前端行 &#187; 引用</title>
	<atom:link href="http://www.frontendcodes.com/?feed=rss2&#038;tag=%E5%BC%95%E7%94%A8" rel="self" type="application/rss+xml" />
	<link>http://www.frontendcodes.com</link>
	<description>路漫漫其修远兮</description>
	<lastBuildDate>Wed, 18 Mar 2015 10:05:27 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>javascript中的引用与闭包</title>
		<link>http://www.frontendcodes.com/?p=28</link>
		<comments>http://www.frontendcodes.com/?p=28#comments</comments>
		<pubDate>Sat, 22 Jan 2011 13:41:28 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[引用]]></category>
		<category><![CDATA[闭包]]></category>

		<guid isPermaLink="false">http://www.frontendcodes.com/?p=28</guid>
		<description><![CDATA[javascript真是神奇的语言，实在是太灵活了。 javascript中的变量，大体分为两大种。 &#8220;直接量&#8221;和&#8221;引用量&#8221;，姑且这么称呼吧，肯定不标准。 ：） &#8220;直接量&#8221;包括，number,string,boolean 除此之外，都是&#8221;引用量&#8221; 有很多JS的面试题，都在这里搞点花样。 var a=[1,2,3]; var b=a; a[0]=2; console.log(b[0]); 结果：2 深入的理解这段代码。 var a=[1,2,3]; var b=a; 看起来似乎是把数组赋值给a了，其实不然，应该是a引用了数组[1,2,3] , 可以这么理解。内存中存在了一个数组[1,2,3]，而变量a其实只是保存了一个对数组[1,2,3]的引用罢了。 那么，b=a就好理解了，b只是复制了这种引用。 所以a[0]的重新赋值，会让b[0]也随着改变。 因为a和b本来就引用了同一个数组。 而如果是直接量的，就不会存在这样的情况。 var a=&#8221;hello&#8221;; var b=a; a=1; console.log(b); 结果：hello &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 有的时候，需要复制而不是引用，就麻烦了。 var a={attr:1}; 如果需要复制一个a。。怎么办呢？ function copy(o){ var obj={}; for(var i in o){ obj[i]=o[i]; } return obj; } 没错，生成一个对象，然后把被复制的对象的所有属性都拷贝一份到新的对象里。。 当然，如果你要拷贝一个数组，就要new一个Array，拷贝一个function，就要new一个Function， &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; 引用，各种引用，各种各种引用，JS就是由引用组成的。 [...]]]></description>
			<content:encoded><![CDATA[<p>javascript真是神奇的语言，实在是太灵活了。</p>
<p>javascript中的变量，大体分为两大种。 &#8220;直接量&#8221;和&#8221;引用量&#8221;，姑且这么称呼吧，肯定不标准。</p>
<p>：）</p>
<p>&#8220;直接量&#8221;包括，number,string,boolean</p>
<p>除此之外，都是&#8221;引用量&#8221;</p>
<p>有很多JS的面试题，都在这里搞点花样。</p>
<p>var a=[1,2,3];</p>
<p>var b=a;</p>
<p>a[0]=2;</p>
<p>console.log(b[0]);</p>
<p>结果：2</p>
<p>深入的理解这段代码。</p>
<p>var a=[1,2,3];</p>
<p>var b=a;</p>
<p>看起来似乎是把数组赋值给a了，其实不然，应该是a引用了数组[1,2,3] , 可以这么理解。内存中存在了一个数组[1,2,3]，而变量a其实只是保存了一个对数组[1,2,3]的引用罢了。</p>
<p>那么，b=a就好理解了，b只是复制了这种引用。</p>
<p>所以a[0]的重新赋值，会让b[0]也随着改变。 因为a和b本来就引用了同一个数组。</p>
<p>而如果是直接量的，就不会存在这样的情况。</p>
<p>var a=&#8221;hello&#8221;;</p>
<p>var b=a;</p>
<p>a=1;</p>
<p>console.log(b);</p>
<p>结果：hello</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>有的时候，需要复制而不是引用，就麻烦了。</p>
<p>var a={attr:1};</p>
<p>如果需要复制一个a。。怎么办呢？</p>
<p>function copy(o){</p>
<p>var obj={};</p>
<p>for(var i in o){</p>
<p>obj[i]=o[i];</p>
<p>}</p>
<p>return obj;</p>
<p>}</p>
<p>没错，生成一个对象，然后把被复制的对象的所有属性都拷贝一份到新的对象里。。</p>
<p>当然，如果你要拷贝一个数组，就要new一个Array，拷贝一个function，就要new一个Function，</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>引用，各种引用，各种各种引用，JS就是由引用组成的。</p>
<p>获取DOM对象，是引用，填充数组还是引用。使用直接量的机会对于JS来说，是那么的稀少。 ：（</p>
<p>这就引入了又一个奇怪的货色：闭包，引用的副产品。</p>
<p>所谓的闭包，一句话讲，就是函数外引用了函数内的局部变量（或者叫私有变量吧，反正都是一回事 ：]  ）。</p>
<p>举例：</p>
<p>var b;</p>
<p>function closure(){</p>
<p>var i=0;</p>
<p>b=function(){i++;alert(i);}</p>
<p>}</p>
<p>closure();</p>
<p>b();</p>
<p>b();</p>
<p>在上例中，全局变量b引用了函数closure中的匿名函数，这就形成了一个闭包。</p>
<p>说起闭包，就要说JS的内存回收，JS的内存回收机制是，如果有一个东西，不存在被引用，就会被销毁回收。（销毁的过程是怎么样的，是立刻回收还是有个时间间隔，没有测试过，欢迎讨论），换言之，如果被引用，那么就会驻留在内存中，不被回收，正式由于JS得这个特性，使得闭包得以存在。</p>
<p>由于变量b引用了函数中的内部变量，使得closure无法被回收，然后它的所有一切都被保存下来，包括内部变量i</p>
<p>在这个例子中，运行b，第一次是1，第二次是2，就是这个道理了。</p>
<p>于是，闭包的好处出现了&#8212;&#8212;可以保存变量，坏处也出现了&#8212;&#8212;&#8211;内存泄露</p>
<p>在循环给DOM元素绑定事件中，经常会用到闭包。</p>
<p>var li=document.getElementsByTagName(&#8220;li&#8221;);</p>
<p>for(var i=0,l=li.length;i&lt;l;i++){</p>
<p>li[i].onclick=function(){alert(i);}</p>
<p>}</p>
<p>在上例中，按照代码理解，应该是每个li在点击的时候alert出这个li的索引。但是事与愿违，alert出的总是最后一个</p>
<p>因为，虽然每个li都绑定了onclick事件，但是等到click事件执行的时候，变量i已经是l了</p>
<p>这时候闭包出场了。。</p>
<p>var li=document.getElementsByTagName(&#8220;li&#8221;);</p>
<p>for(var i=0,l=li.length;i&lt;l;i++){</p>
<p>li[i].onclick=(function(i){</p>
<p>return function(){alert(i);}</p>
<p>})(i);</p>
<p>}</p>
<p>事实上给li绑定的函数，引用了匿名函数的内部变量。。形成了闭包，使得当时的i也被保存了下来。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>虽然有如此好处，闭包依然尽量避免，不仅仅是可见的内存泄露，更多的时候，闭包会不自觉的形成循环引用，造成更大的问题。</p>
<p>：） 不过Jquery就是个大闭包。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.frontendcodes.com/?feed=rss2&#038;p=28</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
