<?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>Lefter &#187; javascript</title>
	<atom:link href="http://lefter.net/blog/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://lefter.net/blog</link>
	<description>blog of lefter</description>
	<lastBuildDate>Mon, 23 Nov 2009 10:27:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CSS,JS文件压缩工具</title>
		<link>http://lefter.net/blog/compressor/</link>
		<comments>http://lefter.net/blog/compressor/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 10:27:56 +0000</pubDate>
		<dc:creator>lujo</dc:creator>
				<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[程序相关]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[yuicompressor]]></category>

		<guid isPermaLink="false">http://lefter.net/blog/?p=1122</guid>
		<description><![CDATA[js/css文件常见的压缩工具有：		

			YUIcompressor GUI TBcompressor
			ESC(ECMAScript cruncher)
			JSmin
  GUI:JsMinGUI
			Dojo ShrinkSafe
			在线Js压缩
			Google Closure compiler   Closure Tools			
打包下载地址
		
Yuicompre... ]]></description>
			<content:encoded><![CDATA[<h4>js/css文件常见的压缩工具有：</h4>		
<ul>
			<li><a href="http://yuilibrary.com/downloads/#yuicompressor">YUIcompressor</a><sup> GUI TBcompressor</sup></li>
			<li><a href="http://www.saltstorm.net/depo/esc/">ESC(ECMAScript cruncher)</a></li>
			<li><a href="http://www.crockford.com/javascript/jsmin.html">JSmin</a>
 <sup> GUI:JsMinGUI</sup></li>
			<li><a href="http://www.dojotoolkit.org/docs/shrinksafe">Dojo ShrinkSafe</a></li>
			<li><a href="http://dean.edwards.name/packer/">在线Js压缩</a></li>
			<li><a href="http://code.google.com/closure/compiler/">Google Closure compiler</a>  <sup> <a href="http://code.google.com/closure/">Closure Tools</a></sup></li>			
<li><strong><a href="http://lefter.googlecode.com/files/JS-css%E5%8E%8B%E7%BC%A9%E5%B7%A5%E5%85%B7.7z">打包下载地址</a></strong></li>
		</ul>
<h4>Yuicompressor的用法</h4>
<pre><code>java -jar D:\yuicompressor-2.4.2\build\yuicompressor-2.4.2.jar 
--charset UTF-8 D:\my.js -o D:\my-min.js
	
java -jar D:\yuicompressor-2.4.2\build\yuicompressor-2.4.2.jar 
--charset UTF-8 D:\my.css -o D:\my-min.css 
</code></pre>
<p>具体语法和其他参数参考：<a href="http://www.julienlecomte.net/yuicompressor/">julienlecomte Yuicompressor</a>。 也可以写一个批处理文件<a href="http://hi.baidu.com/wymwon/blog/item/f060cd6e868b6adc80cb4a6f.html">具体格式</a>，同时处理多个文件，例如:将D盘中的WEBsite文件夹下的所有.CSS , .JS文件进行压缩</p>
<pre><code>@echo off
::设置YUI Compressor启动目录
SET YUIFOLDER=D:\yuicompressor-2.4.2\build
::设置你的JS和CSS根目录，脚本会自动按树层次查找和压缩所有的JS和CSS
SET JSFOLDER=D:\WEBsite
echo look for JavaScript, CSS ...
chdir /d %JSFOLDER%
for /r . %%a in (*.js *.css) do (
@echo It's compressing  %%~a ...
@java -jar %YUIFOLDER%\yuicompressor-2.4.2.jar --charset UTF-8 %%~fa -o %%~fa
 )
@echo OK!
pause &amp; exit</code></pre>
<h4>ESC(ECMAScript cruncher)</h4>
<p>这个工具只能在Windows下使用,ESC.wsf提供5种压缩级别，从0到4：<br/>
Level 0 :: No compression 不对JS文件进行压缩<br/>
Level 1 :: Comment removal 移除JS文件中的注释<br/>
Level 2 :: Whitespace removal 移除JS文件中的注释及空行（默认，一般选择此级别就足够了）<br/>
Level 3 :: Newline removal 移除JS文件中的注释，将所有代码合并为一行<br/>
Level 4 :: Variable substitution 提供最新的压缩率，移除JS文件中的注释，将所有代码合并为一行，并且修改JS文件中的变量名。例如：将"big.js"按照压缩级别2来压缩（ESC.wsf默认压缩级别为2）为"min.js"</p>
<pre><code>cscript ESC.wsf -ow min.js big.js </code></pre>
<h4>Google Closure Tools 包含三大块</h4>
<ol>
<li><a href="http://code.google.com/closure/compiler/">Closure Compiler</a>：这是个JavaScript优化器，可以将JavaScript编译成压缩的、高性能代码。它除了能移除无效代码，重写代码使其最小化且运行更快，还能检查语法、变量引用和类型，并对一些常见JavaScript错误提出警告。同时，它还提供了Closure Inspector（一个Firefox插件）用于调试编译后的代码。<a href="http://closure-inspector.googlecode.com/files/closureinspector09.xpi">FireFox插件</a></li>
<li><a href="http://code.google.com/closure/library/">Closure Library</a>：这是个广泛的、经过良好测试、模块化且跨浏览器的JavaScript库。在例子中可以看到，Google Docs就是用这个库写的。</li>
<li><a href="http://code.google.com/closure/templates/">Closure Templates</a>：这是一个为Java和JavaScript实现的模板系统，可在服务器和客户端使用相同的模板。值得一提的是，JavaScript模板会进行预编译处理，以提高其性能。此外，Gmail和Google Docs也是使用该模板系统。</li>
</ol>]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/compressor/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JavaScript中的Function对象</title>
		<link>http://lefter.net/blog/javascript-function/</link>
		<comments>http://lefter.net/blog/javascript-function/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 15:33:54 +0000</pubDate>
		<dc:creator>lujo</dc:creator>
				<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://lefter.net/blog/?p=841</guid>
		<description><![CDATA[函数的类型分为三类

	作为普通逻辑代码容器
	作为对象方法
作为构造函数	

函数逻辑代码容器
function Add(x,y){
    return x+y
}
alert(Add(2,8));

定义一个函数有三种方式

	函数声明function fo... ]]></description>
			<content:encoded><![CDATA[<p>函数的类型分为三类</p>
<ol>
	<li><a href="#content">作为普通逻辑代码容器</a></li>
	<li><a href="#method">作为对象方法</a></li>
<li><a href="#constructor">作为构造函数</a></li>	
</ol>
<h4><a name="content">函数逻辑代码容器</a></h4>
<pre><code>function Add(x,y){
    return x+y
}
alert(Add(2,8));
</code></pre>
定义一个函数有三种方式
<ol>
	<li>函数声明function foo(){}</li>
	<li>函数表达式 var foo=function(){}</li>
<li>Function对象 var foo=new Function</li>	
</ol>
而函数声明和函数表达式是有差别的,先看两个例子：<pre><code>函数表达式：var example = function(){
return 1;
}
example();//1

var example = function(){
return 2;
}
example();//2</code></pre>
<pre><code>函数声明：function example(){
return 1;
}
example();//1

function example(){
return 2;
}
example();//2</code></pre>
<p>在采用函数声明创建同名函数时，后创建的函数会覆盖先创建的函数。这种差别是由于JavaScript解释引擎的工作机制所导致的。JavaScript解释引擎在执行任何函数调用之前，首先会在全局作用域中注册以函数声明创建的函数，然后再依次执行函数调用。由于注册函数时，后定义的函数重写了先定义的函数，因此无论调用语句位于何处，执行的都是后定义的函数。<br/>相反，对于函数表达式创建的函数，JavaScript解释引擎会像对待任何声明的变量一样，等到执行调用该变量的代码时才会对变量求值。由于JavaScript代码是从上到下顺序执行的，因此当执行第一个example()调用时，example函数的代码就是首先定义代码；而当执行第二个example()调用时，example函数的代码又变成了后来定义的代码。</p>

<h4><a name="method">作为对象方法</a></h4>
<p>JavaScript在解析代码时，会为声明或定义的函数指定调用对象。所谓调用对象，就是函数的执行环境。如果函数体内有以关键字this声明的变量，则this引用的就是调用对象。事实上，在普通的函数中，也存在调用对象，只不过这个调用对象是默认的全局window对象而已。例如上面的例子相当于：</p>
<pre><code>var Add= window.Add(26,26); // Add= 52</code></pre>
<p>这说明，默认情况下，在全局作用域中定义或声明的函数的调用对象就是window。
在面向对象编程中，通常将作为对象成员的函数称为方法。
</p>
<pre><code>var people={}
people.name="lefter";
people.age="24 years old"
people.intro=function(){
    alert(this.name+" is "+this.age)
}
people.intro();//lefter is 24years old

var animal ={}
animal .name='huahua'
animal .age='1years old';
animal .wangwang=people.intro;//对象可以借用其他对象的方法
animal .wangwang();//huahua is 1years
</code></pre>
<p>使用函数对象的call和apply方法，还可以动态指定函数或方法的调用对象
<br/><strong>call 方法</strong>:调用一个对象的一个方法，以另一个对象替换当前对象(其实就是更改对象的内部指针，即改变对象的this指向的内容)
<br/>
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数，那么 Global 对象被用作 thisObj。 
</p>
<p><strong>apply方法</strong>apply方法的第一个参数也是要传入给当前对象的对象，即函数内部的this。后面的参数都是传递给当前对象的参数。<br/>
对于apply和call两者在作用上是相同的，但两者在参数上有区别的。对于第一个参数意义都一样，但对第二个参数：apply传入的是一个参数数组，也就是将多个参数组合成为一个数组传入，而call则作为call的参数传入（从第二个参数开始）。<br/>
如 func.call(func1,var1,var2,var3)对应的apply写法为：func.apply(func1, [var1,var2,var3])同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入</p>
因此上面可以写为：<pre><code>animal.wangwang.call(people);
或者：animal.wangwang.apply(people); </code></pre>
<h4><a name="constructor">作为构造函数</a></h4>
<pre><code>function Man(name,age){
this.name= name;
this.age = age;
}
//然后可以new一个实例
var lefter=new Man("lefter",24);</code></pre>
<p>
创建lefter的对象的过程如下：首先，new运算符创建一个空对象({})，然后以这个空对象为调用对象调用函数Man，为这个空对象添加两个属性name和age，接着，再将这个空对象的默认constructor属性修改为构造函数的名称（即Man；空对象创建时默认的constructor属性值是Object），并且将空对象的__proto__属性设置为指向Man.prototype——这就是所谓的对象初始化。最后，返回初始化完毕的对象。这里将返回的新对象赋值给了变量lefter,除了new外还可以用这样的方式来创建。
</p>
<pre><code>var lefter = {};
Man.call(lefter,"lefter",24);</code></pre>
<p>区别是后者新创建的lefter对象失去了通过Man.prototype属性继承其他对象的能力。只要与前面采用new运算符调用构造函数创建对象的过程对比一下，就会发现，new运算符在初始化新对象期间，除了为新对象添加显式声明的属性外，还会对新对象进行了一番“暗箱操作”——即将新对象的constructor属性重写为Man，将新对象的__proto__属性设置为指向Man.prototype。虽然手工“初始化对象”也可以将dog.constructor重写为Man，但根据ECMA262规范，对象的__proto__属性对开发人员是只读的，对它的设置只能在通过new运算符创建对象时由JavaScript解释引擎替我们完成。
<br/>JavaScript是基于原型继承的，如果不能正确设置对象的__proto__属性，那么就意味着默认的继承机制会失效：
</p><pre><code>Man.prototype.say="hellow";
lefter.say;//undefine</code></pre>]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/javascript-function/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>充分利用javascript参数对象</title>
		<link>http://lefter.net/blog/making-full-use-of-the-arguments-object/</link>
		<comments>http://lefter.net/blog/making-full-use-of-the-arguments-object/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 10:29:23 +0000</pubDate>
		<dc:creator>lujo</dc:creator>
				<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://lefter.net/blog/?p=780</guid>
		<description><![CDATA[ 在javascript中，参数是传递给函数的变量,可以理解为一个自动售货机，你投入什么面值的硬币就给出什么样的商品。硬币就是arguments,一下是一般的使用参数的方法。

(function (str1, str2) {
    ale... ]]></description>
			<content:encoded><![CDATA[ 在javascript中，参数是传递给函数的变量,可以理解为一个自动售货机，你投入什么面值的硬币就给出什么样的商品。硬币就是arguments,一下是一般的使用参数的方法。
<pre>
<code>(function (str1, str2) {
    alert( str1 + str2);
})('left', 'er');
// returns 'lefter';
</code></pre>
但是这样在有些时候访问参数并不是很方便，因此javascript提供了Arguments对象。
<pre>
<code>(function  () {
    alert(arguments[0] + arguments[1];)
})('left','er');
// returns 'lefter'
</code></pre>
在我们不确定有多少参数的时候更能体现Arguments对象的好处。
<pre>
<code>function concatenate () {
    var result = '' ";
    for(var i=0; i &lt;arguments.length; ++i){
        result += arguments[i];
    }
    return result;
}
concatenate('lefter', 'crockford', 'has', 'a', 'posse');
// returns 'leftercrocfordhasaposse'
</code></pre>
javascript提供了两个方法call和apply，做为每一个function的属性,提供了很强的灵活性，看下面两个例子
<pre>
<code>function concatenate () {
    return Array.prototype.slice.call(arguments).join('');
}
concatenate('douglas', 'crockford', 'has', 'a', 'posse');
// returns 'douglascrocfordhasaposse'
</code></pre>
<pre><code>function concatenate (separator) {
    return Array.prototype.slice.call(arguments, 1).join(separator);
}
concatenate(' ', 'lefter', 'crockford', 'has', 'a', 'posse');
// returns 'lefter crockford has a posse'
</code></pre>

]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/making-full-use-of-the-arguments-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>自动改变CSS，JS版本</title>
		<link>http://lefter.net/blog/automatically-version-your-css-and-javascript-files/</link>
		<comments>http://lefter.net/blog/automatically-version-your-css-and-javascript-files/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 03:35:36 +0000</pubDate>
		<dc:creator>lujo</dc:creator>
				<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[程序相关]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://lefter.net/blog/?p=759</guid>
		<description><![CDATA[在雅虎工程师，史蒂夫Souders 的高性能网站建设中，有很多条关于网站性能优化的建议,其中第3条建议您使用树立了一个Expires头的静态文件（图片， CSS和JavaScript ），实施Expires头很简单，在您... ]]></description>
			<content:encoded><![CDATA[在雅虎工程师，史蒂夫Souders 的<a href="http://oreilly.com/catalog/9780596529307/">高性能网站建设</a>中，有很多条关于网站性能优化的<a href="http://developer.yahoo.com/performance/rules.html">建议</a>,其中<a href="http://developer.yahoo.com/performance/rules.html#expires">第3条建议</a>您使用树立了一个Expires头的静态文件（图片， CSS和JavaScript ），实施Expires头很简单，在您的<a href="http://www.freewebmasterhelp.com/tutorials/htaccess/1" title="Apache非常强大的分布式配置文件">.htaccess</a>的文件，您可以使用下面的代码
<pre><code>#Far Future Expires Header
&lt;FilesMatch "\.(gif|png|jpg|js|css|swf)$"&gt;
    ExpiresActive On
    ExpiresDefault "access plus 10 years"
&lt;/FilesMatch&gt;
</code>
</pre>
作者指出：<blockquote>Keep in mind, if you use a far future Expires header you have to change the component’s filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component’s filename, for example, yahoo_2.0.6.js.</blockquote>
要生成像yahoo_2.0.6.js可以按照下面的方法：
<p>第一步，建立一些可规则重写的存储模块，一边存储文件的版本号，因此还是在.htaccess的文件中加入下面的代码</P><pre><code>#Rules for Versioned Static Files
RewriteRule ^(scripts|css)/(.+)\.(.+)\.(js|css)$ $1/$2.$4 [L]
</code></pre>
<p>然后写一个PHP函数来检查文件的最后修改日期，然后将服务器的修改时间作为版本号</p>
<pre><code>&lt;?php 
function autoVer($url){$path = pathinfo($url); 
$ver = '.'.filemtime($_SERVER['DOCUMENT_ROOT'].$url).'.';
echo $path['dirname'].'/'.str_replace('.', $ver, $path['basename']); } 
?&gt; 
</code></pre>
然后我们可以将这个函数包含到页面中
<pre><code>include($_SERVER['DOCUMENT_ROOT'].'/path/to/autoVer.php'); 
&lt;link rel="stylesheet" href="&lt;?php autoVer('/css/structure.css'); ?&gt;" 
type="text/css" /&gt; 
&lt;script type="text/javascript" src="&lt;?php autoVer('/scripts/prototype.js'); ?&gt;"&gt;
&lt;/script&gt; :include($_SERVER['DOCUMENT_ROOT'].'/path/to/autoVer.php'); 
&lt;link rel="stylesheet" href="&lt;?php autoVer('/css/structure.css'); ?&gt;"
type="text/css" /&gt;
&lt;script type="text/javascript" src="&lt;?php autoVer('/scripts/prototype.js'); ?&gt;"&gt;
&lt;/script&gt; 
</code></pre>
然后经过解析之后在页面文件看到的HTML代码将会是
<pre><code>&lt;script type="text/javascript" src="/prototype.197993206.js">&lt;/script&gt; 
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/automatically-version-your-css-and-javascript-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Anonymous function</title>
		<link>http://lefter.net/blog/anonymous-function/</link>
		<comments>http://lefter.net/blog/anonymous-function/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 05:56:37 +0000</pubDate>
		<dc:creator>lujo</dc:creator>
				<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://lefter.net/blog/?p=540</guid>
		<description><![CDATA[定义一个函数常见的三种格式

函数关键字(function)语句：
function add(a,b){alert(a+b);}

函数字面量(Function Literals)：
var add= function(a,b){alert(a+b);}

Function()构造函数：
var add= new Function('a','b','alert(a+b);')
... ]]></description>
			<content:encoded><![CDATA[<p>定义一个函数常见的三种格式</p>
<ol>
<li><strong>函数关键字(function)语句</strong>：
<pre><code>function add(a,b){alert(a+b);}</code></pre>
</li>
<li><strong>函数字面量(Function Literals)</strong>：
<pre><code>var add= function(a,b){alert(a+b);}</code></pre>
</li>
<li><strong>Function()构造函数</strong>：
<pre><code>var add= new Function('a','b','alert(a+b);')</code></pre>
</li>
</ol>
<p>一个匿名函数就是一个没有名字的函数。你可以认为他们是一次性函数。当你只需要用一次某个函数式，他们就特别有用。通过使用匿名函数，没有必要把函数一直放在内存中，所以使用匿名函数更加有效率。</p>
<h3><a href="http://www.hedgerwow.com/360/dhtml/js-anonymous-function-patterns.html">Code patterns for anonymous function（代码模式）</a></h3>
<pre><code>function(){  alert(1);}();
</code></pre>
<p><strong>错误模式</strong>：其无法工作，浏览器会报语法错。</p>
<ol>
<li><strong>函数字面量</strong>：首先声明一个函数对象，然后执行它。
<pre><code>(function(){
  alert(1);
} ) ( );</code></pre>
</li>
<li><strong>优先表达式</strong>：由于Javascript执行表达式是从圆括号里面到外面，所以可以用圆括号强制执行声明的函数。如果你写了括号，那么在括号中的代码就会被先计算。在计算之后，括号所在的地方就会有一个值。
<pre><code>( function(){
  alert(2);
} ( ) );</code></pre>
</li>
<li><strong>Void操作符</strong>：用void操作符去执行一个没有用圆括号包围的一个单独操作数。
<pre><code>void function(){
  alert(3);
}()</code></pre>
</li>
<li><strong>!操作符</strong>：用！操作符去执行一个没有用圆括号包围的一个单独操作数。
<pre><code>!function(){
  alert(4);
}()</code></pre>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/anonymous-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>程序运行机制</title>
		<link>http://lefter.net/blog/scope/</link>
		<comments>http://lefter.net/blog/scope/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 06:23:52 +0000</pubDate>
		<dc:creator>lujo</dc:creator>
				<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[程序相关]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://lefter.net/blog/?p=491</guid>
		<description><![CDATA[先看下面两个例子：试试看将弹出什么消息？
var a = 1;
function foo(a) {
     alert(a);
      var a = 2;
}
foo(3);
var a = "right";
(function() {
    alert(a);
    var a = "wrong";
})();

来自《编译原理》：对于传统编译型... ]]></description>
			<content:encoded><![CDATA[<p>先看下面两个例子：试试看将弹出什么消息？</p>
<pre><code>var a = 1;
function foo(a) {
     alert(a);
      var a = 2;
}
foo(3);</code></pre>
<pre><code>var a = "right";
(function() {
    alert(a);
    var a = "wrong";
})();
</code></pre>
<blockquote><p>来自《编译原理》：对于传统编译型语言来说，编译步骤分为：词法分析、语法分析、语义检查、代码优化和字节生成。<br />
但对于解释型语言来说，通过<a href="http://en.wikipedia.org/wiki/Lexical_analysis">词法分析</a>和语法分析得到语法树后，就可以开始解释执行了。</p></blockquote>
<p>
第二个函数输出结果是undefined, 这种现象被称成“预解析”：JavaScript引擎会优先解析var变量和function定义。在预解析完成后，才会执行代码。如果一个文档流中包含多个script代码段运行顺序是：<br />
<strong>step1.</strong> 读入第一个代码段<br />
<strong>step2.</strong> 做语法分析，有错则报语法错误（比如括号不匹配等），并跳转到step5<br />
<strong>step3.</strong>对var变量和function定义做“预解析”（永远不会报错的，因为只解析正确的声明,在step2的语法分析阶段完成，并存储在语法树中。当执行到函数实例时，会将varDelcs和funcDecls从语法树中复制到执行环境的scriptObject上）<br />
<strong>step4.</strong> 执行代码段，有错则报错（比如变量未定义,未定义变量意味着在scriptObject的变量表中找不到，JS引擎会沿着scriptObject的upvalue往上寻找，如果都没找到，对于写操作i = 1; 最后就会等价为 window.i = 1; 给window对象新增了一个属性。对于读操作，如果一直追溯到全局执行环境的scriptObject上都找不到，就会产生运行期错误）<br />
<strong>step5.</strong> 如果还有下一个代码段，则读入下一个代码段，重复step2<br />
<strong>step6.</strong> 结束<br />
通过编译，JavaScript代码已经翻译成了语法树，然后会立刻按照语法树执行。进一步的执行过程，需要理解JavaScript的作用域机制，JavaScript采用的是词法作用域（lexcical scope）。通俗地讲，就是JavaScript变量的作用域是在定义时决定而不是执行时决定，也就是说词法作用域取决于源码，编译器通过静态分析就能确定，因此词法作用域也叫做静态作用域（static scope）。但需要注意，with和eval的语义无法仅通过静态技术实现，实际上，只能说JS的作用域机制非常接近lexical scope.</p>
]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/scope/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>White space around images and objects</title>
		<link>http://lefter.net/blog/hspace/</link>
		<comments>http://lefter.net/blog/hspace/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 06:09:05 +0000</pubDate>
		<dc:creator>lujo</dc:creator>
				<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://ilujo.cn/?p=428</guid>
		<description><![CDATA[以前给图片和文字之间加间隙的方法使用的MARGIN或者PADDING值！今天无意中发现了img标签里面有一个专门的属性hspace&#038;vspace可设置或返回图片(或者OBJECT)的水平间距,可以配合align使用
The vspace an... ]]></description>
			<content:encoded><![CDATA[<p>以前给图片和文字之间加间隙的方法使用的MARGIN或者PADDING值！今天无意中发现了img标签里面有一个专门的属性hspace&#038;vspace可设置或返回图片(或者OBJECT)的水平间距,可以配合align使用<br />
<blockquote><p>The vspace and hspace attributes specify the amount of white space to be inserted to the left and right (hspace) and above and below (vspace) an IMG, APPLET, OBJECT. The default value for these attributes is not specified, but is generally a small, non-zero length. Both attributes take values of type length.</p></blockquote>
<p>这样做更有语意，<a href="http://www.w3.org/TR/WD-html40-970917/struct/objects.html#adef-vspace">w3c</a>也是支持的<strong>语法格式如下</strong><br/>imageObject.hspace=pixels</p>
<pre><code>
function setSpace(){
  document.getElementById("el").hspace="50"
  document.getElementById("el").vspace="50"
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/hspace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>建立优美的面向对象JS编程风格</title>
		<link>http://lefter.net/blog/oo-js-style/</link>
		<comments>http://lefter.net/blog/oo-js-style/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 16:03:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[体验&交互&平面&策划]]></category>
		<category><![CDATA[前端开发&架构]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://ilujo.cn/?p=32</guid>
		<description><![CDATA[由于js语言自身语法的灵活性，使得在js程序中出现了各种各样的代码风格，但也正因为如此，导致了代码的可读性和可维护性大大降低，特别随着项目的不断更新，js代码的不断增多，到后期... ]]></description>
			<content:encoded><![CDATA[<p>由于js语言自身语法的灵活性，使得在js程序中出现了各种各样的代码风格，但也正因为如此，导致了代码的可读性和可维护性大大降低，特别随着项目的不断更新，js代码的不断增多，到后期维护时甚至连自己写的代码都不知所以然了，因此确定一种好的代码风格是很有必要的。近两年随着ajax的兴起，js变得越来越受“重用”，js开始在web开发中中充当着非常重要的角色，因此也开始遇到了各种各样的问题。于是很多牛人们就提出了js的面向对象编程方法。</p>
<p>使用面向对象的编程思想实现js代码其实也并不难，实现方法也又多种，比如prototype原型，new object()等方法。前面的每个方法都有其自己的优缺点，但都存在一个问题，那就是对于js变量作用域的控制。如果不能很好控制js变量作用域，就可能导致对象内部变量被外部肆意修改，从而导致程序被破坏，不便于程序的维护，对象的封装特性和程序健壮性都大打折扣。被由于js本身没有很好的对变量范围的定义（public/private等限定符），因此在js的面向对象编程中也就遇到了变量的控制问题，特别是对于对象内部的公有变量在prototype原型方法中都很难实现。</p>
]]></content:encoded>
			<wfw:commentRss>http://lefter.net/blog/oo-js-style/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
