﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-迷失北京</title><link>http://www.blogjava.net/focusJ/</link><description /><language>zh-cn</language><lastBuildDate>Sat, 11 Apr 2026 10:56:06 GMT</lastBuildDate><pubDate>Sat, 11 Apr 2026 10:56:06 GMT</pubDate><ttl>60</ttl><item><title>浅谈java异常[Exception]</title><link>http://www.blogjava.net/focusJ/archive/2011/12/26/367223.html</link><dc:creator>王康</dc:creator><author>王康</author><pubDate>Mon, 26 Dec 2011 00:57:00 GMT</pubDate><guid>http://www.blogjava.net/focusJ/archive/2011/12/26/367223.html</guid><wfw:comment>http://www.blogjava.net/focusJ/comments/367223.html</wfw:comment><comments>http://www.blogjava.net/focusJ/archive/2011/12/26/367223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/focusJ/comments/commentRss/367223.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/focusJ/services/trackbacks/367223.html</trackback:ping><description><![CDATA[<p class="p0">一．&nbsp;异常的定义</p>
<p class="p0">在《<span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">编程思想》中这样定义&nbsp;异常：阻止当前方法或作用域继续执行的</span>问题。虽然<span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">中有异常处理机制，但是要明确一点，决不应该用</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">正常</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">的态度来看待异常。绝对一点说异常就是某种意义上的错误，就是问题，它可能会导致程序失败。之所以</span><span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">要提出异常处理机制，就是要告诉开发人员，你的程序出现了不正常的情况，请注意。</span></p>
<p class="p0">记得当初学习<span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">的时候，异常总是搞不太清楚，不知道这个异常是什么意思，为什么会有这个机制？但是随着知识的积累逐渐也对异常有一点感觉了。举一个例子来说明一下异常的用途。</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public class Calculator {
	public int devide(int num1, int num2) {
		//判断除数是否为0
		if(num2 == 0) {
			throw new IllegalArgumentException("除数不能为零");
		}
		
		return num1/num2;
	}
}
</pre>
</div>
<p class="p0">&nbsp;</p>
<p>看一下这个类中关于除运算的方法，如果你是新手你可能会直接返回计算结果，根本不去考虑什么参数是否正确，是否合法（当然可以原谅，谁都是这样过来的）。但是我们应尽可能的考虑周全，把可能导致程序失败的<span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">苗头</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">扼杀在摇篮中，所以进行参数的合法性检查就很有必要了。其中执行参数检查抛出来的那个参数非法异常，这就属于这个方法的不正常情况。正常情况下我们会正确的使用计算器，但是不排除粗心大意把除数赋值为</span><span style="font-family: 'Courier New';">0</span><span style="font-family: 宋体;">。如果你之前没有考虑到这种情况，并且恰巧用户数学基础不好，那么你完了。但是如果你之前考虑到了这种情况，那么很显然错误已在你的掌控之中。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">二．&nbsp;异常扫盲行动</p>
<p class="p0">&nbsp;</p>
<p class="p0">今天和别人聊天时看到一个笑话：世界上最真情的相依，是你在<span style="font-family: Tahoma;">try</span><span style="font-family: 宋体;">我在</span><span style="font-family: Tahoma;">catch</span><span style="font-family: 宋体;">。无论你发神马脾气，我都默默承受，静静处理。</span>&nbsp;大多数新手对<span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">异常的感觉就是：</span><span style="font-family: 'Courier New';">try...catch...</span><span style="font-family: 宋体;">。没错，这是用的最多的，也是最实用的。我的感觉就是：</span><span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">异常是从</span><span style="font-family: 'Courier New';">"try...catch..."</span><span style="font-family: 宋体;">走来。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">首先来熟悉一下<span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">的异常体系：</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">Throwable&nbsp;<span style="font-family: 宋体;">类是&nbsp;</span><span style="font-family: 'Courier New';">Java&nbsp;</span><span style="font-family: 宋体;">语言中所有错误或异常的超类</span>（这就是一切皆可抛的东西）。它有两个子类：<span style="font-family: 'Courier New';">Error</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Courier New';">Exception</span><span style="font-family: 宋体;">。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">Error<span style="font-family: 宋体;">：</span>用于指示合理的应用程序不应该试图捕获的严重问题。这种情况是很大的问题，大到你不能处理了，所以听之任之就行了，你不用管它。比如说VirtualMachineError：当&nbsp;<span style="font-family: 'Courier New';">Java&nbsp;</span><span style="font-family: 宋体;">虚拟机崩溃或用尽了它继续操作所需的资源时，抛出该错误。</span>好吧，就算这个异常的存在了，那么应该何时，如何处理它呢？？交给<span style="font-family: 'Courier New';">JVM</span><span style="font-family: 宋体;">吧，没有比它更专业的了。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">Exception<span style="font-family: 宋体;">：</span>它指出了合理的应用程序想要捕获的条件。Exception<span style="font-family: 宋体;">又分为两类：一种是</span><span style="font-family: 'Courier New';">CheckedException</span><span style="font-family: 宋体;">，一种是</span><span style="font-family: 'Courier New';">UncheckedException</span><span style="font-family: 宋体;">。这两种</span><span style="font-family: 'Courier New';">Exception</span><span style="font-family: 宋体;">的区别主要是</span><span style="font-family: 'Courier New';">CheckedException</span><span style="font-family: 宋体;">需要用</span><span style="font-family: 'Courier New';">try...catch...</span><span style="font-family: 宋体;">显示的捕获，而</span><span style="font-family: 'Courier New';">UncheckedException</span><span style="font-family: 宋体;">不需要捕获。通常</span><span style="font-family: 'Courier New';">UncheckedException</span><span style="font-family: 宋体;">又叫做</span><span style="font-family: 'Courier New';">RuntimeException</span><span style="font-family: 宋体;">。《</span><span style="font-family: 'Courier New';">effective&nbsp;java</span><span style="font-family: 宋体;">》指出：对于可恢复的条件使用被检查的异常（</span><span style="font-family: 'Courier New';">CheckedException</span><span style="font-family: 宋体;">），对于程序错误（言外之意不可恢复，大错已经酿成）使用运行时异常（</span><span style="font-family: 'Courier New';">RuntimeException</span><span style="font-family: 宋体;">）。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">我们常见的<span style="font-family: 'Courier New';">RuntimeExcepiton</span><span style="font-family: 宋体;">有</span>IllegalArgumentException、<span style="font-family: 'Courier New';">IllegalStateException</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier New';">NullPointerException</span><span style="font-family: 宋体;">、</span>IndexOutOfBoundsException等等。对于那些<span style="font-family: 'Courier New';">CheckedException</span><span style="font-family: 宋体;">就不胜枚举了，我们在编写程序过程中</span><span style="font-family: 'Courier New';">try...catch...</span><span style="font-family: 宋体;">捕捉的异常都是</span><span style="font-family: 'Courier New';">CheckedException</span><span style="font-family: 宋体;">。</span><span style="font-family: 'Courier New';">io</span><span style="font-family: 宋体;">包中的</span><span style="font-family: 'Courier New';">IOException</span><span style="font-family: 宋体;">及其子类，这些都是</span><span style="font-family: 'Courier New';">CheckedException</span><span style="font-family: 宋体;">。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">三．&nbsp;异常的使用</p>
<p class="p0">&nbsp;</p>
<p class="p0">在异常的使用这一部分主要是演示代码，都是我们平常写代码的过程中会遇到的（当然只是一小部分），抛砖引玉吗！</p>
<p class="p0">&nbsp;</p>
<p class="p0">例<span style="font-family: 'Courier New';">1.&nbsp;</span><span style="font-family: 宋体;">这个例子主要通过两个方法对比来演示一下有了异常以后代码的执行流程。&nbsp;</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public static void testException1() {
		int[] ints = new int[] { 1, 2, 3, 4 };
		System.out.println("异常出现前");
		try {
			System.out.println(ints[4]);
			System.out.println("我还有幸执行到吗");// 发生异常以后，后面的代码不能被执行
		} catch (IndexOutOfBoundsException e) {
			System.out.println("数组越界错误");
		}
		System.out.println("异常出现后");
	}
	/*output:
	异常出现前
	数组越界错误
	4
	异常出现后
	*/
