??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
表单如下Q?br><form name="form1" action="test.jsp" method="post" onsubmit="return checkData();">
<input name="checkall1" type="checkbox" value="0" onClick="checkAllBox(this);"/>全?lt;br>
<input name="answer" type="checkbox" value="a"/>A<br>
<input name="answer" type="checkbox" value="b"/>B<br>
<input name="answer" type="checkbox" value="c"/>C<br>
<input name="answer" type="checkbox" value="d"/>D<br>
<input name="answer" type="checkbox" value="e"/>E<br>
<input name="answer" type="checkbox" value="f"/>F<br>
</form>
全选及验证javascript如下Q?/strong>
<script type="text/javascript">
function checkAllBox(obj){
var answer= document.getElementsByName("answer");
if(obj.checked==true){
for(var i=0;i<answer.length;i++){
answer[i].checked = true;
}
}else{
for(var i=0;i<answer.length;i++){
answer[i].checked = false;
}
}
}
function checkData(){
var answer= document.getElementsByName("answer");
var flag = false;
for(var i=0;i<income.length;i++){
if(income[i].checked == true){
flag = true;
break;
}
}
if(!flag){
alert("误选择一?);
}
return flag;
}
</script>
test.jsp中取值如下:
String[] answer= request.getParameterValues("answer");//q里只取得了选中的项Q如果没有选中M一,则ؓnull
if(answer!=null){
for(String i:answer){
System.out.println(i);
}
}
]]>
<%@ page import="java.util.*"%>
<%
//remove cache
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
%>
]]>
onerror事g处理函数是第一个用来协助javascript处理错误的机制。页面上出现异常Ӟerror事g便在window对象上触发?br>例如Q?br>
c?/td> | 发生原因 |
EvalError | 错误发生在eval()函数?/td> |
RangeError | 数字的D出javascript可表C的范围 |
ReferenceError | 使用了非法的引用 |
SyntaxError | 在eval()函数调用中发生了语法错误。其他的语法错误由浏览器报告Q无法通过try...catch语句处理 |
TypeError | 变量的类型不是预期所需?/td> |
URIError | 在encodeURI()或者decodeURI()函数中发生了错误 |
Ҏ?Ҏ | cd/q回cd | 说明 |
nodeName | String | 节点的名?Ҏ节点的类型而定?/td> |
nodeValue | String | 节点的?Ҏ节点的类型而定?/td> |
nodeType | Number | 节点的类型常量g一 |
ownerDocument | Document | 指向q个节点所属的文档 |
firstChild | Node | 指向在childNodes列表中的W一个节?/td> |
lastChild | Node | 指向在childNodes列表中的最后一个节?/td> |
childNodes | NodeList | 所有子节点的列?/td> |
previousSibling | Node | 指向前一个兄弟节?如果q个节点是W一个兄弟节点,那么该gؓnull |
nextSibling | Node | 指向后一个兄弟节?如果q个节点是最后一个兄弟节点,那么该gؓnull |
hasChildNodes() | Boolean | 当childNodes包含一个或多个节点?q回?/td> |
attributes | NamedNodeMap | 包含了代表一个元素的Ҏ的Attr对象;仅用于Element节点 |
appendChild(node) | Node | noded到childNodes的末?/td> |
removeChild(node) | Node | 从childNodes中删除node |
replaceChild(newnode,oldnode) | Node | childNodes中的oldnode替换成newnode |
insertBefore(newnode,refnode) | Node | 在childNodes中的refnode之前插入newnodd |
Ҏ?Ҏ | 说明 |
caption | 指向<caption/>元素q将其放入表?/td> |
tBodies | <tbody/>元素的集?/td> |
tFoot | 指向<tfoot/>元素Q如果存在) |
tHead | 指向<thead/>元素Q如果存在) |
rows | 表格中所有行的集?/td> |
createTHead() | 创徏<thead/>元素q将其放入表?/td> |
createTFood() | 创徏<tfoot/>元素q将其放入表?/td> |
createCpation() | 创徏<caption/>元素q将其放入表?/td> |
deleteTHead() | 删除<thead/>元素 |
deleteTFood() | 删除<tfoot/>元素 |
deleteCaption() | 删除<caption/>元素 |
deleteRow(position) | 删除指定位置上的?/td> |
insertRow(position) | 在rows集合中的指定位置上插入一个新?/td> |
Ҏ?Ҏ | 说明 |
rows | <tbody/>中所有行的集?/td> |
deleteRow(position) | 删除指定位置上的?/td> |
insertRow(position) | 在rows集合中的指定位置上插入一个新?/td> |
Ҏ?Ҏ | 说明 |
cells | <tr/>元素中所有的单元格的集合 |
deleteCell(postion) | 删除l定位置上的单元?/td> |
insertCell(postion) | 在cells集合的给点位|上插入一个新的单元格 |
EventUtil.formatEvent = function (oEvent) {
if (isIE && isWin) {
oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
oEvent.eventPhase = 2;
oEvent.isChar = (oEvent.charCode > 0);
oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
oEvent.pageY = oEvent.clientY + document.body.scrollTop;
oEvent.preventDefault = function () {
this.returnValue = false;
};
if (oEvent.type == "mouseout") {
oEvent.relatedTarget = oEvent.toElement;
} else if (oEvent.type == "mouseover") {
oEvent.relatedTarget = oEvent.fromElement;
}
oEvent.stopPropagation = function () {
this.cancelBubble = true;
};
oEvent.target = oEvent.srcElement;
oEvent.time = (new Date).getTime();
}
return oEvent;
};
EventUtil.getEvent = function() {
if (window.event) {
return this.formatEvent(window.event);
} else {
return EventUtil.getEvent.caller.arguments[0];
}
};
function compareVersions(sVersion1, sVersion2) {
var aVersion1 = sVersion1.split(".");
var aVersion2 = sVersion2.split(".");
if (aVersion1.length > aVersion2.length) {
for (var i=0; i < aVersion1.length - aVersion2.length; i++) {
aVersion2.push("0");
}
} else if (aVersion1.length < aVersion2.length) {
for (var i=0; i < aVersion2.length - aVersion1.length; i++) {
aVersion1.push("0");
}
}
for (var i=0; i < aVersion1.length; i++) {
if (aVersion1[i] < aVersion2[i]) {
return -1;
} else if (aVersion1[i] > aVersion2[i]) {
return 1;
}
}
return 0;
}
var isOpera = sUserAgent.indexOf("Opera") > -1;
var isMinOpera4 = isMinOpera5 = isMinOpera6 = isMinOpera7 = isMinOpera7_5 = false;
if (isOpera) {
var fOperaVersion;
if(navigator.appName == "Opera") {
fOperaVersion = fAppVersion;
} else {
var reOperaVersion = new RegExp("Opera (\\d+\\.\\d+)");
reOperaVersion.test(sUserAgent);
fOperaVersion = parseFloat(RegExp["$1"]);
}
isMinOpera4 = fOperaVersion >= 4;
isMinOpera5 = fOperaVersion >= 5;
isMinOpera6 = fOperaVersion >= 6;
isMinOpera7 = fOperaVersion >= 7;
isMinOpera7_5 = fOperaVersion >= 7.5;
}
var isKHTML = sUserAgent.indexOf("KHTML") > -1
|| sUserAgent.indexOf("Konqueror") > -1
|| sUserAgent.indexOf("AppleWebKit") > -1;
var isMinSafari1 = isMinSafari1_2 = false;
var isMinKonq2_2 = isMinKonq3 = isMinKonq3_1 = isMinKonq3_2 = false;
if (isKHTML) {
isSafari = sUserAgent.indexOf("AppleWebKit") > -1;
isKonq = sUserAgent.indexOf("Konqueror") > -1;
if (isSafari) {
var reAppleWebKit = new RegExp("AppleWebKit\\/(\\d+(?:\\.\\d*)?)");
reAppleWebKit.test(sUserAgent);
var fAppleWebKitVersion = parseFloat(RegExp["$1"]);
isMinSafari1 = fAppleWebKitVersion >= 85;
isMinSafari1_2 = fAppleWebKitVersion >= 124;
} else if (isKonq) {
var reKonq = new RegExp("Konqueror\\/(\\d+(?:\\.\\d+(?:\\.\\d)?)?)");
reKonq.test(sUserAgent);
isMinKonq2_2 = compareVersions(RegExp["$1"], "2.2") >= 0;
isMinKonq3 = compareVersions(RegExp["$1"], "3.0") >= 0;
isMinKonq3_1 = compareVersions(RegExp["$1"], "3.1") >= 0;
isMinKonq3_2 = compareVersions(RegExp["$1"], "3.2") >= 0;
}
}
var isIE = sUserAgent.indexOf("compatible") > -1
&& sUserAgent.indexOf("MSIE") > -1
&& !isOpera;
var isMinIE4 = isMinIE5 = isMinIE5_5 = isMinIE6 = false;
if (isIE) {
var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
reIE.test(sUserAgent);
var fIEVersion = parseFloat(RegExp["$1"]);
isMinIE4 = fIEVersion >= 4;
isMinIE5 = fIEVersion >= 5;
isMinIE5_5 = fIEVersion >= 5.5;
isMinIE6 = fIEVersion >= 6.0;
}
var isMoz = sUserAgent.indexOf("Gecko") > -1
&& !isKHTML;
var isMinMoz1 = sMinMoz1_4 = isMinMoz1_5 = false;
if (isMoz) {
var reMoz = new RegExp("rv:(\\d+\\.\\d+(?:\\.\\d+)?)");
reMoz.test(sUserAgent);
isMinMoz1 = compareVersions(RegExp["$1"], "1.0") >= 0;
isMinMoz1_4 = compareVersions(RegExp["$1"], "1.4") >= 0;
isMinMoz1_5 = compareVersions(RegExp["$1"], "1.5") >= 0;
}
var isNS4 = !isIE && !isOpera && !isMoz && !isKHTML
&& (sUserAgent.indexOf("Mozilla") == 0)
&& (navigator.appName == "Netscape")
&& (fAppVersion >= 4.0 && fAppVersion < 5.0);
var isMinNS4 = isMinNS4_5 = isMinNS4_7 = isMinNS4_8 = false;
if (isNS4) {
isMinNS4 = true;
isMinNS4_5 = fAppVersion >= 4.5;
isMinNS4_7 = fAppVersion >= 4.7;
isMinNS4_8 = fAppVersion >= 4.8;
}
var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows");
var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC")
|| (navigator.platform == "Macintosh");
var isUnix = (navigator.platform == "X11") && !isWin && !isMac;
var isWin95 = isWin98 = isWinNT4 = isWin2K = isWinME = isWinXP = false;
var isMac68K = isMacPPC = false;
var isSunOS = isMinSunOS4 = isMinSunOS5 = isMinSunOS5_5 = false;
if (isWin) {
isWin95 = sUserAgent.indexOf("Win95") > -1
|| sUserAgent.indexOf("Windows 95") > -1;
isWin98 = sUserAgent.indexOf("Win98") > -1
|| sUserAgent.indexOf("Windows 98") > -1;
isWinME = sUserAgent.indexOf("Win 9x 4.90") > -1
|| sUserAgent.indexOf("Windows ME") > -1;
isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1
|| sUserAgent.indexOf("Windows 2000") > -1;
isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1
|| sUserAgent.indexOf("Windows XP") > -1;
isWinNT4 = sUserAgent.indexOf("WinNT") > -1
|| sUserAgent.indexOf("Windows NT") > -1
|| sUserAgent.indexOf("WinNT4.0") > -1
|| sUserAgent.indexOf("Windows NT 4.0") > -1
&& (!isWinME && !isWin2K && !isWinXP);
}
if (isMac) {
isMac68K = sUserAgent.indexOf("Mac_68000") > -1
|| sUserAgent.indexOf("68K") > -1;
isMacPPC = sUserAgent.indexOf("Mac_PowerPC") > -1
|| sUserAgent.indexOf("PPC") > -1;
}
if (isUnix) {
isSunOS = sUserAgent.indexOf("SunOS") > -1;
if (isSunOS) {
var reSunOS = new RegExp("SunOS (\\d+\\.\\d+(?:\\.\\d+)?)");
reSunOS.test(sUserAgent);
isMinSunOS4 = compareVersions(RegExp["$1"], "4.0") >= 0;
isMinSunOS5 = compareVersions(RegExp["$1"], "5.0") >= 0;
isMinSunOS5_5 = compareVersions(RegExp["$1"], "5.5") >= 0;
}
}
字符 | 描述 |
\t | 制表W?/td> |
\n | 换行W?/td> |
\r | 回RW?/td> |
\f | 换页W?/td> |
\a | alert字符 |
\e | escape字符 |
\cx | 与X相对应的控制字符 |
\b | 回退字符 |
\v | 垂直制表W?/td> |
\0 | I字W?/td> |
代码 | {同?/td> | 匚w |
. | [^\n\r] | 除了换行和回车之外的L字符 |
\d | [0-9] | 数字 |
\D | [^0-9] | 非数字字W?/td> |
\s | [\t\n\x0B\f\r] | I白字符 |
\S | [^\t\n\x0B\f\r] | 非空白字W?/td> |
\w | [a-zA-Z_0-9] | 单词字符Q所有字母,所有的数字和下划线Q?/td> |
\W | [^a-zA-Z_0-9] | 非单词字W?/td> |
代码 | 描述 |
? | 出现零次或一?/td> |
* | 出现零次或多?/td> |
+ | 出现一ơ或多次Q至出Cơ) |
{n} | 一定出现n?/td> |
{n,m} | 臛_出现nơ但不超qm?/td> |
{n,} | 臛_出现n?/td> |
贪婪 | 惰?/td> | 支配 | 描述 |
? | ?? | ?+ | 零次或一ơ出?/td> |
* | *? | *+ | 零次或多ơ出?/td> |
+ | +? | ++ | 一ơ或多次出现 |
{n} | {n}? | {n}+ | 恰好nơ出?/td> |
{n,m} | {n,m}? | {n,m}+ | 臛_nơ至多mơ出?/td> |
{n,} | {n,}? | {n,}+ | 臛_nơ出?/td> |
览器对支配量词的支持还很不完善。IE和Opera不支持,Mozilla支配量词看作是贪婪的?br>
二、复杂模?br>1.分组
分组是通过一pd括号包围一pd字符、字W类以及量词来用的?br>/dogdog/可用分l来重写?(dog){2}/
/([bd]ad?)*/匚w零个和多?ba","da","bad"?dad"
/(mom( and dad)?)/匚w"mom" 或 "mom and dad"
2.反向引用
在表辑ּ计算完成后还可以怎样利用分组Q每个分l都被存攑֜一个特D的地方以备来使用。这些存储在分组中的Ҏ|我们UC为反向引用?br>反向引用是按照从左到右遇到的左括号字W的序q行创徏和编L。例如表辑ּ(A?(B?(C?)))生编号从1-3的三个反向引?br>(1).(A?(B?(C?)))
(2).(B?(C?))
(3).(C?)
反向引用可以有几U不同的使用Ҏ?br>首先Q用正则表辑ּ对象的test(),match()或search()Ҏ后,反向引用的值可以从RegExp构造函C获得。例
var sToMatch = "#123456789";
var reNumbers = /#(\d+)/;
reNumbers.test(sToMatch);
alert(RegExp.$1); //outputs "123456789"
然后Q还可以直接在定义分l的表达式中包含反向引用Q这可以通过使用Ҏ转义序列如\1,\2{等实现
例如
var sToMatch = "dogdog";
var reDogDog = /(dog)\1/;
alert(reDogDog.test(sToMatch)); //outputs "true"
正则表达式reDogDog首先创徏单词dog的组Q然后又被特D{义序列\1引用Q得这个正则表辑ּ{同?dogdog/
W三Q反向引用可以用在String对象的replace()Ҏ中,q通过使用Ҏ字符序列$1,$2{等来实现。例?br>var sToChange = "1234 5678";
var reMatch = /(\d{4}) (\d{4})/
var sNew = sToChange.replace(reMatch,"$2 $1");
alert(sNew); //outputs "5678 1234"
3.候?br>有时候要构徏一个能够正匹配想得到所有可能性的模式是十分困隄。如果要对同一个表辑ּ同时匚w"red"?break"时要怎么做呢Q这些单词完全没有相同的字符Q这样就要写两个不同的正则表辑ּQƈ分别对两个字W串q行匚wQ像q样Q?br>var sToMatch1 = "red";
var sToMatch2 = "black";
var reRed = /red/;
var reBlack = /black/;
alert(reRed.test(sToMatch1)||reBlack.test(sToMatch1)); //outputs "true"
alert(reRed.test(sToMatch2)||reBlack.test(sToMatch2)); //outputs "true"
q完成了dQ但是十分冗ѝ还有另一U方式就是用正则表辑ּ的候选操作符。例Q?br>var sToMatch1 = "red";
var sToMatch2 = "black";
var reRedOrBlack = /(red|black)/;
alert(reRedOrBlack.test(sToMatch1)); //outputs "true"
alert(reRedOrBlack.test(sToMatch2)); //outputs "true"
4.非捕h分l?br>创徏反向引用的分l,我们UC为捕h分l。同时还有一U非捕获性分l,它不会创建反向引用。在较长的正则表辑ּ中,存储反向引用会降低匹配速度?br>如果要创Z个非捕获性分l,只要在左括号的后面加上一个问号和一个紧跟的冒号Q?br>var sToMatch = "#123456789";
var reNumbers = /#(?:\d+)/;
reNumbers.test(sToMatch);
alert(RegExp.$1); //outputs ""
5.前瞻
有时候,可能希望Q当某个特定的字W分l出现在另一个字W串之前Ӟ才去捕获它。如果?#8220;前瞻”可以让q个q程变得十分单?br>前瞻Q告诉正则表辑ּq算器向前看一些字W而不Ud其位|。同样存在正向前d负向前瞻。正向前L查的是接下来出现的是不是某个特定字符集。而负向前d是检查接下来的不应该出现的特定字W集?br>创徏正向前瞻要将模式攑֜(?=?之间。注意这不是分组Q虽然它也用到括受?br>var sToMatch1 = "bedroom";
var sToMatch2 = "bedding";
var reBed = /(bed(?=room)/;
alert(reBed.test(sToMatch1)); //outputs "true"
alert(RegExp.$1); //outputs "bed"
alert(reBed.test(sToMatch2)); //outputs "false"
负向前瞻Q则要将模式攑֜(?!?之间?br>var sToMatch1 = "bedroom";
var sToMatch2 = "bedding";
var reBed = /(bed(?!room)/;
alert(reBed.test(sToMatch1)); //outputs "false"
alert(reBed.test(sToMatch2)); //outputs "true"
alert(RegExp.$1); //outputs "bed"
6.边界
边界 用于正则表达式中表示模式的位|。下表列Z几种可能的边?br>
边界 | 描述 |
^ | 行开?/td> |
$ | 行结?/td> |
\b | 单词的边?/td> |
\B | 非单词的边界 |
长名 | 短名 | 描述 |
input | $_ | 最后用于匹配的字符?传递给exec()或test()的字W串) |
lastMatch | $& | 最后匹配的字符 |
lastParen | $+ | 最后匹配的分组 |
leftContext | $` | 在上ơ匹配的前面的子?/td> |
multiline | $* | 用于指定是否所有的表达式都使用多行模式的布?/td> |
rightContext | $' | 在上ơ匹配之后的子串 |
function ClassB(sColor, sName) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
所有新的属性和新的Ҏ都必d删除了新Ҏ的代码行后定义。否则,可能会覆盖超cȝ相关属性和Ҏ?br>对象冒充可以支持多ѝ?br>function ClassZ(){
this.newMethod = ClassX;
this.newMethod(sColor);
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod(sColor);
delete this.newMethod;
}
q里存在一个弊端,如果ClassX和ClassYh相同的属性或ҎQClassYh高优先Q因为承的是最后的cR?br>
2.call()Ҏ
call()Ҏ是与l典的对象冒充方法最怼的方法,它的W一个参数用作this的对象,其他参数都直接传递函数自w?br>function ClassA(sColor) {
this.color = sColor;
this.sayColor = function () {
alert(this.color);
};
}
function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.call(this, sColor);
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
3.apply()Ҏ
apply()Ҏ有两个参敎ͼ用作this的对象和要传递参数的数组。例如:
function ClassA(sColor) {
this.color = sColor;
this.sayColor = function () {
alert(this.color);
};
}
function ClassB(sColor, sName) {
//this.newMethod = ClassA;
//this.newMethod(color);
//delete this.newMethod;
ClassA.apply(this, arguments);
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
当然Q只有超cM的参数顺序与子类中的参数序完全一致时才可以传递参数对象。如果不是,必dZ个单独的数组Q按照正的序攄参数。此外,q可以用call()Ҏ?br>
4.原型?br>function ClassA() {
}
ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB() {
}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
alert(this.name);
};
var objA = new ClassA();
var objB = new ClassB();
objA.color = "red";
objB.color = "blue";
objB.name = "Nicholas";
objA.sayColor();
objB.sayColor();
objB.sayName();
注意Q调用ClassA的构造函数时Q没有给它传递参数。这在原型链中是标准做法。要保构造函数没有Q何参数?br>原型铄弊端是不支持多重l承?br>
5.混合方式
与创建对象最好方式相|用对象冒充承构造函数的属性,用原型链l承prototype对象的方法?br>function ClassA(sColor) {
this.color = sColor;
}
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB(sColor, sName) {
ClassA.call(this, sColor);
this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.sayName = function () {
alert(this.name);
};
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
var car1 = createCar("red", 4, 23);
var car2 = createCar("blue", 3, 25);
car1.showColor(); //outputs "red"
car2.showColor(); //outputs "blue"
q个例子中,每次调用函数createCar()Q都要创建新函数showColor()Q意味着每个对象都有自己的showColor()版本Q事实上Q每个对象都׃n了同一个函数?br>有些开发者在工厂函数外定义对象的ҎQ然后通过属性指向该ҎQ从而避开q个问题?br>function showColor(){
alert(this.color);
}
function createCar(color, doors, mpg) {
var tempcar = new Object;
tempcar.color = color;
tempcar.doors = doors;
tempcar.mpg = mpg;
tempcar.showColor = showColor;
return tempcar;
}
var car1 = createCar("red", 4, 23);
var car2 = createCar("blue", 3, 25);
car1.showColor(); //outputs "red"
car2.showColor(); //outputs "blue"
从功能上Ԍq样解决了重复创建函数对象的问题Q但该函数看h不像对象的方法。所有这些问题引发了开发者定义的构造函数的出现?br>
2.构造函数方?br>function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function () {
alert(this.color)
};
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.showColor(); //outputs "red"
oCar2.showColor(); //outputs "blue"
像工厂函数Q构造函C重复生成函数Qؓ每个对象都创建独立的函数版本。不q,也可以用外部函数重写构造函敎ͼ同样Q这么做语义上无M意义?br>
3.原型方式
function Car(){
}
Car.prototype.color = "red";
Car.prototype.doors= 4;
Car.prototype.mpg= 23;
Car.prototype.showColor = function(){
alert(this.color);
}
var oCar1 = new Car();
var oCar2 = new Car();
它解决了前面两种方式存在的两个问题。但q不h意。首先,q个构造函数没有参数。用原型方式时Q不能通过构造函C递参数初始化属性的|q点很o厌,但还没完Q真正的问题出现在属性指向的是对象,而不是函数时。考虑下面的例子:
function Car(){
}
Car.prototype.color = "red";
Car.prototype.doors= 4;
Car.prototype.mpg= 23;
Car.prototype.drivers = new Array("Mike","Sue");
Car.prototype.showColor = function(){
alert(this.color);
}
var oCar1 = new Car();
var oCar2 = new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue,Matt"
4.混合的构造函?原型方式
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike", "Sue");
}
Car.prototype.showColor = function () {
alert(this.color);
};
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue"
现在更像创Z般对象了。所有的非函数属性都有构造函C创徏Q意味着又可用构造函数的参数赋予属性默认g。因为只创徏showColor()函数的一个实例,所以没有内存浪贏V?br>
5.动态原型方?br>function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike", "Sue");
if (typeof Car._initialized == "undefined") {
Car.prototype.showColor = function () {
alert(this.color);
};
Car._initialized = true;
}
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); //outputs "Mike,Sue,Matt"
alert(oCar2.drivers); //outputs "Mike,Sue"
动态原型方法的基本x与合的构造函?原型方式相同Q即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。唯一的区别是赋予对象Ҏ的位|?/p>
6.混合工厂方式
q种方式通常是在不能应用前一U方式时的变通方法。它的目的是创徏假构造函敎ͼ只返回另一U对象的新实例?br>function Car() {
var tempcar = new Object;
tempcar.color = "red";
tempcar.doors = 4;
tempcar.mpg = 23;
tempcar.showColor = function () {
alert(this.color)
};
return tempcar;
}
与经典方式不同,q种方式使用newq算W,使它看v来像真正的构造函数?br>
7.采用哪种方式
如前所qͼ目前使用最q泛的是混合的构造函?原型方式。些外,动态原型方法也很流行,在功能上与前者等P可以采用q两U方式中的Q何一U?br>
二、修改对?br>1.创徏新方?br>可以用prototype属性ؓM已有的类定义新方法,像处理自己的类一栗?br>例:
Array.prototype.indexOf = function(vItem){
for(var i=0;i<this.length;i++){
if(vItem == this[i]){
return i;
}
}
retunr -1;
}
最后,如果想给ECMAScript中的每个本地对象d新方法,必须在Object对象的prototype属性上定义它?br>
2.重定义已有方?br>像能给自己的类定义新方法一P也可重定义已有的Ҏ。函数名只是指向函数的指针,因此可以LC它指向其他函数?br>?br>Function.prototype.toString = function(){
return "Function code hidden";
}
function sayHi(){
alert("hi");
}
alert(sayHi.toString()); //outputs "Function code hidden"
W三范式Q?NFQ:如果关系模式RQUQFQ中的所有非d性对M候选关键字都不存在传递信赖, 则称关系R是属于第三范式的?例:如S1QSNOQSNAMEQDNOQDNAMEQLOCATIONQ?各属性分别代表学P姓名Q所在系Q系名称Q系地址?关键字SNO军_各个属性。由于是单个关键字,没有部分依赖的问题,肯定?NF。但q关p肯定有大量的冗余,有关学生所在的几个属性DNOQ?DNAMEQLOCATION重复存储,插入Q删除和修改时也生类g上例的情c?原因Q关pM存在传递依赖造成的。即SNO -> DNO。而DNO -> SNO却不存在QDNO -> LOCATION,因此关键?SNO ?LOCATION 函数军_是通过传递依?SNO -> LOCATION实现的。也是_SNO不直接决定非d性LOCATION?解决目地Q每个关pL式中不能留有传递依赖?解决ҎQ分Z个关p?SQSNOQSNAMEQDNOQ,DQDNOQDNAMEQLOCATIONQ?注意Q关pS中不能没有外关键字DNO。否则两个关pM间失去联pR?/p>
BCNFQ?如果关系模式RQUQFQ的所有属性(包括d性和非主属性)都不传递依赖于R的Q何候选关键字Q那么称关系R是属于BCNF的。或是关pL式RQ如果每 个决定因素都包含关键字(而不是被关键字所包含Q,则RCNF的关pL式?例:配g理关系模式 WPEQWNOQPNOQENOQQNTQ分别表仓库P配gP职工P数量。有以下条g a.一个仓库有多个职工?b.一个职工仅在一个仓库工作?c.每个仓库里一U型L配g׃责,但一个h可以理几种配g?d.同一U型L配g可以分放在几个仓库中?分析Q由以上?PNO 不能定QNTQ由l合属性(WNOQPNOQ来军_Q存在函C赖(WNOQPNOQ?>ENO。由于每个仓库里的一U配件由专h负责Q而一个h可以理几种配gQ所以有l合属性(WNOQPNOQ才能确定负责hQ有QWNOQ?PNOQ?> ENO。因?一个职工仅在一个仓库工作,有ENO ->WNO。由于每个仓库里的一U配件由专h负责Q而一个职工仅在一个仓库工作,?QENOQPNOQ?> QNT?找一下候选关键字Q因为(WNOQPNOQ?-> QNTQ(WNOQPNOQ?> ENO Q因此(WNOQPNOQ可以决定整个元l,是一个候选关键字。根据ENO->WNOQ(ENOQPNOQ?>QNTQ故QENOQPNOQ?也能军_整个元组Qؓ另一个候选关键字。属性ENOQWNOQPNO均ؓd性,只有一个非d性QNT。它对Q何一个候选关键字都是完全函数依赖的,q?且是直接依赖Q所以该关系模式?NF?分析一下主属性。因为ENO->WNOQ主属性ENO是WNO的决定因素,但是它本w不是关键字Q只是组合关键字的一部分。这造成d性WNO?另外一个候选关键字QENOQPNOQ的?分依赖,因ؓQENOQPNOQ?>ENO但反q来不成立,而P->WNOQ故QENOQPNOQ?> WNO 也是传递依赖?虽然没有非主属性对候选关键辽的传递依赖,但存在主属性对候选关键字的传递依赖,同样也会带来ȝ。如一个新职工分配C库工作,但暂时处于实习阶D,没有独立负责Ҏ些配件的理d。由于缺关键字的一部分PNO而无法插入到该关pM厅R又如某个hҎ不管配g了去负责安全Q则在删除配件的同时该职?也会被删除?解决办法Q分成管理EPQENOQPNOQQNTQ,关键字是QENOQPNOQ工作EWQENOQWNOQ其关键字是ENO ~点Q分解后函数依赖的保持性较差。如此例中,׃分解,函数依赖QWNOQPNOQ?> ENO 丢失?因而对原来的语义有所破坏。没有体现出每个仓库里一U部件由专h负责。有可能出现一部g׃个h或两个以上的人来同时理。因此,分解之后的关pL式降低了部分完整性约束?
一个关pd解成多个关系Q要使得分解有意义,L的要求是分解后不丢失原来的信息。这些信息不仅包括数?本nQ而且包括由函C赖所表示的数据之间的怺制约。进行分解的目标是达到更高一U的规范化程度,但是分解的同时必考虑两个问题Q无损联接性和保持?C赖。有时往往不可能做到既有无损联接性,又完全保持函C赖。需要根据需要进行权衡?
1NF直到BCNF的四U范式之间有如下关系Q?BCNF包含?NF包含2NF包含1NF
结Q目圎ͼ规范化目的是使结构更合理Q消除存储异常,使数据冗余尽量小Q便于插入、删除和更新原则Q遵从概念单一?"一事一?原则Q即一个关pL式描qC个实体或实体间的一U联pR规范的实质是概念的单一化?ҎQ将关系模式投媄分解成两个或两个以上的关pL式?要求Q分解后的关pL式集合应当与原关pL?{h"Q即l过自然联接可以恢复原关p而不丢失信息Qƈ保持属性间合理的联pR?
注意Q?一个关pL式结q分解可以得C同关pL式集合,也就是说分解Ҏ不是唯一的。最冗余的要求必须以分解后的数据库能够表达原来数据库所有信息ؓ前提来实 现。其Ҏ目标是节省存储空_避免数据不一致性,提高对关pȝ操作效率Q同时满_用需求。实际上Qƈ不一定要求全部模式都辑ֈBCNF不可。有时故?保留部分冗余可能更方便数据查询。尤其对于那些更新频度不高,查询频度极高的数据库pȝ更是如此?
在关pL据库中,除了函数依赖之外q有多g赖,联接依赖的问题,从而提ZW四范式Q第五范式等更高一U的规范化要求?/p>
import java.io.File;
import java.io.IOException;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
/**
*
* CopyRight (C) m.tkk7.com/ilovezmh All rights reserved.<p>
*
* WuHan Inpoint Information Technology Development,Inc.<p>
*
* Author zhu<p>
*
* @version 1.0 2007-2-6
*
* <p>Base on : JDK1.5<p>
*
*/
public class JexcelSample {
/**
* 写excel文g
*
*/
public void writeExc(File filename){
WritableWorkbook wwb = null;
try
{
wwb = Workbook.createWorkbook(filename);
}
catch (Exception e){
e.printStackTrace();
}
//创徏Excel工作?
WritableSheet ws = wwb.createSheet("通讯?, 0);//创徏sheet
try {
ws.mergeCells(0, 0, 2, 1);//合ƈ单元?左列Q左行,叛_Q右?从第1行第1列到W?行第3?br /> Label header = new Label(0, 0, "通讯?191026?", getHeader());
ws.addCell(header);//写入?br /> Label l = new Label(0, 2, "姓名", getTitle());//W??br /> ws.addCell(l);
l = new Label(1, 2, "电话", getTitle());
ws.addCell(l);
l = new Label(2, 2, "地址", getTitle());
ws.addCell(l);
l = new Label(0, 3, "祝", getNormolCell());//W??br /> ws.addCell(l);
l = new Label(1, 3, "1314***0974", getNormolCell());
ws.addCell(l);
l = new Label(2, 3, "武汉武昌", getNormolCell());
ws.addCell(l);
l = new Label(0, 4, "施", getNormolCell());//W??br /> ws.addCell(l);
l = new Label(1, 4, "1347***5057", getNormolCell());
ws.addCell(l);
l = new Label(2, 4, "武汉武昌", getNormolCell());
ws.addCell(l);
ws.setColumnView(0,20);//讄列宽
ws.setColumnView(1,20);
ws.setColumnView(2,40);
ws.setRowView(0,400);//讄行高
ws.setRowView(1,400);
ws.setRowView(2,500);
ws.setRowView(3,500);
ws.setRowView(4,500);
} catch (RowsExceededException e1) {
e1.printStackTrace();
} catch (WriteException e1) {
e1.printStackTrace();
}
//输出?br /> try {
wwb.write();
} catch (IOException ex) {
// TODO 自动生成 catch ?br /> ex.printStackTrace();
}
//关闭?br /> try {
wwb.close();
} catch (WriteException ex) {
// TODO 自动生成 catch ?br /> ex.printStackTrace();
} catch (IOException ex) {
// TODO 自动生成 catch ?br /> ex.printStackTrace();
}
//outStream.close();
System.out.println("写入成功Q\n");
}
public void readExc(File filename) throws BiffException, IOException{
Workbook wb = Workbook.getWorkbook(filename);
Sheet s = wb.getSheet(0);//W?个sheet
Cell c = null;
int row = s.getRows();//总行?br /> int col = s.getColumns();//d?br /> for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
c = s.getCell(j,i);
System.out.print(c.getContents()+" ");
}
System.out.println();
}
}
/**
* 讄头的样式
* @return
*/
public static WritableCellFormat getHeader(){
WritableFont font = new WritableFont(WritableFont.TIMES, 24 ,WritableFont.BOLD);//定义字体
try {
font.setColour(Colour.BLUE);//蓝色字体
} catch (WriteException e1) {
// TODO 自动生成 catch ?br /> e1.printStackTrace();
}
WritableCellFormat format = new WritableCellFormat(font);
try {
format.setAlignment(jxl.format.Alignment.CENTRE);//左右居中
format.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
format.setBorder(Border.ALL,BorderLineStyle.THIN,Colour.BLACK);//黑色Ҏ
format.setBackground(Colour.YELLOW);//黄色背景
} catch (WriteException e) {
// TODO 自动生成 catch ?br /> e.printStackTrace();
}
return format;
}
/**
* 讄标题样式
* @return
*/
public static WritableCellFormat getTitle(){
WritableFont font = new WritableFont(WritableFont.TIMES, 14);
try {
font.setColour(Colour.BLUE);//蓝色字体
} catch (WriteException e1) {
// TODO 自动生成 catch ?br /> e1.printStackTrace();
}
WritableCellFormat format = new WritableCellFormat(font);
try {
format.setAlignment(jxl.format.Alignment.CENTRE);
format.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
format.setBorder(Border.ALL,BorderLineStyle.THIN,Colour.BLACK);
} catch (WriteException e) {
// TODO 自动生成 catch ?br /> e.printStackTrace();
}
return format;
}
/**
* 讄其他单元格样?br /> * @return
*/
public static WritableCellFormat getNormolCell(){//12号字?上下左右居中,带黑色边?br /> WritableFont font = new WritableFont(WritableFont.TIMES, 12);
WritableCellFormat format = new WritableCellFormat(font);
try {
format.setAlignment(jxl.format.Alignment.CENTRE);
format.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
format.setBorder(Border.ALL,BorderLineStyle.THIN,Colour.BLACK);
} catch (WriteException e) {
// TODO 自动生成 catch ?br /> e.printStackTrace();
}
return format;
}
public static void main(String[] args) throws IOException, BiffException{
JexcelSample js = new JexcelSample();
File f = new File("D:\\address.xls");
f.createNewFile();
js.writeExc(f);
js.readExc(f);
}
}
生成的excel表格如下Q?br />
import java.io.InputStream;
import java.util.Properties;
/**
*
* CopyRight (C) m.tkk7.com/ilovezmh All rights reserved.<p>
*
* WuHan Inpoint Information Technology Development,Inc.<p>
*
* Author zhu<p>
*
* @version 1.0 2007-2-2
*
* <p>Base on : JDK1.5<p>
*
*/
public class ReadPro {
public String getPara(String fileName) {
Properties prop= new Properties();
try {
//ClassLoader cl = this.getClass().getClassLoader();
//InputStream is = cl.getResourceAsStream(fileName);
InputStream is = this.getClass().getResourceAsStream(fileName);
prop.load(is);
if(is!=null) is.close();
}
catch(Exception e) {
System.out.println(e+"file "+fileName+" not found");
}
return prop.getProperty("ip");
}
public static void main(String[] args) {
ReadPro pro = new ReadPro();
System.out.println(pro.getPara("ip.property"));
}
//-----------------------------------
//ip.property内容如下Q?br />
//ip:192.168.0.1
}
注意Q上面用Class和ClassLoader都是可以的,只是使用的时候\径需要注意下
Class是把class文g所在的目录做ؓ根目录,
ClassLoader是把加蝲所有classpath的目录ؓ根目录,也就?#8220;..../classes”?/p>
如:
使用ClassLoaderQthis.getClass().getClassLoader().getResourceAsStream("com/test/ip.property");
使用ClassQthis.getClass().getResourceAsStream("/com/test/ip.property");
如果cM配置文g在同一目录下,也可
this.getClass().getResourceAsStream("ip.property");
用jdom读xml文g的例子:
(jdom下蝲)
package com.test;
import java.io.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.XMLOutputter;
import org.jdom.output.Format;
/**
*
* CopyRight (C) m.tkk7.com/ilovezmh All rights reserved.<p>
*
* WuHan Inpoint Information Technology Development,Inc.<p>
*
* Author zhu<p>
*
* @version 1.0 2007-2-1
*
* <p>Base on : JDK1.5<p>
*
*/
public class XMLReader {
public void createXML(){
Element root=new Element("books");
Document doc=new Document(root);
Element book1 = new Element("book");
//Element name1=new Element("name");
//name1.setAttribute(new Attribute("hot","true"));
//name1.addContent("E序?);
//Element price1=new Element("price");
//price1.addContent("10.00");
//book1.addContent(name1);
//book1.addContent(price1);
Element book2 = new Element("book");
//Element name2=new Element("name");
//name2.setAttribute(new Attribute("hot","false"));
//name2.addContent("读?);
//Element price2=new Element("price");
//price2.addContent("3.00");
//book2.addContent(name2);
//book2.addContent(price2);
book1.addContent(new Element("name").addContent("E序?).setAttribute("hot","true"));
book1.addContent(new Element("price").addContent("10.00"));
book2.addContent(new Element("name").addContent("青年文摘").setAttribute("hot","false"));
book2.addContent(new Element("price").addContent("3.00"));
root.addContent(book1);
root.addContent(book2);
try
{
XMLOutputter outer=new XMLOutputter(Format.getPrettyFormat().setEncoding("gb2312"));
outer.output(doc,new FileOutputStream("book.xml"));
}catch(IOException e){
e.printStackTrace();
}
}
public void readXML() throws FileNotFoundException, IOException{
Document myDoc=null;
try
{
SAXBuilder sb=new SAXBuilder();
myDoc=sb.build(new FileInputStream("book.xml"));
}catch(JDOMException e){
e.printStackTrace();
}catch(NullPointerException e){
e.printStackTrace();
}
Element root=myDoc.getRootElement(); //先得到根元素
List books=root.getChildren();//root.getChildren("book");
for (Iterator iter1 = books.iterator();iter1.hasNext(); ) {
Element book = (Element) iter1.next();
System.out.println("bookname:"+book.getChild("name").getText());
System.out.println("hot:"+book.getChild("name").getAttributeValue("hot"));
System.out.println("price:"+book.getChild("price").getText());
}
}
public static void main(String args[]) throws FileNotFoundException, IOException {
XMLReader x=new XMLReader();
x.createXML();
x.readXML();
}
}
生成的book.xml文g如下:
<?xml version="1.0" encoding="gb2312"?>
<books>
<book>
<name hot="true">E序?lt;/name>
<price>10.00</price>
</book>
<book>
<name hot="false">青年文摘</name>
<price>3.00</price>
</book>
</books>
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
*
* CopyRight (C) http://m.tkk7.com/ilovezmh All rights reserved.<p>
*
* WuHan Inpoint Information Technology Development,Inc.<p>
*
* Author zhu<p>
*
* @version 1.0 2007-1-17
*
* <p>Base on : JDK1.5<p>
*
*/
public class City {
static String driver1="sun.jdbc.odbc.JdbcOdbcDriver";
static String driver2="net.sourceforge.jtds.jdbc.Driver";
static String url1="jdbc:odbc:driver={Microsoft Access Driver (*.mdb)};DBQ=D:\\TDdownload\\area\\area.mdb";
static String url2="jdbc:jtds:sqlserver://localhost:1433/test;SelectMethod=cursor;characterEncoding=GBK";
public static void main(String arg[]) throws IOException,SQLException{
Connection conn1=null;
Connection conn2=null;
Statement ps1=null;
//Statement ps2=null;
ResultSet rs1=null;
//ResultSet rs2=null;
String sql1=null;
String sql2=null;
PreparedStatement pstmt =null;
try{
Class.forName(driver1);
Class.forName(driver2);
conn1 = DriverManager.getConnection(url1,"","");
conn2= DriverManager.getConnection(url2,"sa","sa");
ps1 = conn1.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
//ps2 = conn2.createStatement();
}
catch(ClassNotFoundException e){
System.out.print(e);
}
catch (SQLException e) {
// TODO 自动生成 catch ?br /> e.printStackTrace();
}
try{
sql1="select * from area";
rs1 = ps1.executeQuery(sql1);
sql2 = "insert into tbcity(code,name,parentid,type) values (?,?,?,?)";
pstmt=conn2.prepareStatement(sql2);
int code=0;
int parentid=0;
String name=new String();
while(rs1.next()){
code=rs1.getInt(2);
name=rs1.getString(3);
parentid=rs1.getInt(4);
//sql2="insert into TBCITY(code,name,parentid,type) values ("+code+",'"+name+"',"+parentid+",3)";
//ps2.executeUpdate(sql2);
pstmt.setInt(1,code);
pstmt.setString(2, name);
pstmt.setInt(3,parentid);
pstmt.setInt(4, 3);
pstmt.addBatch();
}
pstmt.executeBatch();
System.out.println("转换完成!谢谢使用");
ps1.close();
//ps2.close();
pstmt.close();
conn1.close();
conn2.close();
}
catch(Exception e){
System.out.print(e);
}
}
}