javascript语言精粹 笔记一
作者:yaya | 时间:2009年9月15日 | 分类 学海无涯 | 标签 javascript | 1回复
最近在看Douglas Crockford大师的《JavaScript语言精粹》。于是就胡乱记录下自己的一些理解与认识,这其中不免有说得不好甚至错误的地方。但是我相信,随着理解的深入,这些问题会逐渐减少的。
此书主要就JavaScript的精华,鸡肋和糟粕做了详细的分析阐述。将其优雅的地方展现得淋漓尽致,而对于其糟粕,也显示出了其危害性。
JavaScript是基于原型继承的语言。也就是说,对象可以直接从其他对象继承属性。其语言是无类别而言的。除了简单类型(包括数字、字符串、布尔值、null、underfined)外都是对象。其中的函数也是对象。对象就是名称与对应值所组成的集合。每个对象都拥有一个连到原型对象的隐藏连接。
对象字面量(花括号中的名称与其对应值组成对,属性名在编译时候了解到。型如下)产生的对象连接到Object.prototype。函数对象连接到Function.Prototype(其原型对象也是连接到Object.prototype)。每个函数创建的时候,会有两个隐藏属性:函数上下文和实现函数行为的代码。而其中的上下文是很重要的东东,其在函数访问外部函数的实际变量(并且不是复制的)的时候会让人觉得很神奇。一个函数可以访问它被创建时候的上下文环境,当然各种变量也就不再话下。这种情况称之为闭包。有时候函数已经返回了,但是它的变量还会保留,这中情况其实是很常见的。看起来也很帅。很经典的例见下。
-
var empty_object = {};
-
-
var card_object = {
-
"first-name":"yaya",
-
"last-name":"zinkey"
-
};
这个例子目前是当点击一个节点时,弹出一个对话框显示的节点的序号。可是呢。前者并不能达到这样的效果,并且老是得到节点的数目。原因即是绑定的变量i随着循环的递增已经变化成了节点的数目。在函数构造时候,i就等于节点的数目。第一个例子中,我们可以看到的是onclick得到赋值是一个函数,而这个函数是弹出i的对话框。但其本身就可以访问到var i的实际的值(上下文),所以最终得不到预期的效果。而第二个例子呢?我们可以看到,当定义了一个函数,就传递i执行,函数返回的是事件处理函数,其本身是和传递进去的i绑定的。而不是var i。可以看到(i),用()运算符立即调用刚刚构造出来的函数,而这个被调用创建并返回的函数才是给予onclick的处理函数。
-
var add_the_handlers = function (nodes){
-
var i;
-
for (i=0;i<nodes.length;i+=1){
-
nodes[i].onclick = function(e){
-
alert(i);
-
}
-
}
-
};
-
-
//另外一个
-
var add_the_handlers = function (nodes){
-
var i;
-
for (i=0;i<nodes.length;i+=1){
-
nodes[i].onclick = function(i){
-
return function(e){
-
alert(e);
-
};
-
}(i);
-
}
-
};
一下是method定义新方法
-
Function.prototype.method = function (name,func){
-
this.prototype[name] = func;
-
return this;
-
}
以后就直接通过method来定义新的方法。
如:
-
String.method("trim",function(){
-
return this.replace(/^s+|s+$/g,'');
-
});
但是这样来写method,会忽略一个问题:基本类型的原型是公共结构,在类库混用时要考虑其已有方法。
所以,修改method为:
-
Function.prototype.method = function (name,func){
-
if (!this.prototype[name]){
-
this.prototype[name] = func;
-
}
-
};
-
//或者
-
Function.prototype.method = function (name,func){
-
if (!this.prototype.hasOwnProperty[name]){
-
this.prototype[name] = func;
-
}
-
};
hasOwnProperty将筛选出继承出来的属性,这样就可以避免混用的发生。
sort呀
作者:yaya | 时间:2009年9月13日 | 分类 学海无涯 | 标签 quicksort std | 1回复
-
start=clock();
-
std::sort(a,a+MAX);
-
finish=clock();
-
total_time=(double)(finish - start)/CLOCKS_PER_SEC;
-
cout<<"time:"<<total_time<<endl;
当我执行了上面代码后,就被它打败了。我的小Qt好悲剧啊,完全不是对手。改了很久,也是这样。template太可怕了。
有时间一定要再看看研究下。再改!再改!再改!!!
javascript浏览器判断
作者:yaya | 时间:2009年9月12日 | 分类 学海无涯 | 标签 javascript | 1回复
好久没写过学海无涯里面的东西了。开始!
今天上网看到关于javascript判断浏览器的东东,于是就去看了关于它的一些写法。最先就是去李战csdn上看他书的介绍。那说是彩印的,所以当然就贵啦。看封面就很好玩。
他写道了这个东西,就把代码给复制了过来。同时,也贴了些其他的关于判断的代码。
-
var Sys = {};
-
var ua = navigator.userAgent.toLowerCase();
-
var s;
-
(s = ua.match(/msie ([d.]+)/)) ? Sys.ie = s[1] :
-
(s = ua.match(/firefox/([d.]+)/)) ? Sys.firefox = s[1] :
-
(s = ua.match(/chrome/([d.]+)/)) ? Sys.chrome = s[1] :
-
(s = ua.match(/opera.([d.]+)/)) ? Sys.opera = s[1] :
-
(s = ua.match(/version/([d.]+).*safari/)) ? Sys.safari = s[1] : 0;
-
-
//以下进行测试
-
if (Sys.ie) document.write('IE: ' + Sys.ie);
-
if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
-
if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
-
if (Sys.opera) document.write('Opera: ' + Sys.opera);
-
if (Sys.safari) document.write('Safari: ' + Sys.safari);
“以上的代码都是为了打造前端框架所做的预研,并在五大浏览器上测试通过。今后,判断某种浏览器只需用if(Sys.ie)或if(Sys.firefox)等形式,而判断浏览器版本只需用if(Sys.ie == '8.0')或if(Sys.firefox == '3.0')等形式,表达起来还是非常优雅的。”
-
var userAgent = navigator.userAgent.toLowerCase();
-
-
// Figure out what browser is being used
-
jQuery.browser = {
-
version: (userAgent.match( /.+(?:rv|it|ra|ie)[/: ]([d.]+)/ ) || [0,'0'])[1],
-
safari: /webkit/.test( userAgent ),
-
opera: /opera/.test( userAgent ),
-
msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
-
mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
-
};
jquery果然是精悍啊!下面看看yui的。
-
YAHOO.env.ua = function() {
-
var o={
-
-
/**
-
* Internet Explorer version number or 0. Example: 6
-
* @property ie
-
* @type float
-
*/
-
ie:0,
-
-
/**
-
* Opera version number or 0. Example: 9.2
-
* @property opera
-
* @type float
-
*/
-
opera:0,
-
-
/**
-
* Gecko engine revision number. Will evaluate to 1 if Gecko
-
* is detected but the revision could not be found. Other browsers
-
* will be 0. Example: 1.8
-
* <pre>
-
* Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7
-
* Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
-
* Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
-
* Firefox 3 alpha: 1.9a4 <-- Reports 1.9
-
* </pre>
-
* @property gecko
-
* @type float
-
*/
-
gecko:0,
-
-
/**
-
* AppleWebKit version. KHTML browsers that are not WebKit browsers
-
* will evaluate to 1, other browsers 0. Example: 418.9.1
-
* <pre>
-
* Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
-
* latest available for Mac OSX 10.3.
-
* Safari 2.0.2: 416 <-- hasOwnProperty introduced
-
* Safari 2.0.4: 418 <-- preventDefault fixed
-
* Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
-
* different versions of webkit
-
* Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been
-
* updated, but not updated
-
* to the latest patch.
-
* Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native SVG
-
* and many major issues fixed).
-
* 3.x yahoo.com, flickr:422 <-- Safari 3.x hacks the user agent
-
* string when hitting yahoo.com and
-
* flickr.com.
-
* Safari 3.0.4 (523.12):523.12 <-- First Tiger release - automatic update
-
* from 2.x via the 10.4.11 OS patch
-
* Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event.
-
* yahoo.com user agent hack removed.
-
*
-
* </pre>
-
* http://developer.apple.com/internet/safari/uamatrix.html
-
* @property webkit
-
* @type float
-
*/
-
webkit: 0,
-
-
/**
-
* The mobile property will be set to a string containing any relevant
-
* user agent information when a modern mobile browser is detected.
-
* Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
-
* devices with the WebKit-based browser, and Opera Mini.
-
* @property mobile
-
* @type string
-
*/
-
mobile: null,
-
-
/**
-
* Adobe AIR version number or 0. Only populated if webkit is detected.
-
* Example: 1.0
-
* @property air
-
* @type float
-
*/
-
air: 0,
-
-
/**
-
* Google Caja version number or 0.
-
* @property caja
-
* @type float
-
*/
-
caja: 0
-
-
},
-
-
ua = navigator.userAgent,
-
-
m;
-
-
// Modern KHTML browsers should qualify as Safari X-Grade
-
if ((/KHTML/).test(ua)) {
-
o.webkit=1;
-
}
-
// Modern WebKit browsers are at least X-Grade
-
m=ua.match(/AppleWebKit/([^s]*)/);
-
if (m&&m[1]) {
-
o.webkit=parseFloat(m[1]);
-
-
// Mobile browser check
-
if (/ Mobile//.test(ua)) {
-
o.mobile = "Apple"; // iPhone or iPod Touch
-
} else {
-
m=ua.match(/NokiaN[^/]*/);
-
if (m) {
-
o.mobile = m[0]; // Nokia N-series, ex: NokiaN95
-
}
-
}
-
-
m=ua.match(/AdobeAIR/([^s]*)/);
-
if (m) {
-
o.air = m[0]; // Adobe AIR 1.0 or better
-
}
-
-
}
-
-
if (!o.webkit) { // not webkit
-
// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
-
m=ua.match(/Opera[s/]([^s]*)/);
-
if (m&&m[1]) {
-
o.opera=parseFloat(m[1]);
-
m=ua.match(/Opera Mini[^;]*/);
-
if (m) {
-
o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
-
}
-
} else { // not opera or webkit
-
m=ua.match(/MSIEs([^;]*)/);
-
if (m&&m[1]) {
-
o.ie=parseFloat(m[1]);
-
} else { // not opera, webkit, or ie
-
m=ua.match(/Gecko/([^s]*)/);
-
if (m) {
-
o.gecko=1; // Gecko detected, look for revision
-
m=ua.match(/rv:([^s)]*)/);
-
if (m&&m[1]) {
-
o.gecko=parseFloat(m[1]);
-
}
-
}
-
}
-
}
-
}
-
-
m=ua.match(/Caja/([^s]*)/);
-
if (m&&m[1]) {
-
o.caja=parseFloat(m[1]);
-
}
-
-
return o;
-
}();
yui果然很好很强大,判断了N种~~~~~~~
最后来看看baidu自己的框架。bb就是b2b的意思吧。看看。
-
Browser: (function(){
-
var ua = window.navigator.userAgent.toLowerCase();
-
var b = {
-
platform: window.navigator.platform,
-
msie: /msie/.test(ua) && !/opera/.test(ua),
-
opera: /opera/.test(ua),
-
safari: /webkit/.test(ua) && !/chrome/.test(ua),
-
firefox: /firefox/.test(ua),
-
chrome: /chrome/.test(ua)
-
};
-
var vMark = "";
-
for (var i in b) {
-
if (b[i]) {
-
vMark = i;
-
}
-
}
-
if (b.safari) {
-
vMark = "version";
-
}
-
b.version = (ua.match(eval("/(?:" + vMark + ")[\/: ]([\d.]+)/")) || [])[1];
-
b.ie = b.msie;
-
b.ie6 = b.msie && parseInt(b.version) == 6;
-
try {
-
b.maxthon = b.msie && !!external.max_version;
-
}
-
catch (e) {
-
b.maxthon = false;
-
}
-
return b;
-
})()
maxthon也判断了,基于external.max_version来判断。不过搜狗怎么判断呢?当IE7三。
有人说判断还是基于功能好,如同 if(window.XMLHttpRequest) ,但浏览器本来就在发展互相学习。难免功能交叉的时候。
下面是个很BT的判断IE 的东东。比短!
-
/*判断浏览器*/
-
B=(function x(){})[-5]=='x'?'FF3':(function x(){})[-6]=='x'?'FF2':/a/[-1]=='a'?'FF':'v'=='v'?'IE':/a/.__proto__=='//'?'Saf':/s/.test(/a/.toString)?'Chr':/^function (/.test([].sort)?'Op':'Unknown'
-
-
-
/*判断IE 好短!*/
-
IE=top.execScript?1:0
-
-
-
/*判断IE 更短!!!*/
-
IE='\v'=='v'
经测试能用。
!!!
光明正大加分
作者:yaya | 时间:2009年6月11日 | 分类 学海无涯 | 标签 数学 四舍五入 学习 项目 | 3回复
软件管理课上,老师就要每个小组长给自己的小组打分(包括小组长自己)。
我们小组的得分是23分(还算不错),包括组长我在内一共5个同学。
现在有500分(5个人的小组就500分,6个人的小组就600分)。
那么假设我们小组的5个人是A,B,C,D,E,那么如果把这500分平均分给这5个人,那么每个人就得到了100(我们组我是想大家平均分的,有的组是组长和某个人高点或者其他情况)。
这样一来,比如A的最后得分就是:23(小组得分)×100%(白分之A的得分)=23。A的最后得分就是23,其他的成员B,C,D,E也就是23分。

这样我们组的个人总得分就是23+23+23+23+23=115分。
这样看起来好像没什么问题。因为小组得分(我们小组是23分)是固定了的。假设A,B,C,D,E分别得分为XA,XB,XC,XD,XE(得分都只能是整数,比如100分,101分)。
这样,小组的个人总得分就是23×XA%+23×XB%+23×XC%+23×XD%+23×XE%=23×(XA+XB+XC+XD+XE)%=23×500%=115分,这样不是说再怎么来分小组个人总得分都不会有变化吗?(原谅我用了半天来说明这个简单的问题)
但是这个地方有个问题,比如算A的得分等于23×XA%,若有小数怎么办呢?老师给的官方说明是:为了方便统计,遇到有小数点就四舍五入。哈哈,总算看到了提高小组个人总分的曙光了。
想要“五入”上去,就得让小数点后的数大于或者等于5。对于我们组的23分,23×0.02=0.46,23×0.03=0.69,所以3是一个分水岭。再高一些也没用,反正都得一样“五入”上去,而光想加上去的分还不行,加上去的分是其他组员
贡献出来的,得想法让他们不降分,这样总体才会提高。考虑23×0.02=0.46,那么1-0.02=0.08,所以23×0.98四舍五入也会是23。这样就把分给加上去了。那么可以加上去多少分呢?怎么分配呢?2÷5=0.4,3÷5=0.6,可以简单地认为
五个人中有3个人拿出2分来给另外两人(每人得3分)。这拿分出来的三个人因为都拿的2分,计算的时候都会出现23×0.98四舍五入也会是23,而得到3分的成员,因为23×0.03=0.69将“五入”上去,即23×1.03=24。
这样拿分出来的3个人分数不变,另外两个人可以“五入”上去,所以总体可以加上两分。所以可以这样来分配:
| 成员 | 得分比例×500% | 四舍五入后的实际得分 |
| A | 103 | 24 |
| B | 103 | 24 |
| C | 98 | 23 |
| D | 98 | 23 |
| E | 98 | 23 |
| 总共 | 500 | 117 |
这样就把总分提高了2分,并且可以证明,对于我们组,最多就是提高2分了。
设小组得分为S分,小组总共有N个人,其中有X个人可以把分“五入”上去,那么就有L=N-X个人是“五入”后分数不变的。
设V是关于S的可以四舍五入的分水岭数,则有:S×V%≥0.5,V取能满足不等式的最小的整数。即V=50÷S,其中V取四舍五入,且用V=round(50÷S)来表示。
而要使得拿出分的成员也可以“五入”到不变的状态,则Z=V-1,为能够拿出最多而不会改变原来分数的值。
要想加分,其实就是靠“五入”把小数的值加上去成为整数,所以X个人能够就上去的分就是X,这是因为一个人最多就能加上去1分。所以,小组能够加上去的总分J=X。而又有拿出分的分是等于得到分的(如果自己拿出分来加在自己身上等于没用)。
所以,有等式:
V×X=Z×L
=> V×X=(V-1)×(T-X)
=> X=T(V-1)/(2V-1)
=> X=T(round(50/S)-1)/(2round(50/S)-1)
=> J=[T(round(50/S)-1)/(2round(50/S)-1)] (高斯函数取整)
由这个函数及数值范围可知,当T,S固定后,J是固定的。S不变T越大J越大,T不变S越小J越大。
所以我们组T=5,S=23,得到J=2.
再考虑到实际情况T值一般是5~6,S范围是20~24,所以可以各个小组可以提高的个人总得是2分。
然后把表拿给老师,她说你们组的加分有点意思。
嗯,我也觉得有点意思,也算是光明正大的加分吧。
ArrayList赋值
作者:yaya | 时间:2008年12月16日 | 分类 学海无涯 | 标签 .net arraylist 学习 | 0回复
在ArrayList赋值给另一个ArrayList时候,很容易就不小心犯错误,然后在程序中找了半天,最后发现原来是ArrayList赋值的时候出现了错误。
现在,让我们来看看错误的情况。
假设有
ArrayList a= new ArrayList();
ArrayList b= new ArrayList();
a.Add("1");
a.Add("2");
现在要把a赋给b,该怎么做呢?一个简单又不会错的办法就是循环赋值
foreach(Object o in a) { b.Add(o); }
而要是写成
b=a;
就错了,因为其值是引用类型,所以赋值后,即把b的引用地址传给了a,这样的话,其操作的都是同一数据,改变a或者b,都将对数据有相同影响。也就是说,a和b“相同”了。比如b.Add("3"),则a也相当于做了a.Add("3") 所以,是不行了。
其实,还可以写作
a = new ArrayList(b.GetRange(0, b.Count));
GetRange的参数可以选择自己需要的,0和b.Count则复制完所有数据。