</pre>
</div>
<p class="p0">&nbsp;</p>
<p>　　</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public static void testException2() {
		int[] ints = new int[] { 1, 2, 3, 4 };
		System.out.println("异常出现前");
		System.out.println(ints[4]);
		System.out.println("我还有幸执行到吗");// 发生异常以后，他后面的代码不能被执行
	}
</pre>
</div>
<p>　　</p>
<p class="p0">首先指出例子中的不足之处，<span style="font-family: 'Courier New';">IndexOutofBoundsException</span><span style="font-family: 宋体;">是一个非受检异常，所以不用</span><span style="font-family: 'Courier New';">try...catch...</span><span style="font-family: 宋体;">显示捕捉，但是我的目的是对同一个异常用不同的处理方式，看它会有什么不同的而结果（这里也就只能用它将就一下了）。异常出现时第一个方法只是跳出了</span><span style="font-family: 'Courier New';">try</span><span style="font-family: 宋体;">块，但是它后面的代码会照样执行的。但是第二种就不一样了直接跳出了方法，比较强硬。从第一个方法中我们看到，</span><span style="font-family: 'Courier New';">try...catch...</span><span style="font-family: 宋体;">是一种</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">事务性</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">的保障，它的目的是保证程序在异常的情况下运行完毕，同时它还会告知程序员程序中出错的详细信息（这种详细信息有时要依赖于程序员设计）。</span></p>
<p class="p0">例<span style="font-family: 'Courier New';">2.&nbsp;</span><span style="font-family: 宋体;">重新抛出异常</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public class Rethrow {
	public static void readFile(String file) throws FileNotFoundException {
		try {
			BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.err.println("不知道如何处理该异常或者根本不想处理它，但是不做处理又不合适，这是重新抛出异常交给上一级处理");
			//重新抛出异常
			throw e;
		}
	}
	
	public static void printFile(String file) {
		try {
			readFile(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		printFile("D:/file");
	}
}
</pre>
</div>
<p class="p0">&nbsp;</p>
<p>　　</p>
<p class="p0">异常的本意是好的，让我们试图修复程序，但是现实中我们修复的几率很小，我们很多时候就是用它来记录出错的信息。如果你厌倦了不停的处理异常，重新抛出异常对你来说可能是一个很好的解脱。原封不动的把这个异常抛给上一级，抛给调用这个方法的人，让他来费脑筋吧。这样看来，<span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">异常（当然指的是受检异常）又给我们平添很多麻烦，尽管它的出发点是好的。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">例<span style="font-family: 'Courier New';">3.&nbsp;</span><span style="font-family: 宋体;">异常链的使用及异常丢失</span></p>
<p class="p0">定义三个异常类：<span style="font-family: 'Courier New';">ExceptionA,ExceptionB,ExceptionC</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public class ExceptionA extends Exception {
	public ExceptionA(String str) {
		super();
	}
}

public class ExceptionB extends ExceptionA {

	public ExceptionB(String str) {
		super(str);
	}
}

public class ExceptionC extends ExceptionA {
	public ExceptionC(String str) {
		super(str);
	}
}</pre>
</div>
<p class="p0">异常丢失的情况：</p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public class NeverCaught {
	static void f() throws ExceptionB{
		throw new ExceptionB("exception b");
	}

	static void g() throws ExceptionC {
		try {
			f();
		} catch (ExceptionB e) {
			ExceptionC c = new ExceptionC("exception a");
			throw c;
		}
	}

	public static void main(String[] args) {
			try {
				g();
			} catch (ExceptionC e) {
				e.printStackTrace();
			}
	}

}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:19)
*/</pre>
</div>
<p class="p0">为什么只是打印出来了<span style="font-family: 'Courier New';">ExceptionC</span><span style="font-family: 宋体;">而没有打印出</span><span style="font-family: 'Courier New';">ExceptionB</span><span style="font-family: 宋体;">呢？这个还是自己分析一下吧！</span></p>
<p class="p0">上面的情况相当于少了一种异常，这在我们排错的过程中非常的不利。那我们遇到上面的情况应该怎么办呢？这就是异常链的用武之地：保存异常信息，在抛出另外一个异常的同时不丢失原来的异常。</p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public class NeverCaught {
	static void f() throws ExceptionB{
		throw new ExceptionB("exception b");
	}

	static void g() throws ExceptionC {
		try {
			f();
		} catch (ExceptionB e) {
			ExceptionC c = new ExceptionC("exception a");
			//异常连
			c.initCause(e);
			throw c;
		}
	}

	public static void main(String[] args) {
			try {
				g();
			} catch (ExceptionC e) {
				e.printStackTrace();
			}
	}

}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:21)
Caused by: exception.ExceptionB
at exception.NeverCaught.f(NeverCaught.java:5)
at exception.NeverCaught.g(NeverCaught.java:10)
... 1 more
*/</pre>
</div>
<p class="p0">这个异常链的特性是所有异常均具备的，因为这个<span style="font-family: 'Courier New';">initCause()</span><span style="font-family: 宋体;">方法是从</span><span style="font-family: 'Courier New';">Throwable</span><span style="font-family: 宋体;">继承的。</span></p>
<p class="p0">例<span style="font-family: 'Courier New';">4.&nbsp;</span><span style="font-family: 宋体;">清理工作</span></p>
<p class="p0">清理工作对于我们来说是必不可少的，因为如果一些消耗资源的操作，比如<span style="font-family: 'Courier New';">IO,JDBC</span><span style="font-family: 宋体;">。如果我们用完以后没有及时正确的关闭，那后果会很严重，这意味着内存泄露。异常的出现要求我们必须设计一种机制不论什么情况下，资源都能及时正确的清理。这就是</span><span style="font-family: 'Courier New';">finally</span><span style="font-family: 宋体;">。</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public void readFile(String file) {
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(file)));
			// do some other work
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}</pre>
</div>
<p class="p0">例子非常的简单，是一个读取文件的例子。这样的例子在<span style="font-family: 'Courier New';">JDBC</span><span style="font-family: 宋体;">操作中也非常的常见。（所以，我觉得对于资源的及时正确清理是一个程序员的基本素质之一。）</span></p>
<p class="p0">Try...finally<span style="font-family: 宋体;">结构也是保证资源正确关闭的一个手段。如果你不清楚代码执行过程中会发生什么异常情况会导致资源不能得到清理，那么你就用</span><span style="font-family: 'Courier New';">try</span><span style="font-family: 宋体;">对这段</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">可疑</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">代码进行包装，然后在</span><span style="font-family: 'Courier New';">finally</span><span style="font-family: 宋体;">中进行资源的清理。举一个例子：</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public void readFile() {
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(
					new FileInputStream("file")));
			// do some other work
		
			//close reader
			reader.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
