<?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>10V &#187; javascript</title>
	<atom:link href="http://www.smartwei.com/tag/javascript/feed" rel="self" type="application/rss+xml" />
	<link>http://www.smartwei.com</link>
	<description>干一行，爱一行</description>
	<lastBuildDate>Fri, 13 Jan 2012 01:22:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Firebug &amp; Chrome Console 控制台使用指南</title>
		<link>http://www.smartwei.com/firebug-chrome-console-guid.html</link>
		<comments>http://www.smartwei.com/firebug-chrome-console-guid.html#comments</comments>
		<pubDate>Wed, 23 Mar 2011 16:48:18 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[常用工具]]></category>
		<category><![CDATA[firebug]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=312</guid>
		<description><![CDATA[本文介绍了如何使用firebug的console（控制台）来调试javascript]]></description>
			<content:encoded><![CDATA[<div style="font: bold 18px Arial;color: #C00;margin-top:20px">Console API</div>
<p>当打开 firebug (也包括 Chrome 等浏览器的自带调试工具)，window 下面会注册一个叫做 console 的对象，它提供多种方法向控制台输出信息，供开发人员调试使用。下面是这些方法的一个简单介绍，适时地运用它们，对于提高开发效率很有帮助。</p>
<p><strong>console.log(object[, object, ...])</strong><br />
使用频率最高的一条语句：向控制台输出一条消息。支持 C 语言 printf 式的格式化输出。当然，也可以不使用格式化输出来达到同样的目的：</p>
<pre lang="javascript">
var animal='frog', count=10;
console.log("The %s jumped over %d tall buildings", animal, count);
console.log("The", animal, "jumped over", count, "tall buildings");
</pre>
<p><strong>console.debug(object[, object, ...])</strong><br />
向控制台输出一条信息，它包括一个指向该行代码位置的超链接。</p>
<p><strong>console.info(object[, object, ...])</strong><br />
向控制台输出一条信息，该信息包含一个表示“信息”的图标，和指向该行代码位置的超链接。</p>
<p><strong>console.warn(object[, object, ...])</strong><br />
同 info。区别是图标与样式不同。</p>
<p><strong>console.error(object[, object, ...])</strong><br />
同 info。区别是图标与样式不同。error 实际上和 throw new Error() 产生的效果相同，使用该语句时会向浏览器抛出一个 js 异常。</p>
<p><strong>console.assert(expression[, object, ...])</strong><br />
断言，测试一条表达式是否为真，不为真时将抛出异常（断言失败）。</p>
<p><strong>console.dir(object)</strong><br />
输出一个对象的全部属性（输出结果类似于 DOM 面板中的样式）。</p>
<p><strong>console.dirxml(node)</strong><br />
输出一个 HTML 或者 XML 元素的结构树，点击结构树上面的节点进入到 HTML 面板。</p>
<p><strong>console.trace()</strong><br />
输出 Javascript 执行时的堆栈追踪。</p>
<p><strong>console.group(object[, object, ...])</strong><br />
输出消息的同时打开一个嵌套块，用以缩进输出的内容。调用 console.groupEnd() 用以结束这个块的输出。</p>
<p><strong>console.groupCollapsed()</strong><br />
同 console.group(); 区别在于嵌套块默认是收起的。</p>
<p><strong>console.time(name)</strong><br />
计时器，当调用 console.timeEnd(name);并传递相同的 name 为参数时，计时停止，并输出执行两条语句之间代码所消耗的时间（毫秒）。</p>
<p><strong>console.profile([title])</strong><br />
与 profileEnd() 结合使用，用来做性能测试，与 console 面板上 profile 按钮的功能完全相同。</p>
<p><strong>console.count([title])</strong><br />
输出该行代码被执行的次数，参数 title 将在输出时作为输出结果的前缀使用。</p>
<p><strong>console.clear()</strong><br />
清空控制台</p>
<div style="font: bold 18px Arial;color: #C00;margin-top:20px">命令行</div>
<p>控制台的输出面板右边，是控制台的输入面板（Chrome 调试工具对应为下方），在这里除了可以运行常规的 javascript 代码，还内置了相当数量的命令行可以辅助我们的调试工作，下面是一些常用命令行的简单介绍。</p>
<p><strong>$(id)</strong><br />
返回一个给定 id 的元素。</p>
<p><strong>$$(selector)</strong><br />
返回给定的 css 选择器匹配到的一组元素。</p>
<p><strong>$x(xpath)</strong><br />
返回给定的 XPath 表达式匹配到的一组元素。</p>
<p><strong>$0</strong><br />
在 HTML 面板中选中的元素。</p>
<p><strong>$1</strong><br />
上一次在 HTML 面板中选中的元素。</p>
<p><strong>$n(index)</strong><br />
访问最近 5 个被选中过的元素，index 的范围： 0 &#8211; 4。</p>
<p><strong>dir(object)</strong><br />
同 console.dir(object)。</p>
<p><strong>dirxml(node)</strong><br />
同 console.dirxml(node)。</p>
<p><strong>clear()</strong><br />
同 console.clear()。</p>
<p><strong>inspect(object[, tabName])()</strong><br />
在合适的（或一个指定的） tab 中检视一个对象。</p>
<p><strong>keys(object)</strong><br />
返回一个对象的所有属性的键。</p>
<p><strong>values(object)</strong><br />
返回一个对象的所有属性的值。</p>
<p><strong>debug(fn)</strong><br />
在函数第一行添加一个断点，使用 undebug(fn) 移除断点。</p>
<p><strong>monitor(fn)</strong><br />
开启一个函数的调用日志，使用 unmonitor(fn) 关闭该功能。非常有用的一个命令，但是它似乎并没有很好地工作。</p>
<p><strong>monitorEvents(object[, types])</strong><br />
开启一个元素的某个事件（或所有事件）被触发时的日志记录。用例如下：</p>
<pre lang="javascript">
monitorEvents($0,['click'])
</pre>
<p>上面的命令行被执行后，将开启当前在 HTML 面板中被选中元素的 click 事件监控，一旦这个元素的 click 事件被触发，事件对象将会在控制台输出。如果不指定第二个参数，将对所有事件进行记录。</p>
<p><strong>profile([title])</strong><br />
同 console.profile([title])</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/firebug-chrome-console-guid.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《javascript精粹》读书笔记 – 数组</title>
		<link>http://www.smartwei.com/%e3%80%8ajavascript%e7%b2%be%e7%b2%b9%e3%80%8b%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e6%95%b0%e7%bb%84.html</link>
		<comments>http://www.smartwei.com/%e3%80%8ajavascript%e7%b2%be%e7%b2%b9%e3%80%8b%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e6%95%b0%e7%bb%84.html#comments</comments>
		<pubDate>Sun, 23 Jan 2011 15:27:24 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript精萃]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=309</guid>
		<description><![CDATA[记录《javascript精粹》中“数组”这一章节的知识点]]></description>
			<content:encoded><![CDATA[<p><strong>1. </strong>数组length属性的值是这个数组的最大整数属性名加上1.它不一定等于数组里属性的个数：<br />
[js]<br />
var myArray = [];<br />
alert(myArray.length); // 0</p>
<p>myArray[1000000] = true;<br />
alert(myArray.length); //1000001<br />
[/js]</p>
<p><strong>2. </strong>在数组尾部添加一个新元素：<br />
[js]<br />
var numbers = ['zero', 'one', 'two'];<br />
numbers[numbers.length] = &#8216;three&#8217;;<br />
numbers.push(&#8216;four&#8217;);<br />
[/js]</p>
<p><strong>3. </strong>删除数组元素。<br />
js中的数组实际上就是对象，所以delete运算符就可以用来从数组中移除元素：<br />
[js]<br />
var numbers = ['one', 'two', 'three', 'four'];<br />
delete numbers[2]; // ['one', 'two', undefined, 'four']<br />
[/js]<br />
不幸的是，那样会在数组中遗留一个空洞。 通常可以使用splice方法来删除元素：<br />
[js]<br />
var numbers = ['one', 'two', 'three', 'four'];<br />
numbers.splice(2, 1); //['one', 'two', 'four']<br />
[/js]<br />
这个对大型数组来说可能会效率不高。</p>
<p><strong>4. </strong>当属性名是小而连续的整数时，应该使用数组；否则使用对象。</p>
<p>5. 判断是否是数组：<br />
[js]<br />
var is_array = function(value){<br />
	return value &amp;&amp;<br />
		typeof value === &#8216;object&#8217; &amp;&amp;<br />
		value.constructor === Array;<br />
};<br />
[/js]<br />
不幸的是，它在识别从不同的窗口(window)或帧(frame)里构造的数组时会失败。完整的测试方法如下：<br />
[js]<br />
var is_array = function(value){<br />
	return value &amp;&amp;<br />
		typeof value === &#8216;object&#8217; &amp;&amp;<br />
		typeof value.length === &#8216;number&#8217; &amp;&amp;<br />
		typeof value.splice === &#8216;function&#8217; &amp;&amp;<br />
		!(value.propertyIsEnumberable(&#8216;length&#8217;));<br />
};<br />
[/js]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/%e3%80%8ajavascript%e7%b2%be%e7%b2%b9%e3%80%8b%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e6%95%b0%e7%bb%84.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《javascript精粹》读书笔记 – 函数</title>
		<link>http://www.smartwei.com/javascript-good-part-note-function.html</link>
		<comments>http://www.smartwei.com/javascript-good-part-note-function.html#comments</comments>
		<pubDate>Fri, 14 Jan 2011 01:49:19 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript 闭包]]></category>
		<category><![CDATA[javascript精萃]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=305</guid>
		<description><![CDATA[记录《javascript精粹》中“函数”这一章节的知识点]]></description>
			<content:encoded><![CDATA[<p>1. 当实际参数的个数与形式参数的个数不匹配时，不会导致错误。<br />
如果实际参数值过多了，超出的参数值将被忽略；如果实际的参数值过少，缺失的值将被替换为undefined。</p>
<p>2. 在javascript中一共有四种调用模式： 方法调用模式、函数调用模式、构造器调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异。<br />
a.方法调用模式：<br />
当一个函数被保存为对象的一个属性时，我们称它为一个方法。方法调用模式可以使用this去访问对象，所以它能够从对象中取值或修改对象。<br />
b.函数调用模式：<br />
当一个函数并非一个对象的属性时，它被当作一个函数来调用。当函数以此模式调用时，this被绑定到全局变量，这是语言设计上的一个错误。（正确的情况：当内部函数被调用时，this应该仍然被绑定到外部函数的this变量。）解决方法：如果该方法定义一个变量并给他赋值为this,那么内部函数就可以通过那个变量访问到this,按照约定，给那个变量命名为 that：<br />
[js]<br />
	//给 myObject增加一个double方法<br />
	myObject.double = function()<br />
	{<br />
		var that = this; //解决方法</p>
<p>		var helper = function()<br />
		{<br />
			that.value = add(that.value, that.value);<br />
		}</p>
<p>		helper(); //以函数的形式调用helper。<br />
	}</p>
<p>	//以方法的形式调用double<br />
	myObject.double();<br />
[/js]<br />
c.构造器调用模式：<br />
在一个函数前面带上new来调用，那么将创建一个隐藏连接到该函数的prototype成员的新对象，同时this将会被绑定到那个新对象上。<br />
[js]<br />
	//创建一个名为Quo的构造函数。它构造一个带有status属性的对象<br />
	var Quo = function(String)<br />
	{<br />
		this.status = String;<br />
	}</p>
<p>	//给Quo的所有实例提供一个名为get_status的公共方法<br />
	Quo.prototype.get_status = function()<br />
	{<br />
		return this.status;<br />
	}</p>
<p>	//构造一个Quo实例<br />
	var myQuo = new Quo(&quot;confused&quot;); //构造器模式调用<br />
	document.writeln(myQuo.get_status());<br />
[/js]<br />
按照约定，构造器函数保存在以大写格式命名的变量里。<br />
d.Apply调用模式:<br />
apply方法接受两个参数，第一个是将被绑定给this的值，第二个就是参数数组。它让我们构建一个参数数组并用其去调用函数。<br />
[js]<br />
	//构造一个Quo实例<br />
	var myQuo = new Quo(&quot;confused&quot;); //构造器模式调用<br />
	document.writeln(myQuo.get_status());</p>
<p>	//构建一个包含两个数字的数组，并将他们相加<br />
	add = function(a, b)<br />
	{<br />
		return a+b;<br />
	}</p>
<p>	var anArray = [3, 4];<br />
	var sum = add.apply(null, anArray);  //7</p>
<p>	//构建一个包含status成员的对象<br />
	var statusObject = {<br />
		status: &quot;A-OK&quot;<br />
	};</p>
<p>	//statusObject并没有继承自Quo.prototype,但我们可以再statusObject上调用<br />
	//get_status方法，尽管statusObject并没有一个名为get_status的方法。<br />
	var status = Quo.prototype.get_status.apply(statusObject);<br />
[/js]</p>
<p>3. 参数：<br />
当一个函数被调用时，会有一个默认的参数，就是 arguments “数组”。<br />
[js]<br />
	//构造一个将很多值相加的函数</p>
<p>	//注意该函数内部定义的变量sum不会与函数外部定义的sum产生冲突。<br />
	//该函数只能看到内部的那个变量。<br />
	var sum = function()<br />
	{<br />
		var i, sum=0;<br />
		for(i = 0; i &lt; arguments.length; i+=1)<br />
		{<br />
			sum += arguments[i];<br />
		}<br />
		return sum;<br />
	};</p>
<p>	document.writeln(sum(4, 8, 15, 16, 23, 42)); //108<br />
[/js]<br />
注：arguments并不是一个真正的数组。它知识一个“类似数组”的对象。arguments用友一个length属性，但它缺少所有的数组方法。</p>
<p>4. 返回:<br />
一个函数总是会返回一个值。如果没有置顶返回值，则返回undefined。<br />
如果函数以构造器方式被调用，且返回值不是一个对象，则返回this(该新对象)。</p>
<p>5.给类型增加方法：<br />
[js]<br />
	Function.prototype.method = function(name, func)<br />
	{<br />
		this.prototype[name] = func;<br />
		return this;<br />
	}</p>
<p>	//给Number添加一个integer方法，来提取数字钟的整数部分<br />
	//根据正负来判断是使用Math.ceil还是Math.floor<br />
	Number.method(&#8216;integer&#8217;, function(){<br />
	 return Math[this &lt; 0 ? 'ceil' : 'floor'](this);<br />
	});</p>
<p>	document.writeln((-10/3).integer()); //-3</p>
<p>	//去掉字符串两端空白的方法<br />
	String.method(&#8216;trim&#8217;, function()<br />
	{<br />
		return this.replace(/^\s+|\s+$/g, ”);<br />
	});<br />
[/js]<br />
基本类型的原型是公共结构，所以在类库混用时务必小心。一个保险的做法就是只在确定没有该方法时再添加：<br />
[js]<br />
	//有条件的增加一个方法</p>
<p>	Function.prototype.method = function(name, func)<br />
	{<br />
		if(!this.prototype[name])<br />
		{<br />
			this.prototype[name] = func;<br />
			return this;<br />
		}<br />
	};<br />
[/js]</p>
<p>6.闭包<br />
理解内部函数能访问外部函数的实际变量而无需<strong>复制</strong><br />
[js]<br />
//构造一个函数，用错误的方式给一个数组中的借点设置事件处理程序<br />
//当点击一个节点时，按照预想应该弹出一个对话框显示节点的序号<br />
//但他总是会显示节点的数目</p>
<p>var add_the_handlers = function(nodes) {<br />
	var i;<br />
	for (i = 0; i &lt; nodes.length; i += 1) {<br />
			nodes[i].onclick = function(e) {<br />
				alert(i);<br />
			}<br />
	}<br />
}<br />
[/js]<br />
add_the_handlers函数的目的是给每个事件处理器一个唯一值（i）。它未能达到目的的原因是事件处理器函数绑定了变量i，而不是<strong>函数在构造时的变量i的值</strong>。<br />
正确的写法：<br />
[js]<br />
//点击一个节点，将会弹出一个对话框显示节点的序号<br />
var add_the_handlers = function (nodes) {<br />
	var i;<br />
	for (i = 0; i &lt; nodes.length; i +=1 ) {<br />
		nodes[i].onclick = function (i) {<br />
			return funtion (e) {<br />
				return alert(e);<br />
			} ;<br />
		}(i);<br />
	}<br />
}<br />
[/js]<br />
现在，定义了一个函数并立即传递i进去执行， 而不是把一个函数赋值给onclick。那个函数将返回一个事件处理器函数。这个事件处理器函数绑定的是传递进去的i的值，而不只定义在add_the_handlers函数里的i的值。那个被返回的函数被复制给onclick。</p>
<p>7.javascript的单例模式<br />
Javascript的单例就是用对象字面量表示法创建的对象，对象的属性值可以是数值或函数，并且属性值在该对象的生命周期中不会发生变化。他通常作为<b>工具为程序其他部分提供功能支持</b></p>
<p>8.模块<br />
模块模式的一般形式是：一个定义了<b>私有变量和函数的函数</b>；利用<b>闭包</b>创建可以访问<b>私有变量和函数</b>的特权函数,或者把他们保存到一个可访问的地方。<br />
[js]<br />
String.method(&#8216;deentityify&#8217;, function (){<br />
	var entity = {<br />
		quot: &#8216;&quot;&#8217;,<br />
		lt: &#8216;&lt;&#8217;,<br />
		gt: &#8216;&gt;&#8217;<br />
	}</p>
<p>	return function () {<br />
		return this.replace(/&amp;([^&amp;;]+);/g,<br />
			function (a, b) {<br />
				var r = entity[b];<br />
				return typeof r === &#8216;string&#8217; ? r : a;<br />
		});<br />
	};<br />
}());<br />
[/js]<br />
模块模式利用了函数作用域和闭包来创建绑定对象与私有成员关联，摒弃了全局变量的使用，从而缓解这个JavaScript的最为糟糕的特性之一所带来的影响</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/javascript-good-part-note-function.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《javascript精粹》读书笔记 &#8211; 对象</title>
		<link>http://www.smartwei.com/javascript-good-part-note.html</link>
		<comments>http://www.smartwei.com/javascript-good-part-note.html#comments</comments>
		<pubDate>Sun, 09 Jan 2011 05:29:33 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript精萃]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=302</guid>
		<description><![CDATA[整理了《javascript精粹》中关于对象的一些内容]]></description>
			<content:encoded><![CDATA[<p>《javascript精粹》中和对象相关的内容：</p>
<p>1. 当尝试检索对象的一个并不存在的成员元素的值，将返回一个undefined值。可以通过“||”运算符来填充默认值：<br />
[js]<br />
stooge[&quot;middle-name&quot;] //undefined<br />
var middle = stooge[&quot;middle-name&quot;] || &quot;tom&quot;;<br />
[/js]</p>
<p>2. 当尝试检索一个undefined值将会导致TypeError异常。可以通过“&#038;&#038;”运算符来避免错误：<br />
[js]<br />
flight.equipment  //undefined<br />
flight.equipment.model //throw &quot;TypeError&quot;<br />
flight.equipment &amp;&amp; flight.equipment.model //undefined<br />
[/js]</p>
<p>3. 对象通过引用来传递。他们永远不会被拷贝<br />
[js]<br />
var x = stooge;<br />
x.nickname = &#8216;Curly&#8217;;<br />
var nick = stooge.nickname;<br />
//因为x和stooge是指向同一个对象的引用，所以nick的值为&#8217;Curly&#8217;</p>
<p>var a={}, b={}, c={};<br />
//a, b和c每个都引用一个&lt;strong&gt;不同&lt;/strong&gt;的空对象</p>
<p>a=b=c={}<br />
//a,b和c都引用&lt;strong&gt;同一个&lt;/strong&gt;空对象<br />
[/js]</p>
<p>4. 原型连接<br />
通过beget方法创建一个使用原对象作为其原型的新对象<br />
[js]<br />
if (typeof Object.beget !== &#8216;function&#8217;)<br />
{<br />
    Object.beget = function (o)<br />
    {<br />
        var F = function () {};<br />
        F.prototype = o;<br />
        return new F();<br />
    }<br />
}</p>
<p>var another_stooge = Object.beget(stooge);<br />
[/js]<br />
<strong>注：</strong><br />
a. 原型连接在更新时是不起作用的<br />
当我们对某个对象作出改变时，不会触及到该对象的原型。<br />
b. 原型连接只有在检索值的时候才被用到<br />
如果尝试去获取对象的某个属性值，且该对象没有此属性名，那么从它的圆形对象中获取属性值。 （如果那个原型对象也没有该属性值，那么再从它的原型中寻找，依次类推，知道该过程左后的重点Object.prototype。如果想要的属性完全不存在于原型链中，那么结果就是<strong>undefined</strong>值。这个过程称为<strong>委托</strong>）<br />
c. 原型关系是一种动态关系。<br />
如果我们添加一个新的属性到原型中，该属性会立即对所有基于该原形创建的对象可见。</p>
<p>5. 反射<br />
在一些时候下，我们需要能够在对对象完全不了解的情况下进行处理，并且在处理之前发现他们的属性和方法，这个过程称作反射（reflection）。<br />
在判断对象是否有某一属性时，可以使用”<strong>hasOwnProperty</strong>“方法，如果对象拥有独有的属性，它将返回true。<br />
注：hasOwnProperty方法不会检查原型链。</p>
<p>6. 枚举<br />
for in 语句可以用来遍历一个对象中的所有属性名。<br />
属性名出现的顺序是不确定的，因此要对任何可能出现的顺序有所准备。如果你想要确保属性以特定的顺序出现，最好的办法就是完全避免使用for in语句，而是创建一个数组，在其中以正确的顺序包含属性名：<br />
[js]<br />
//使用for in语句：<br />
	var name;<br />
	for (name in another_stooge)<br />
	{<br />
		if(typeof another_stooge[name] !== &#8216;function&#8217;)<br />
		{<br />
			document.writeln(name + &#8216;: &#8216; + another_stooge[name]);<br />
		}<br />
	}</p>
<p>//使用for语句<br />
	var i;<br />
	var properties = [<br />
		'first-name',<br />
		'middle-name',<br />
		'last-name',<br />
		'profession'<br />
	]<br />
	for (i=0; i&lt;properties.length; i +=1)<br />
	{<br />
		document.writeln(properties[i] + &#8216;: &#8216; +<br />
					another_stooge[properties[i]]);<br />
	}<br />
[/js]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/javascript-good-part-note.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>js DOM 事件绑定</title>
		<link>http://www.smartwei.com/js-add-event.html</link>
		<comments>http://www.smartwei.com/js-add-event.html#comments</comments>
		<pubDate>Thu, 11 Nov 2010 03:45:46 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=288</guid>
		<description><![CDATA[jsDOM事件绑定以及onload事件绑定——兼容原有函数]]></description>
			<content:encoded><![CDATA[<p><b>Js绑定DOM事件</b><br />
[js]<br />
function addEvent( obj, type, fn ) {<br />
	if( obj.attachEvent ) {<br />
		obj[ 'e' + type + fn ] = fn;<br />
		obj[ type + fn ] = function() {<br />
			ojb[ 'e' + type + fn ]( window.event );<br />
		}<br />
		obj.attachEvent( &#8216;on&#8217; + type, obj[ type + fn ]);<br />
	}<br />
	else {<br />
		obj.addEventListener( type, fn, false );<br />
	}<br />
}</p>
<p>function removeEvent( ojb, type, fn ) {<br />
	if( obj.detachEvent ) {<br />
		obj.detachEvent( &#8216;on&#8217; + type + obj[ type + fn ] );<br />
		obj[ type + fn ] = null;<br />
	}<br />
	else {<br />
		ojb.removeEventListener( type, fn, false );<br />
	}<br />
}<br />
[/js]<br />
<br />
<b>JS绑定onLoad事件</b><br />
[js]<br />
function addLoadEvent( func ) {<br />
	var oldonload = window.onload;<br />
	if( typeof window.onload != &#8216;function&#8217; ) {<br />
		window.onload = func;<br />
	}<br />
	else {<br />
		window.onload = function() {<br />
			oldonload();<br />
			func();<br />
		}<br />
	}<br />
}<br />
[/js]<br />
作者: <a href="http://www.smartwei.com">石巍</a><br />
原载: <a href="http://www.smartwei.com/js-add-event.html">10V的博客</a><br />
链接: <a href="http://www.smartwei.com/js-add-event.html">http://www.smartwei.com/js-add-event.html</a><br />
版权所有，转载时必须以超链接形式注明作者和原始出处及本声明。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/js-add-event.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript实现url跳转</title>
		<link>http://www.smartwei.com/javascript-url-redirect.html</link>
		<comments>http://www.smartwei.com/javascript-url-redirect.html#comments</comments>
		<pubDate>Mon, 01 Nov 2010 03:49:16 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=286</guid>
		<description><![CDATA[javascript实现url跳转，可以设置延时跳转]]></description>
			<content:encoded><![CDATA[<p>做下笔记, js实现url跳转,可以设置延时跳转:<br />
[js]<br />
function urlJump( url, secs)<br />
{<br />
	var secs = parseInt( secs ) &gt; 0 ? parseInt( secs ) * 1000 : 0;<br />
	if( !-[1,] )<br />
	{ //判断是否为IE浏览器。 当为IE浏览器时 [1,].toString()输出为&#8217;1,&#8217;, 其他浏览器输出为&#8217;1&#8242;;<br />
		var a = document.createElement( &#8216;a&#8217; );<br />
		a.href = url;<br />
		document.body.appendChild( a );<br />
		setTimeout(function(){a.click()}, secs);<br />
	}<br />
	else<br />
	{<br />
		setTimeout(&quot;location.href = &#8216;&quot; + url + &quot;&#8217;&quot;, secs);<br />
	}<br />
}<br />
[/js]</p>
<p>作者: <a href="http://www.smartwei.com">石巍</a><br />
原载: <a href="http://www.smartwei.com/javascript-url-redirect.html">10V的博客</a><br />
版权所有，转载时必须以超链接形式注明作者和原始出处及本声明。</p>
<p>本文链接: <a href="http://www.smartwei.com/javascript-url-redirect.html">http://www.smartwei.com/javascript-url-redirect.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/javascript-url-redirect.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>非常实用的javascript设置、获取、删除cookie函数</title>
		<link>http://www.smartwei.com/javascript-cookie-functions.html</link>
		<comments>http://www.smartwei.com/javascript-cookie-functions.html#comments</comments>
		<pubDate>Mon, 01 Nov 2010 02:53:19 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=284</guid>
		<description><![CDATA[非常实用的javascript设置、获取、删除cookie函数]]></description>
			<content:encoded><![CDATA[<p>做下笔记，非常好用的javascript操作cookie函数：<br />
[js]<br />
//secure设置为ture时，只有是HTTPS连接时才设置cookie<br />
function setcookie( name, value, expires, path, domain, secure )<br />
{<br />
	var today = new Date();<br />
	today.setTime( today.getTime() );<br />
	var expire_date = new Date( today.getTime() + (expires * 1000 ) );<br />
	document.cookie = name + &#8216;=&#8217; + escape( value ) +<br />
		( ( expires ) ? &#8216;;expires=&#8217; + expire_date.toGMTString() : ” ) +<br />
		( ( path) ? &#8216;;path=&#8217; + path : ” ) +<br />
		( ( domain ) ? &#8216;;domain=&#8217; + domain : ” ) +<br />
		( ( secure ) ? &#8216;;secure&#8217; : ” );<br />
}</p>
<p>function getcookie( name )<br />
{<br />
	var start = document.cookie.indexOf( name + &quot;=&quot; );<br />
	var len = start + name.length + 1;<br />
	if( ( !start ) &amp;&amp; ( name != document.cookie.substring( 0, name.length ) ) )<br />
	{<br />
		return null;<br />
	}<br />
	if( start == -1 )<br />
	{<br />
		return null;<br />
	}<br />
	var end = document.cookie.indexOf( &#8216;;&#8217;, len );<br />
	if( end == -1 )<br />
	{<br />
		end = document.cookie.length;<br />
	}<br />
	return unescape( document.cookie.substring( len, end ) );<br />
}</p>
<p>function delcookie( name, path, domain )<br />
{<br />
	var exp = new Date();<br />
	exp.setTime( exp.getTime() &#8211; 1 );<br />
	var cval = getcookie( name );<br />
	document.cookie = name + &quot;=&quot; + cval + &quot;;expires=&quot; + exp.toGMTString() +<br />
		( ( path ) ? &#8216;;path&#8217; + path : ” ) +<br />
		( ( domain ) ? &#8216;;domain=&#8217; + domain : ” );<br />
} </p>
<p>[/js]</p>
<p>作者: <a href="http://www.smartwei.com">石巍</a><br />
原载: <a href="http://www.smartwei.com/javascript-cookie-functions.html">10V的博客</a><br />
版权所有，转载时必须以超链接形式注明作者和原始出处及本声明。</p>
<p>本文链接: <a href="http://www.smartwei.com/javascript-cookie-functions.html">http://www.smartwei.com/javascript-cookie-functions.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/javascript-cookie-functions.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript判断各种浏览器</title>
		<link>http://www.smartwei.com/javascript-judge-browers.html</link>
		<comments>http://www.smartwei.com/javascript-judge-browers.html#comments</comments>
		<pubDate>Mon, 01 Nov 2010 02:15:22 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=279</guid>
		<description><![CDATA[这篇文章介绍了javascript如何判断当前浏览器是否是IE浏览器，Mozilla浏览器，Firefox浏览器，Safari浏览器以及Opera浏览器]]></description>
			<content:encoded><![CDATA[<p><b>Javascript判断是否是Mozilla浏览器</b></p>
<p>
[js]<br />
var isMozilla = ( typeof document.implementation != &#8216;undefined&#8217; ) &amp;&amp; ( typeof document.implementation.createDocument != &#8216;undefined&#8217; ) &amp;&amp; ( typeof HTMLDocument != &#8216;undefined&#8217;);<br />
[/js]
</p>
<p><b>Javascript判断是否是IE浏览器</b></p>
<p>
[js]<br />
var isIE = window.ActiveXObject ? true; false;<br />
[/js]
</p>
<p><b>Javascript判断是否是Firefox浏览器</b></p>
<p>
[js]<br />
var isFirefox = ( navigator.userAgent.toLowerCase().indexOf( &#8216;firefox&#8217; ) != -1 );<br />
[/js]
</p>
<p><b>Javascript判断是否是Safari浏览器</b></p>
<p>
[js]<br />
var isSafari = ( navigator.userAgent.toLowerCase().indexOf( &#8216;safari&#8217; ) != -1 );<br />
[/js]
</p>
<p><b>Javascript判断是否是Opera浏览器</b></p>
<p>
[js]<br />
var isOpera = ( navigator.userAgent.toLowerCase().indexOf( &#8216;opera&#8217; ) != -1);<br />
[/js]
</p>
<p>作者: <a href="http://www.smartwei.com">石巍</a><br />
原载: <a href="http://www.smartwei.com/javascript-judge-browers.html">10V的博客</a><br />
版权所有，转载时必须以超链接形式注明作者和原始出处及本声明。</p>
<p>本文链接: <a href="http://www.smartwei.com/javascript-judge-browers.html">http://www.smartwei.com/javascript-judge-browers.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/javascript-judge-browers.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>工作收获碎碎念20101021 &#8211; 石巍的博客10V</title>
		<link>http://www.smartwei.com/work-benefit-20101021.html</link>
		<comments>http://www.smartwei.com/work-benefit-20101021.html#comments</comments>
		<pubDate>Thu, 21 Oct 2010 11:45:57 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[工作收获]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=277</guid>
		<description><![CDATA[2010.10.21当天工作收获，发现了以前没注意到的一些细节]]></description>
			<content:encoded><![CDATA[<p>1. realpath可以获得<strong>绝对路径</strong><br />
2. 全局文件中使用<strong>静态变量</strong>可以减少加载文件的时间 （静态数组中存放需要加载的文件，如果已经加载则直接返回true，未加载则加载并在静态数组中添加该文件）<br />
3. redirct可以通过header(“refresh: {$time};url={$url}”); 来设置<strong>延时</strong>跳转到对应的url<br />
4. $objects[$class] = &#038; new $class(); 这里的&#038;可以是实例化的对象以引用的方式传递，不需要复制（单例模式）<br />
5. trim($str, $mark)可以过滤掉$str头尾出现的$mark字符串，默认mark为\s<br />
6. 可以通过$_SERVER['HTTP_USER_AGENT']来判断是否是浏览器过来的请求<br />
7. 在获取当前时间时，先执行date_default_timezone_set(“PRC”);可以获取更准确的中国时间<br />
8. 在截字时，可以通过mb_internal_encoding(“UTF-8&#8243;);来设置截取字符串的编码，并通过mb_strlen和mb_substr来正确截字<br />
9. $this->{$this->act}(); 这样可以省去很多代码<br />
10. YSLOW研究：<br />
a. minify js和css；合并所有js到一个js；合并所有css到一个css；将css放在头部；将js放在尾部。<br />
b. 当网站要分布式的时候，使用CDN(适合大中型网站，小网站不用考虑..)<br />
c. 给静态内容增加一个长久的过期时间<br />
d. 使用gzip压缩内容<br />
e. 减少DNS查询：尽量让页面上面的元素（图片，css等静态内容）不要使用不同域名的。否则会解析多个域名导致DNS多次查询影响速度<br />
f. 设置Etag (Entity tags)<br />
g. 减少dom数量</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/work-benefit-20101021.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>深入理解 JavaScript闭包(closure)</title>
		<link>http://www.smartwei.com/javascript-closure.html</link>
		<comments>http://www.smartwei.com/javascript-closure.html#comments</comments>
		<pubDate>Fri, 02 Jul 2010 03:26:55 +0000</pubDate>
		<dc:creator>10V</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript 闭包]]></category>

		<guid isPermaLink="false">http://www.smartwei.com/?p=272</guid>
		<description><![CDATA[深入理解 JavaScript闭包(closure) - 本文介绍了闭包的基本概念、微观世界、以及应用场景，对于学习javascript闭包的朋友很有帮助]]></description>
			<content:encoded><![CDATA[<p>最近在网上查阅了不少Javascript闭包(closure)相关的资料，写的大多是非常的学术和专业。对于初学者来说别说理解闭包了，就连文字叙述都很难看懂。撰写此文的目的就是用最通俗的文字揭开Javascript闭包的真实面目。</p>
<p><strong>一、什么是闭包？</strong><br />
“官方”的解释是：闭包是一个拥有许多变量和绑定了这些变量的环境的表达式（通常是一个函数），因而这些变量也是该表达式的一部分。<br />
相信很少有人能直接看懂这句话，因为他描述的太学术。其实这句话通俗的来说就是：JavaScript中所有的function都是一个闭包。不过一般来说，嵌套的function所产生的闭包更为强大，也是大部分时候我们所谓的“闭包”。看下面这段代码：<br />
[js]<br />
function a() {<br />
    var i = 0;<br />
    function b() {<br />
        alert(++i);<br />
    }<br />
    return b;<br />
}<br />
var c = a();<br />
c();<br />
[/js]</p>
<p><span id="more-272"></span><br />
这段代码有两个特点：</p>
<ol>
<li>函数b嵌套在函数a内部；</li>
<li>函数a返回函数b。</li>
</ol>
<p>引用关系如图：<br />
<a href="http://www.smartwei.com/javascript-closure.html"><img src="http://www.smartwei.com/wp-content/uploads/2010/07/jsclosure.jpg" alt="jsclosure" title="jsclosure" width="228" height="175" class="aligncenter size-full wp-image-273" /></a></p>
<blockquote style="color:#C00; font-weight:bold"><p>
当函数a的内部函数b被函数a外的一个变量引用的时候，就创建了一个我们通常所谓的“闭包”。
</p></blockquote>
<p>让我们说的更透彻一些。所谓“闭包”，就是在构造函数体内定义另外的函数作为目标对象的方法函数，而这个对象的方法函数反过来引用外层函数体中的临时变量。这使得只要目标 对象在生存期内始终能保持其方法，就能间接保持原构造函数体当时用到的临时变量值。尽管最开始的构造函数调用已经结束，临时变量的名称也都消失了，但在目 标对象的方法内却始终能引用到该变量的值，而且该值只能通这种方法来访问。即使再次调用相同的构造函数，但只会生成新对象和方法，新的临时变量只是对应新 的值，和上次那次调用的是各自独立的。</p>
<p>为了更深刻的理解闭包，下面让我们继续探索闭包的作用和效果。</p>
<p><strong>二、闭包有什么作用和效果？</strong><br />
简而言之，闭包的作用就是在a执行完并返回后，闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源，因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述，不专业也不严谨，但你一定能看懂。理解闭包需要循序渐进的过程。<br />
在上面的例子中，由于闭包的存在使得函数a返回后，a中的i始终存在，这样每次执行c()，i都是自加1后alert出i的值。</p>
<p>那么我们来想象另一种情况，如果a返回的不是函数b，情况就完全不同了。因为a执行完后，b没有被返回给a的外界，只是被a所引用，而此时a也只会被b引用，因此函数a和b互相引用但又不被外界打扰(被外界引用)，函数a和b就会被GC回收。(关于Javascript的垃圾回收机制将在后面详细介绍)</p>
<p><strong>三、闭包的微观世界</strong><br />
如果要更加深入的了解闭包以及函数a和嵌套函数b的关系，我们需要引入另外几个概念：函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。</p>
<ol>
<li>当定义函数a的时候，js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”，如果a是一个全局函数，则scope chain中只有window对象。</li>
<li>当执行函数a的时候，a会进入相应的执行环境(excution context)。</li>
<li>在创建执行环境的过程中，首先会为a添加一个scope属性，即a的作用域，其值就为第1步中的scope chain。即a.scope=a的作用域链。</li>
<li>然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象，但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后，把活动对象添加到a的作用域链的最顶端。此时a的作用域链包含了两个对象：a的活动对象和window对象。</li>
<li>下一步是在活动对象上添加一个arguments属性，它保存着调用函数a时所传递的参数。</li>
<li>最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中，完成了函数b的的定义，因此如同第3步，函数b的作用域链被设置为b所被定义的环境，即a的作用域。</li>
</ol>
<p>到此，整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c，又函数b的作用域链包含了对函数a的活动对象的引用，也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用，函数b又依赖函数a，因此函数a在返回后不会被GC回收。</p>
<p>当函数b执行的时候亦会像以上步骤一样。因此，执行时b的作用域链包含了3个对象：b的活动对象、a的活动对象和window对象，如下图所示：<br />
<a href="http://www.smartwei.com/javascript-closure.html"><img src="http://www.smartwei.com/wp-content/uploads/2010/07/jsclosure-scopechain.jpg" alt="jsclosure-scopechain" title="jsclosure-scopechain" width="500" height="180" class="aligncenter size-full wp-image-274" /></a><br />
如图所示，当在函数b中访问一个变量的时候，搜索顺序是：</p>
<ol>
<li>先搜索自身的活动对象，如果存在则返回，如果不存在将继续搜索函数a的活动对象，依次查找，直到找到为止。</li>
<li>如果函数b存在prototype原型对象，则在查找完自身的活动对象后先查找自身的原型对象，再继续查找。这就是Javascript中的变量查找机制。</li>
<li>如果整个作用域链上都无法找到，则返回undefined。</li>
</ol>
<p>小结，本段中提到了两个重要的词语：函数的定义与执行。文中提到函数的作用域是在定义函数时候就已经确定，而不是在执行的时候确定（参看步骤1和3）。用一段代码来说明这个问题：<br />
[js]<br />
function f(x) {<br />
    var g = function () { return x; }<br />
    return g;<br />
}<br />
var h = f(1);<br />
alert(h());<br />
[/js]<br />
这段代码中变量h指向了f中的那个匿名函数(由g返回)。</p>
<ul>
<li>假设函数h的作用域是在执行alert(h())确定的，那么此时h的作用域链是：h的活动对象->alert的活动对象 ->window对象。</li>
<li>假设函数h的作用域是在定义时确定的，就是说h指向的那个匿名函数在定义的时候就已经确定了作用域。那么在执行的时候，h的作用域链为：h的活动对象->f的活动对象->window对象。</li>
</ul>
<p>如果第一种假设成立，那输出值就是undefined；如果第二种假设成立，输出值则为1。</p>
<p>运行结果证明了第2个假设是正确的，说明函数的作用域确实是在定义这个函数的时候就已经确定了。</p>
<p><strong>四、闭包的应用场景</strong></p>
<ol>
<li>保护函数内的变量安全。以最开始的例子为例，函数a中i只有函数b才能访问，而无法通过其他途径访问到，因此保护了i的安全性。</li>
<li>在内存中维持一个变量。依然如前例，由于闭包，函数a中i的一直存在于内存中，因此每次执行c()，都会给i自加1。</li>
<li>通过保护变量的安全实现JS私有属性和私有方法（不能被外部访问）推荐阅读：http://javascript.crockford.com/private.html<br />
私有属性和方法在Constructor外是无法被访问的 </li>
</ol>
<p>[js]<br />
function Constructor(&#8230;) {<br />
    var that = this;<br />
    var membername = value;<br />
    function membername(&#8230;) {&#8230;}<br />
}<br />
[/js]<br />
以上3点是闭包最基本的应用场景，很多经典案例都源于此。</p>
<p><strong>五、Javascript的垃圾回收机制</strong><br />
在Javascript中，如果一个对象不再被引用，那么这个对象就会被GC回收。如果两个对象互相引用，而不再被第3者所引用，那么这两个互相引用的对象也会被回收。因为函数a被b引用，b又被a外的c引用，这就是为什么函数a执行后不会被回收的原因。</p>
<p><strong>六、结语</strong><br />
理解JavaScript的闭包是迈向高级JS程序员的必经之路，理解了其解释和运行机制才能写出更为安全和优雅的代码。如果您对本文有任何的建议和疑问，欢迎留言。</p>
<p>作者: <a href="http://www.smartwei.com">石巍</a><br />
原载: <a href="http://www.felixwoo.com/archives/247">Felix Woo &#8211; 深入理解 JavaScript闭包(closure)</a><br />
版权所有，转载时必须以超链接形式注明作者和原始出处及本声明。</p>
<p>本文链接: <a href="http://www.smartwei.com/javascript-closure.html">http://www.smartwei.com/javascript-closure.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.smartwei.com/javascript-closure.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