</pre>
</div>
<p class="p0">&nbsp;</p>
<p class="p0">我们注意一下这个方法和上一个方法的区别，下一个人可能习惯更好一点，及早的关闭<span style="font-family: 'Courier New';">reader</span><span style="font-family: 宋体;">。但是往往事与愿违，因为在</span><span style="font-family: 'Courier New';">reader.close()</span><span style="font-family: 宋体;">以前异常随时可能发生，这样的代码结构不能预防任何异常的出现。因为程序会在异常出现的地方跳出，后面的代码不能执行（这在上面应经用实例证明过）。这时我们就可以用</span><span style="font-family: 'Courier New';">try...finally</span><span style="font-family: 宋体;">来改造：</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public void readFile() {
		BufferedReader reader = null;
		try {
			try {
				reader = new BufferedReader(new InputStreamReader(
						new FileInputStream("file")));
				// do some other work

				// close reader
			} finally {
				reader.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}</pre>
</div>
<p class="p0">及早的关闭资源是一种良好的行为，因为时间越长你忘记关闭的可能性越大。这样在配合上<span style="font-family: 'Courier New';">try...finally</span><span style="font-family: 宋体;">就保证万无一失了</span><span style="font-family: 'Courier New';">(</span><span style="font-family: 宋体;">不要嫌麻烦，</span><span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">就是这么中规中矩</span><span style="font-family: 'Courier New';">)</span><span style="font-family: 宋体;">。</span></p>
<p class="p0">再说一种情况，假如我想在构造方法中打开一个文件或者创建一个<span style="font-family: 'Courier New';">JDBC</span><span style="font-family: 宋体;">连接，因为我们要在其他的方法中使用这个资源，所以不能在构造方法中及早的将这个资源关闭。那我们是不是就没辙了呢？答案是否定的。看一下下面的例子：</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public class ResourceInConstructor {
	BufferedReader reader = null;
	public ResourceInConstructor() {
		try {
			reader = new BufferedReader(new InputStreamReader(new FileInputStream("")));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public void readFile() {
		try {
			while(reader.readLine()!=null) {
				//do some work
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void dispose() {
		try {
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}</pre>
</div>
<p class="p0">这一部分讲的多了一点，但是异常确实是看起来容易用起来难的东西呀，<span style="font-family: 'Courier New';">java</span><span style="font-family: 宋体;">中还是有好多的东西需要深挖的。</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">四．&nbsp;异常的误用</p>
<p class="p0">对于异常的误用着实很常见，上一部分中已经列举了几个，大家仔细的看一下。下面再说两个其他的。</p>
<p class="p0">例<span style="font-family: 'Courier New';">1.&nbsp;</span><span style="font-family: 宋体;">用一个</span><span style="font-family: 'Courier New';">Exception</span><span style="font-family: 宋体;">来捕捉所有的异常，颇有</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">一夫当关万夫莫开</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">的气魄。不过这也是最傻的行为。</span></p>
<p class="p0">&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">public void readFile(String file) {
		BufferedReader reader = null;
		Connection conn = null;
		try {
			reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(file)));
			// do some other work
			
			conn = DriverManager.getConnection("");
			//...
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				reader.close();
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
</pre>
</div>
<p class="p0">&nbsp;</p>
<p>　　</p>
<div class="Section0">
<p class="p0">从异常角度来说这样严格的程序确实是万无一失，所有的异常都能捕获。但是站在编程人员的角度，万一这个程序出错了我们该如何分辨是到底是那引起的呢，<span style="font-family: 'Courier New';">IO</span><span style="font-family: 宋体;">还是</span><span style="font-family: 'Courier New';">JDBC...</span><span style="font-family: 宋体;">所以，这种写法很值得当做一个反例。大家不要以为这种做法很幼稚，傻子才会做。我在公司实习时确实看见了类似的情况：只不过是人家没有用</span><span style="font-family: 'Courier New';">Exception</span><span style="font-family: 宋体;">而是用了</span><span style="font-family: 'Courier New';">Throwable</span><span style="font-family: 宋体;">。</span></p>
<p class="p0">例<span style="font-family: 'Courier New';">2.&nbsp;</span><span style="font-family: 宋体;">这里就不举例子了，上面的程序都是反例。异常是程序处理意外情况的机制，当程序发生意外时，我们需要尽可能多的得到意外的信息，包括发生的位置，描述，原因等等。这些都是我们解决问题的线索。但是上面的例子都只是简单的</span><span style="font-family: 'Courier New';">printStackTrace()</span><span style="font-family: 宋体;">。如果我们自己写代码，就要尽可能多的对这个异常进行描述。比如说为什么会出现这个异常，什么情况下会发生这个异常。如果传入方法的参数不正确，告知什么样的参数是合法的参数，或者给出一个</span><span style="font-family: 'Courier New';">sample</span><span style="font-family: 宋体;">。</span></p>
<p class="p0">例<span style="font-family: 'Courier New';">3.&nbsp;</span><span style="font-family: 宋体;">将</span><span style="font-family: 'Courier New';">try&nbsp;block</span><span style="font-family: 宋体;">写的简短，不要所有的东西都扔在这里，我们尽可能的分析出到底哪几行程序可能出现异常，只是对可能出现异常的代码进行</span><span style="font-family: 'Courier New';">try</span><span style="font-family: 宋体;">。尽量为每一个异常写一个</span><span style="font-family: 'Courier New';">try...catch</span><span style="font-family: 宋体;">，避免异常丢失。在</span><span style="font-family: 'Courier New';">IO</span><span style="font-family: 宋体;">操作中，一个</span><span style="font-family: 'Courier New';">IOException</span><span style="font-family: 宋体;">也具有</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">一夫当关万夫莫开</span><span style="font-family: 'Courier New';">"</span><span style="font-family: 宋体;">的气魄。</span></p>
<p class="p0">五．总结</p>
<p class="p0">总结非常简单，不要为了使用异常而使用异常。异常是程序设计的一部分，对它的设计也要考究点。</p>
</div>
<p class="p0"><span style="font-family: 宋体;"><br /></span></p>
<p class="p0"><span style="font-family: 'Courier New';"><br /></span></p>
<p class="p0"><span style="font-family: 宋体;"><br /></span></p>
<p class="p0"><span style="font-family: 宋体;"><br /></span></p><img src ="http://www.blogjava.net/focusJ/aggbug/367223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/focusJ/" target="_blank">王康</a> 2011-12-26 08:57 <a href="http://www.blogjava.net/focusJ/archive/2011/12/26/367223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我来说说java的NIO</title><link>http://www.blogjava.net/focusJ/archive/2011/11/03/367225.html</link><dc:creator>王康</dc:creator><author>王康</author><pubDate>Thu, 03 Nov 2011 02:10:00 GMT</pubDate><guid>http://www.blogjava.net/focusJ/archive/2011/11/03/367225.html</guid><wfw:comment>http://www.blogjava.net/focusJ/comments/367225.html</wfw:comment><comments>http://www.blogjava.net/focusJ/archive/2011/11/03/367225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/focusJ/comments/commentRss/367225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/focusJ/services/trackbacks/367225.html</trackback:ping><description><![CDATA[<p class="p0">　　Java&nbsp;NIO<span style="font-family: 宋体;">的出现旨在提高文件的读写速度，当</span><span style="font-family: 宋体;">然</span><span style="font-family: 'Times New Roman';">IO</span><span style="font-family: 宋体;">用</span><span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">重新实</span><span style="font-family: 宋体;">过，所以我们不用显示的调用</span><span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">也能享受这种高效的文件读写。</span></p>
<p class="p0">　　Java&nbsp;NIO<span style="font-family: 宋体;">的高效得益于其两大</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">助手</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">：</span><span style="font-family: 'Times New Roman';">Channel(</span><span style="font-family: 宋体;">管道</span><span style="font-family: 'Times New Roman';">)</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Times New Roman';">Buffer(</span><span style="font-family: 宋体;">缓冲器</span><span style="font-family: 'Times New Roman';">)</span><span style="font-family: 宋体;">。当然这两个"得力助手"的"年龄"远远比java大！力求简单易懂的把知识讲解给大家，我举一个例子来说明一下这</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">两元大将</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">是如何在</span><span style="font-family: 'Times New Roman';">java&nbsp;NIO</span><span style="font-family: 宋体;">中配合工作的。</span></p>
<p class="p0">　　中国古代有一种传统的吸烟器具<span style="font-family: 'Times New Roman';">---</span><span style="font-family: 宋体;">水烟袋。我想用这个东西来模拟一下</span><span style="font-family: 'Times New Roman';">Channel</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的工作原理。不求说的好，力求准确无误。</span></p>
<p class="p0">&nbsp;<img src="http://pic002.cnblogs.com/images/2011/303347/2011110116092663.jpg" alt="" /></p>
<p class="p0">分析一下水烟袋是如何工作的：</p>
<p><img src="http://pic002.cnblogs.com/images/2011/303347/2011110309523347.png" alt="" /></p>
<p class="p0">　　第一步，准备工作，准备好上等烟丝；第二步，将<span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">水斗</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">中装入适量的水，烟仓中装满烟丝并插入水斗中，然后再将烟管插入水斗中；第三步，点燃烟丝并吸气。香烟从烟仓产生，经过水的过滤进入水上的空闲区。第四步，享受吸烟的快感</span><span style="font-family: 'Times New Roman';">.....</span><span style="font-family: 宋体;">从这个例子中我们提取出主要对象</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">烟</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">，来分析一下它的运动轨迹。烟仓把烟生产出来，经过水的过滤飘到水上面的空闲区域，然后通过烟管进入人的体内。</span></p>
<p class="p0">　　如果上面的过程大家理解了，明白了，那么<span style="font-family: 'Times New Roman';">java&nbsp;NIO</span><span style="font-family: 宋体;">你已经了解了</span><span style="font-family: 'Times New Roman';">50%</span><span style="font-family: 宋体;">，至少你已经知道它的工作原理了。因为用</span><span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">处理的数据和用水烟袋中吸烟很相似。我们分析一下</span><span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">的工作原理，非常简单。</span></p>
<p class="p0">　　当然和吸烟一样我们首先必须有要用<span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">来处理需求的欲望（这好比你想要吸烟了），比方说我想要将</span><span style="font-family: 'Times New Roman';">C</span><span style="font-family: 宋体;">盘下面的</span><span style="font-family: 'Times New Roman';">wk.txt</span><span style="font-family: 宋体;">文件进行备份，备份文件的名称为</span><span style="font-family: 'Times New Roman';">wk-bak.txt</span><span style="font-family: 宋体;">。类比刚刚吸烟的那个过程：</span></p>
<p class="p0">&nbsp;</p>
<p class="p0">　　步骤一：准备工作，确定文件的位置，并将程序不可直接操作的文件转换成字符流的形式（这一步和上边吸烟实例的第一步没有什么差别，只是进行一些简单的准备工作）。</p>
<div class="cnblogs_code">
<pre>String inFile = "C:\\wk.txt";<br />String outFile = "C:\\wk-bak.txt";<br />FileInputStream inf = <span style="color: #0000ff;">new</span> FileInputStream(inFile);<br />FileOutputStream outf = <span style="color: #0000ff;">new</span> FileOutputStream(outFile);<br />ByteBuffer buffer = ByteBuffer.allocate(1024);</pre>
</div>
<p class="p0">　　步骤二：创建文件输入管道，和文件输出管道。（这一步与上边吸烟的第二部稍有差别，因为<span style="font-family: 'Times New Roman';">Channel</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">是在读写的时候才发生的</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">连接</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">动作）</span></p>
<div class="cnblogs_code">
<pre><span style="color: #008000;">//</span><span style="color: #008000;">准备文件读取的管道--&gt;相当于烟仓和烟管</span><span style="color: #008000;"><br /></span>FileChannel inFc = inf.getChannel();<br />FileChannel outFc = outf.getChannel();<br /><br />Charset charSet = Charset.forName("utf-8");<br /><span style="color: #008000;">//</span><span style="color: #008000;">进行编码解码--&gt;相当于水斗中水的过滤作用</span><span style="color: #008000;"><br /></span>CharsetDecoder decoder = charSet.newDecoder();<br />CharsetEncoder encoder = charSet.newEncoder();　　</pre>
</div>
<p class="p0">　　步骤三：开始进行文件备份工作。</p>
<div class="cnblogs_code">
<pre>       <span style="color: #0000ff;">while</span>(<span style="color: #0000ff;">true</span>) {<br />            <span style="color: #008000;">//</span><span style="color: #008000;">准备向Buffer中写入数据--&gt;相当于点燃烟丝，完事具备只欠东风</span><span style="color: #008000;"><br /></span>            buffer.clear();<br />            <br />            <span style="color: #008000;">//</span><span style="color: #008000;">进行字符编码 --&gt;相当于水的过滤作用</span><span style="color: #008000;"><br /></span>            CharBuffer cb = decoder.decode(buffer);<br />            ByteBuffer bb = encoder.encode(cb);<br />            <br />            <span style="color: #008000;">//</span><span style="color: #008000;">数据经过编码以后暂存缓冲区--&gt;相当于经过水过滤后的烟暂停在水斗中</span><span style="color: #008000;"><br /></span>            <span style="color: #0000ff;">int</span> t = inFc.read(bb);<br />            <span style="color: #0000ff;">if</span>(t == -1) {<br />                <span style="color: #0000ff;">break</span>;<br />            }<br />            <br />            bb.flip();<br />            <br />            <span style="color: #008000;">//</span><span style="color: #008000;">将字节码写入目标文件--&gt;相当于烟已经进入到嘴里</span><span style="color: #008000;"><br /></span>            outFc.write(bb);<br />        }</pre>
</div>
<p class="p0">　　步骤四：检查文件是否备份成功。发现<span style="font-family: 'Times New Roman';">C</span><span style="font-family: 宋体;">盘下面多了一个</span><span style="font-family: 'Times New Roman';">wk-bak.txt</span><span style="font-family: 宋体;">的文件，内容与</span><span style="font-family: 'Times New Roman';">wk.txt</span><span style="font-family: 宋体;">一摸一样。接下来享受</span><span style="font-family: 'Times New Roman';">java</span><span style="font-family: 宋体;">带给你的快感</span><span style="font-family: 'Times New Roman';">....</span></p>
<p class="p0">　　上面的例子估计大家已经理解的差不多了，当然如果深究也会有一些不太妥当的地方，但是不要较真，目的是学习<span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">，并不是吸烟。如果感觉你可以了那么就请把上面的例子补充完整，运行一下，享受一下</span><span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">的威武（当然字符编码并不是必须的，只是让这个例子显得完整一点）。</span></p>
<p class="p0">　　好吧如果你理解了上面的东西，并且真正的补全了文件备份的小程序，那么就来进行稍微深入一点的学习吧。</p>
<p class="p0">　　上文我提到了举吸烟的例子是有欠妥当的，其中之一就是<span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的内部机制和</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">水斗</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">简单的过滤功能是不一样的。还有字符编码那一块也不是在</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">内部实现的东西，</span><span style="font-family: 'Times New Roman';">decoder</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Times New Roman';">encoder</span><span style="font-family: 宋体;">是针对</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的两个工具。那我们接下来分析一下</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">内部机制到底不一样在哪里呢（主要分析常用的两个方法；</span><span style="font-family: 'Times New Roman';">clear()</span><span style="font-family: 宋体;">，</span><span style="font-family: 'Times New Roman';">flip()</span><span style="font-family: 宋体;">）？</span></p>
<p class="p0">　　来吧，打开<span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的源码（摘取有用的部分）：</span></p>
<div class="cnblogs_code">
<pre><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">abstract</span> <span style="color: #0000ff;">class</span> Buffer {<br /><br />    <span style="color: #008000;">//</span><span style="color: #008000;"> Invariants: mark &lt;= position &lt;= limit &lt;= capacity</span><span style="color: #008000;"><br /></span>    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span> mark = -1;<br />    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span> position = 0;<br />    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span> limit;<br />    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span> capacity;<br /><br /> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">final</span> Buffer clear() {<br />    position = 0;<br />    limit = capacity;<br />    mark = -1;<br />    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span>;<br />    }<br />    <br /> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">final</span> Buffer flip() {<br />    limit = position;<br />    position = 0;<br />    mark = -1;<br />    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span>;<br />    }</pre>
</div>
<p class="p0">　首先我们要明确一点，所谓的缓冲器仅仅是一个<span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">多功能</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">的数组。可能在这个</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">类中没有体现，但是如果我们打开</span><span style="font-family: 'Times New Roman';">ByteBuffer</span><span style="font-family: 宋体;">的源码会有</span><span style="font-family: 'Times New Roman';">byte[]</span><span style="font-family: 宋体;">的数组，打开</span><span style="font-family: 'Times New Roman';">CharBuffer</span><span style="font-family: 宋体;">的源码会有</span><span style="font-family: 'Times New Roman';">char[]</span><span style="font-family: 宋体;">的数组。因为</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">是所有缓冲器的父类，所以他它不能预计会有多少种缓冲器，所以索性让</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">儿子</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">们自己实现去吧。</span></p>
<p class="p0">　　既然知道了缓冲器是一个<span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">多功能的数组</span><span style="font-family: 'Times New Roman';">"</span><span style="font-family: 宋体;">，那么我们用画图的形式来分析一下上面</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的源码。</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/303347/2011110309554334.png" alt="" /></p>
<p class="p0">假设我们定义了一个<span style="font-family: 'Times New Roman';">8</span><span style="font-family: 宋体;">个单位大的缓冲区，如上图（其实</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">也就是这么一个东西）。首先告诉大家那三个重要的关于缓冲区状态的的属性：</span></p>
<p class="p0">　　capacity<span style="font-family: 宋体;">：缓冲区的容量；</span></p>
<p class="p0">　　limit<span style="font-family: 宋体;">：缓冲区还有多少数据能够取出或者缓冲区还有多少容量用于存放数据；</span></p>
<p class="p0">　　position<span style="font-family: 宋体;">：相当于一个游标（</span><span style="font-family: 'Times New Roman';">cursor</span><span style="font-family: 宋体;">），记录我们从哪里开始写数据，从哪里开始读数据。</span></p>
<p class="p0">刚还说到<span style="font-family: 'Times New Roman';">flip()</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Times New Roman';">clear()</span><span style="font-family: 宋体;">是</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的两个重要的方法，因为它们两个方法决定了缓冲是否能正常的进行读写工作。</span></p>
<p class="p0">　　当我们要想从缓冲区中写数据的时候必须先执行<span style="font-family: 'Times New Roman';">flip()</span><span style="font-family: 宋体;">方法，当我们要想从缓冲区中读数据时必须先执行</span><span style="font-family: 'Times New Roman';">clear()</span><span style="font-family: 宋体;">方法。</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/303347/2011110309563390.png" alt="" /></p>
<p class="p0">第一次向<span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">中写入数据时，执行一次</span><span style="font-family: 'Times New Roman';">flip()</span><span style="font-family: 宋体;">方法以后，</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的结构变成了这样：</span><span style="font-family: 'Times New Roman';">position</span><span style="font-family: 宋体;">指向了第一个可以存取数据的</span><span style="font-family: 'Times New Roman';">0</span><span style="font-family: 宋体;">号位，</span><span style="font-family: 'Times New Roman';">limit</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Times New Roman';">capacity</span><span style="font-family: 宋体;">同时指向最高位。</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/303347/2011110309565267.png" alt="" /></p>
<p class="p0">假如第一次我们向<span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">中写入了</span><span style="font-family: 'Times New Roman';">3</span><span style="font-family: 宋体;">单位的数据，我们再次执行</span><span style="font-family: 'Times New Roman';">flip()</span><span style="font-family: 宋体;">方法则</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的结构会变成上图的所示。但是经过flip()的改造后</span><span style="font-family: 'Times New Roman';">position</span><span style="font-family: 宋体;">总是指向</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">中第一个可用的位置。那么，未执行flip()方法以前position在哪里呢？很简单，指向最后一个数据的位置。</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/303347/2011110309571397.png" alt="" /></p>
<p class="p0">当我们想要从Buffer<span style="font-family: 宋体;">中读取数据时，执行</span><span style="font-family: 'Times New Roman';">clear()</span><span style="font-family: 宋体;">方法，</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的内部结构变成了上图所示，</span><span style="font-family: 'Times New Roman';">position</span><span style="font-family: 宋体;">指向了可读数据的首位，</span><span style="font-family: 'Times New Roman';">limit</span><span style="font-family: 宋体;">指向了原来</span><span style="font-family: 'Times New Roman';">position</span><span style="font-family: 宋体;">的位置。</span></p>
<p class="p0">　　从上面的几幅图中我们看出：<span style="font-family: 'Times New Roman';">capacity</span><span style="font-family: 宋体;">代表了</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">的容量是不变的，</span><span style="font-family: 'Times New Roman';">limit</span><span style="font-family: 宋体;">与</span><span style="font-family: 'Times New Roman';">position</span><span style="font-family: 宋体;">的差总是表示</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">总可以读的数据，或者</span><span style="font-family: 'Times New Roman';">Buffer</span><span style="font-family: 宋体;">中可以写数据的容量。还有</span><span style="font-family: 'Times New Roman';">position</span><span style="font-family: 宋体;">总是小于等于</span><span style="font-family: 'Times New Roman';">limit</span><span style="font-family: 宋体;">，</span><span style="font-family: 'Times New Roman';">limit</span><span style="font-family: 宋体;">总是小于等于</span><span style="font-family: 'Times New Roman';">capacity</span><span style="font-family: 宋体;">。</span></p>
<p class="p0">　　其实到这里我们已经发现，<span style="font-family: 'Times New Roman';">NIO</span><span style="font-family: 宋体;">并不像</span><span style="font-family: 'Times New Roman';">IO</span><span style="font-family: 宋体;">那么复杂，因为</span><span style="font-family: 'Times New Roman';">IO&nbsp;</span><span style="font-family: 宋体;">中的</span><span style="font-family: 'Times New Roman';">Decorator</span><span style="font-family: 宋体;">模式和</span><span style="font-family: 'Times New Roman';">Adaptor</span><span style="font-family: 宋体;">模式确实让我们一时间摸不到头脑，但是熟悉了会感觉到</span><span style="font-family: 'Times New Roman';">IO</span><span style="font-family: 宋体;">的设计之精美。</span></p>
<p class="p0">　　NIO<span style="font-family: 宋体;">中还有一个知识点就是无阻塞的</span><span style="font-family: 'Times New Roman';">Socket</span><span style="font-family: 宋体;">编程，这里就不说了，因为比较复杂，但是如果我们真正理解了</span><span style="font-family: 'Times New Roman';">Selector</span><span style="font-family: 宋体;">这个调度者的工作，那么无阻塞的实现机制我们差不多就掌握了，复杂也就是编码上面的事了。</span></p><img src ="http://www.blogjava.net/focusJ/aggbug/367225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/focusJ/" target="_blank">王康</a> 2011-11-03 10:10 <a href="http://www.blogjava.net/focusJ/archive/2011/11/03/367225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>体验javascript之“变态”特性</title><link>http://www.blogjava.net/focusJ/archive/2011/10/06/367226.html</link><dc:creator>王康</dc:creator><author>王康</author><pubDate>Thu, 06 Oct 2011 10:02:00 GMT</pubDate><guid>http://www.blogjava.net/focusJ/archive/2011/10/06/367226.html</guid><wfw:comment>http://www.blogjava.net/focusJ/comments/367226.html</wfw:comment><comments>http://www.blogjava.net/focusJ/archive/2011/10/06/367226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/focusJ/comments/commentRss/367226.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/focusJ/services/trackbacks/367226.html</trackback:ping><description><![CDATA[<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">学习<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">断断续续也有十几天了，总结一下为自己也为别人。</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">给我的整体印象就是很&#8220;随便&#8221;，这种印象缘起于它的面向对象。当然</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的灵活性也注定了它是一个随便的语言。</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的语法特性</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;"><br /></span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">是一门动态的，弱类型的，基于原型的脚本语言。我们在一些网站上的一些漂浮效果（虽然很讨厌），图片切换效果，还有一些文本编辑器等等，这都要归功于</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">。当然</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">又是一个彻底的面向对象的语言，虽然你看到的是遍地的</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">function</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">（），但是谁有规定函数不能是对象呢。下面来看一些具体的内容。</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;"><br /></span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">基本语法</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">但凡有一点编程基础的人都会觉得<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的语法很简单，非常容易上手，但这并不代表</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">很容易学习，精通</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">也不是一件易事。</span>Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">有五种基本的数据类型：数值（</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Number</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">），字符串（</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">String</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">），布尔类型（</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">boolean</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">），</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Null</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">类型，</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Undefined</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">类型。</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">上面已经说过了<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">是一种动态的弱类型语言，那我们就来看看</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">动态体现在哪里，弱类型又体现在哪里：</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">//声明变量  
var attr1 = 1;  
var attr2 = 1.03;  
var attr3 = "hello";  
var attr4 = false; 
</pre>
</div>
<p>不用像<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">java</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">中那样，想声明什么类型的变量还必须提前定义，在</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">中，我们</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">"</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">信手拈来</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">"</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">就可以了，它是什么样它就是什么类型。口说无凭，有代码有真相。我们可以通过</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">typeof</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">关键字来测试，一试便知。</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">//声明变量  
var attr0 ;  
var attr1 = 1;  
var attr2 = 1.03;  
var attr3 = "hello";  
var attr4 = false;  
              
alert(typeof attr0); //undefined  
alert(typeof attr1); //number  
alert(typeof attr2); //number    
alert(typeof attr3); //string  
alert(typeof attr4); //boolean  
alert(typeof null); //object  
alert(typeof undefined); //undefined  
</pre>
</div>
<p>这里也还有一个知识点是关于<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">null</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">和</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">undefined</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的。</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Null</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">是一个空的对象，的的类型为</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Object</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">；</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">undefined</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">是全局对象（</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Window</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">）的一个属性，所以他的类型还是</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">undefined</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">。但是</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">undefined</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">是从</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">null</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">继承来的。</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的基本语法非常的简单，大致浏览就可以上手，所以其他的东西就不在这里说了。开始下一小节</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">...</span></p>
<p>Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">作用域</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的作用域是非常个性的，我们先来看几个例子体验一下。</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">// 作用域  
var outer = 1;  
function layer() {  
    var layer1 = 2;  
    function inner() {  
        var layer2 = 3;  
        alert(layer1);//2  
        alert(layer2);//3  
    }  
    inner();  
}  
layer();  
              
alert(outer);//1  
alert(layer1);//layer1已经被回收  
alert(layer2);//layer2已经被回收 
</pre>
</div>
<p>这个是和其他编程语言相似的地方，主要涉及全局变量和局部变量；全局变量和局部变量的作用范围既不用细说了吧。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">// sample2   
var x = "smile";  
var alerts = function() {  
    alert(x); //undefined  
    var x = "fuck";   
    alert(x); //fuck  
          
    //上面的相当于下面的代码  
    //var x ;  
    //alert(x); //undefined  
    //x = "fuck";  
    //alert(x); //fuck  
}  
</pre>
</div>
<p>Javascript没有块级作用域，函数中声明的所有变量无论是在哪里声明的，在整个函数中都有意义。估计对于用熟<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">java</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">语言的程序猿这一点是不容易接受的，反正我是这样。还有一个比较灵活的地方：未使用</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">var</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">声明的变量都是全局变量，而且全局变量都是</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Window</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">对性的属性。呵呵</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">...</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">又纠结了，适应就好了！！</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">Javascript&nbsp;<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的闭包</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;"><br /></span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">在实现深约束时，需要创建一个能显式表示引用环境的东西，并将它与相关的子程序捆绑在一起，这样捆绑起来的整体被称为闭包。单从这样一个定义上说我们并不容易理解什么是闭包。拿一个例子说事<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">...</span></p>
<p>&nbsp;</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;"> //闭包演示  
var func = function() {  
    var attr = "can read me??";  
    return function() {  
        alert(attr);  
    }  
}  
func()(); 
</pre>
</div>
<p>&nbsp;</p>
<p>本来我们已经无法在<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">func</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">函数的外面访问到</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">attr</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">属性，但是</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">"can&nbsp;read&nbsp;me??"</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">确确实实通过</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">alert</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">（）方法弹出来了，这是为什么呢，难道最后那个当做返回值的匿名函数帮我们保存了</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">attr</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">属性？当然调用此函数的方式也有一些奇怪：</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">func()()</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">。我们做进一步详细的介绍。</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">当调用一个&nbsp;Javascript&nbsp;函数时，该函数就会进入相应的执行环境。如果又调用了另外一个函数（或者递归地调用同一个函数），则又会创建一个新的执行环境，并且在函数调用期间执行过程都处于该环境中。当调用的函数返回后，执行过程会返回原始执行环境。同时创建的执行环境会包含一个作用域链，这个作用域链是通过将该执行环境的活动（可变）对象添加到保存于所调用函数对象的&nbsp;<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">[[scope]]&nbsp;</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">属性中的作用域链前端而构成的</span>。</p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">结合上面的例子简单分析一下，<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">func()</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">函数返回了一个匿名的函数</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">function</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">，所以被返回的匿名函数他的执行环境和作用域链不会被回收，当我们访问</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">attr</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">属性的时候，我很会直接到</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">function</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">运行环境的作用域链中去查找。（对于这块内容涉及的</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">内容比深奥，也不怎么理解，不过可以参考：</span><a href="http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html" style="border-style: initial; border-color: initial; color: #ca0000; text-decoration: none; border-width: 0px; padding: 0px; margin: 0px;">http://www.cn-cuckoo.com/2007/08/01/understand-Javascript-closures-72.html</a>&nbsp;）。</p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">面向对象</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;"><br /></span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">Javascript<span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的面向对象真是有点诡异，因为</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">是一个函数式编程语言，虽然我们可以模拟继承，封装等面向对象的特性，但是总是不如</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">java</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">这样的语言感觉更自然，当然不排除自己的主观因素。我们先来模拟一下</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的面向对象，体验一下。</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">　　方式一：最原始的方式</p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">var car = new Object();  
car.color = "red";  
car.speed = 100;  
car.showColor = function() {  
    alert(this.color);  
};  
  
car.showColor();  
</pre>
</div>
<p>　　<span class="Apple-style-span" style="font-family: Arial; line-height: 26px;">方式二：运用工厂</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">function createCar() {  
    var car = new Object();  
    car.color = "red";  
    car.speed = 100;  
    car.showColor = function() {  
        alert(this.color);  
    };  
    return car;  
}  
var car = createCar();  
car.showColor();  
</pre>
</div>
<p>　　<span class="Apple-style-span" style="font-family: Arial; line-height: 26px;">方式三：运用构造函数</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">function Car(color, speed) {  
    this.color = color;  
    this.speed = speed;  
    this.showColor = function() {  
        alert(this.color);  
    };  
}  
var car = new Car("blue", 400);  
car.showColor();  
</pre>
</div>
<p>　　<span class="Apple-style-span" style="font-family: Arial; line-height: 26px;">方式四：运用原型方式</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">function Car() {  
}  
Car.prototype.color = "blue";  
Car.prototype.speed = 300;  
Car.prototype.showColor = function() {  
    alert(this.color);  
};  
var car = new Car();  
car.showColor();  
</pre>
</div>
<p>　　<span class="Apple-style-span" style="font-family: Arial; line-height: 26px;">方式五：混合构造函数和原型方式</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">function Car(color, speed) {  
    this.color = color;  
    this.speed = speed;  
    this.drivers = new Array("mike", "sue");  
}  
Car.prototype.showColor = function() {  
    alert(this.color);  
};  
var car1 = new Car("green", 300);  
car1.drivers.push("wangkang");  
car1.showColor();  
alert(car1.drivers.join());  
  
var car2 = new Car("black", 300);  
car2.showColor();  
alert(car2.drivers.join());  
</pre>
</div>
<p>　　<span class="Apple-style-span" style="font-family: Arial; line-height: 26px;">方式六：动态原型方法</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">function Car(color, speed) {  
    this.color = color;  
    this.speed = speed;  
    this.drivers = new Array("mike", "sue");  
}  
if (typeof Car._initialized == "undefined") {  
    Car.prototype.showColor = function() {  
        alert(this.color);  
    };  
    Car._initialized = true;  
}  
var car1 = new Car("green", 300);  
car1.drivers.push("wangkang");  
car1.showColor();  
alert(car1.drivers.join());  
  
var car2 = new Car("black", 300);  
car2.showColor();  
alert(car2.drivers.join());  
</pre>
</div>
<p>　　<span class="Apple-style-span" style="font-family: Arial; line-height: 26px;">方式七：混合工厂</span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:false;">function Car() {  
    var car = new Object();  
    car.color = "red";  
    car.speed = 100;  
    car.showColor = function() {  
        alert(this.color);  
    };  
    return car;  
}  
var car = new Car();  
car.showColor();  
</pre>
</div>
<p>毕竟面向对象只是一种编程的思想，用的多了其义自现，因为自己没有学习多长时间的<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">，所以内部的机制不是很理解，但是通过上面推荐的那篇文章肯定有帮助，因为它是从</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">运行机制上进行了彻底的分析。</span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;">只是给大家进行一个<span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的扫盲，所以力求文章中没有错误，思想少了一点，例子多了一点！还有那一片推荐的博客希望大家认真的琢磨几遍，如果理解了那篇博客那么</span><span style="border-style: initial; border-color: initial; font-family: 'Times New Roman'; border-width: 0px; padding: 0px; margin: 0px;">Javascript</span><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;">的作用域，闭包，面向对象等特性就非常容易理解了。</span><a href="http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html" style="border-style: initial; border-color: initial; color: #ca0000; text-decoration: none; border-width: 0px; padding: 0px; margin: 0px;">http://www.cn-cuckoo.com/2007/08/01/understand-Javascript-closures-72.html</a></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><br /></span></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><br /></span></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><br /></span></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><br /></span></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><br /></span></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><br /></span></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><br /></span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;"><br /></span></p>
<p><span class="Apple-style-span" style="font-family: Arial; line-height: 26px;"><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;"><br /></span></span></p>
<p style="border-style: initial; border-color: initial; border-width: 0px; padding: 0px; margin: 0px;"><span style="border-style: initial; border-color: initial; font-family: 宋体; border-width: 0px; padding: 0px; margin: 0px;"><br /></span></p><img src ="http://www.blogjava.net/focusJ/aggbug/367226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/focusJ/" target="_blank">王康</a> 2011-10-06 18:02 <a href="http://www.blogjava.net/focusJ/archive/2011/10/06/367226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>