javascript语言精粹 笔记一

作者:yaya | 时间:2009年9月15日 | 分类 学海无涯 | 标签 javascript | 1回复

最近在看Douglas Crockford大师的《JavaScript语言精粹》。于是就胡乱记录下自己的一些理解与认识,这其中不免有说得不好甚至错误的地方。但是我相信,随着理解的深入,这些问题会逐渐减少的。

此书主要就JavaScript的精华,鸡肋和糟粕做了详细的分析阐述。将其优雅的地方展现得淋漓尽致,而对于其糟粕,也显示出了其危害性。

JavaScript是基于原型继承的语言。也就是说,对象可以直接从其他对象继承属性。其语言是无类别而言的。除了简单类型(包括数字、字符串、布尔值、null、underfined)外都是对象。其中的函数也是对象。对象就是名称与对应值所组成的集合。每个对象都拥有一个连到原型对象的隐藏连接。
 对象字面量(花括号中的名称与其对应值组成对,属性名在编译时候了解到。型如下)产生的对象连接到Object.prototype。函数对象连接到Function.Prototype(其原型对象也是连接到Object.prototype)。每个函数创建的时候,会有两个隐藏属性:函数上下文和实现函数行为的代码。而其中的上下文是很重要的东东,其在函数访问外部函数的实际变量(并且不是复制的)的时候会让人觉得很神奇。一个函数可以访问它被创建时候的上下文环境,当然各种变量也就不再话下。这种情况称之为闭包。有时候函数已经返回了,但是它的变量还会保留,这中情况其实是很常见的。看起来也很帅。很经典的例见下。

对象字面量
  1. var empty_object = {};
  2.  
  3. var card_object = {
  4.    "first-name":"yaya",
  5.    "last-name":"zinkey"
  6. };

 
这个例子目前是当点击一个节点时,弹出一个对话框显示的节点的序号。可是呢。前者并不能达到这样的效果,并且老是得到节点的数目。原因即是绑定的变量i随着循环的递增已经变化成了节点的数目。在函数构造时候,i就等于节点的数目。第一个例子中,我们可以看到的是onclick得到赋值是一个函数,而这个函数是弹出i的对话框。但其本身就可以访问到var i的实际的值(上下文),所以最终得不到预期的效果。而第二个例子呢?我们可以看到,当定义了一个函数,就传递i执行,函数返回的是事件处理函数,其本身是和传递进去的i绑定的。而不是var i。可以看到(i),用()运算符立即调用刚刚构造出来的函数,而这个被调用创建并返回的函数才是给予onclick的处理函数。

很经典的例子
  1. var add_the_handlers = function (nodes){
  2.    var i;
  3.    for (i=0;i<nodes.length;i+=1){
  4.      nodes[i].onclick = function(e){
  5.       alert(i);
  6.      }
  7.    }
  8. };
  9.  
  10. //另外一个
  11. var add_the_handlers = function (nodes){
  12.    var i;
  13.    for (i=0;i<nodes.length;i+=1){
  14.      nodes[i].onclick = function(i){
  15.         return function(e){
  16.           alert(e);
  17.         };
  18.      }(i);
  19.    }
  20. };

一下是method定义新方法

用method方法定义新方法
  1. Function.prototype.method = function (name,func){
  2.    this.prototype[name] = func;
  3.    return this;
  4. }

以后就直接通过method来定义新的方法。

如:

trim
  1. String.method("trim",function(){
  2.    return this.replace(/^s+|s+$/g,'');
  3. });

但是这样来写method,会忽略一个问题:基本类型的原型是公共结构,在类库混用时要考虑其已有方法。
所以,修改method为: 

新method
  1. Function.prototype.method = function (name,func){
  2.    if (!this.prototype[name]){
  3.       this.prototype[name] = func;
  4.     }
  5. };
  6. //或者
  7. Function.prototype.method = function (name,func){
  8.    if (!this.prototype.hasOwnProperty[name]){
  9.       this.prototype[name] = func;
  10.     }
  11. };

hasOwnProperty将筛选出继承出来的属性,这样就可以避免混用的发生。

 

sort呀

作者:yaya | 时间:2009年9月13日 | 分类 学海无涯 | 标签 quicksort std | 1回复

 

std::sort
  1.     start=clock();  
  2.     std::sort(a,a+MAX);
  3.     finish=clock();  
  4.     total_time=(double)(finish - start)/CLOCKS_PER_SEC;
  5.     cout<<"time:"<<total_time<<endl;  

当我执行了上面代码后,就被它打败了。我的小Qt好悲剧啊,完全不是对手。改了很久,也是这样。template太可怕了。

有时间一定要再看看研究下。再改!再改!再改!!!

javascript浏览器判断

作者:yaya | 时间:2009年9月12日 | 分类 学海无涯 | 标签 javascript | 1回复

 好久没写过学海无涯里面的东西了。开始!

今天上网看到关于javascript判断浏览器的东东,于是就去看了关于它的一些写法。最先就是去李战csdn上看他书的介绍。那说是彩印的,所以当然就贵啦。看封面就很好玩。



他写道了这个东西,就把代码给复制了过来。同时,也贴了些其他的关于判断的代码。

李战代码
  1.         var Sys = {};
  2.         var ua = navigator.userAgent.toLowerCase();
  3.         var s;
  4.         (s = ua.match(/msie ([d.]+)/)) ? Sys.ie = s[1] :
  5.         (s = ua.match(/firefox/([d.]+)/)) ? Sys.firefox = s[1] :
  6.         (s = ua.match(/chrome/([d.]+)/)) ? Sys.chrome = s[1] :
  7.         (s = ua.match(/opera.([d.]+)/)) ? Sys.opera = s[1] :
  8.         (s = ua.match(/version/([d.]+).*safari/)) ? Sys.safari = s[1] : 0;
  9.  
  10.         //以下进行测试
  11.         if (Sys.ie) document.write('IE: ' + Sys.ie);
  12.         if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
  13.         if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
  14.         if (Sys.opera) document.write('Opera: ' + Sys.opera);
  15.         if (Sys.safari) document.write('Safari: ' + Sys.safari);

 以上的代码都是为了打造前端框架所做的预研,并在五大浏览器上测试通过。今后,判断某种浏览器只需用if(Sys.ie)或if(Sys.firefox)等形式,而判断浏览器版本只需用if(Sys.ie == '8.0')或if(Sys.firefox == '3.0')等形式,表达起来还是非常优雅的。

jquery
  1. var userAgent = navigator.userAgent.toLowerCase();
  2.  
  3. // Figure out what browser is being used
  4. jQuery.browser = {
  5.     version: (userAgent.match( /.+(?:rv|it|ra|ie)[/: ]([d.]+)/ ) || [0,'0'])[1],
  6.     safari: /webkit/.test( userAgent ),
  7.     opera: /opera/.test( userAgent ),
  8.     msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
  9.     mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
  10. };

jquery果然是精悍啊!下面看看yui的。

yui
  1. YAHOO.env.ua = function() {
  2.     var o={
  3.  
  4.         /**
  5.          * Internet Explorer version number or 0.  Example: 6
  6.          * @property ie
  7.          * @type float
  8.          */
  9.         ie:0,
  10.  
  11.         /**
  12.          * Opera version number or 0.  Example: 9.2
  13.          * @property opera
  14.          * @type float
  15.          */
  16.         opera:0,
  17.  
  18.         /**
  19.          * Gecko engine revision number.  Will evaluate to 1 if Gecko
  20.          * is detected but the revision could not be found. Other browsers
  21.          * will be 0.  Example: 1.8
  22.          * <pre>
  23.          * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
  24.          * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
  25.          * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
  26.          * Firefox 3 alpha: 1.9a4   <-- Reports 1.9
  27.          * </pre>
  28.          * @property gecko
  29.          * @type float
  30.          */
  31.         gecko:0,
  32.  
  33.         /**
  34.          * AppleWebKit version.  KHTML browsers that are not WebKit browsers
  35.          * will evaluate to 1, other browsers 0.  Example: 418.9.1
  36.          * <pre>
  37.          * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
  38.          *                                   latest available for Mac OSX 10.3.
  39.          * Safari 2.0.2:         416     <-- hasOwnProperty introduced
  40.          * Safari 2.0.4:         418     <-- preventDefault fixed
  41.          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
  42.          *                                   different versions of webkit
  43.          * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
  44.          *                                   updated, but not updated
  45.          *                                   to the latest patch.
  46.          * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
  47.          *                                   and many major issues fixed).  
  48.          * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
  49.          *                                   string when hitting yahoo.com and
  50.          *                                   flickr.com.
  51.          * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
  52.          *                                   from 2.x via the 10.4.11 OS patch
  53.          * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
  54.          *                                   yahoo.com user agent hack removed.
  55.          *                                  
  56.          * </pre>
  57.          * http://developer.apple.com/internet/safari/uamatrix.html
  58.          * @property webkit
  59.          * @type float
  60.          */
  61.         webkit: 0,
  62.  
  63.         /**
  64.          * The mobile property will be set to a string containing any relevant
  65.          * user agent information when a modern mobile browser is detected.
  66.          * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
  67.          * devices with the WebKit-based browser, and Opera Mini.  
  68.          * @property mobile
  69.          * @type string
  70.          */
  71.         mobile: null,
  72.  
  73.         /**
  74.          * Adobe AIR version number or 0.  Only populated if webkit is detected.
  75.          * Example: 1.0
  76.          * @property air
  77.          * @type float
  78.          */
  79.         air: 0,
  80.  
  81.         /**
  82.          * Google Caja version number or 0.
  83.          * @property caja
  84.          * @type float
  85.          */
  86.         caja: 0
  87.  
  88.     },
  89.  
  90.     ua = navigator.userAgent,
  91.    
  92.     m;
  93.  
  94.     // Modern KHTML browsers should qualify as Safari X-Grade
  95.     if ((/KHTML/).test(ua)) {
  96.         o.webkit=1;
  97.     }
  98.     // Modern WebKit browsers are at least X-Grade
  99.     m=ua.match(/AppleWebKit/([^s]*)/);
  100.     if (m&&m[1]) {
  101.         o.webkit=parseFloat(m[1]);
  102.  
  103.         // Mobile browser check
  104.         if (/ Mobile//.test(ua)) {
  105.             o.mobile = "Apple"; // iPhone or iPod Touch
  106.         } else {
  107.             m=ua.match(/NokiaN[^/]*/);
  108.             if (m) {
  109.                 o.mobile = m[0]; // Nokia N-series, ex: NokiaN95
  110.             }
  111.         }
  112.  
  113.         m=ua.match(/AdobeAIR/([^s]*)/);
  114.         if (m) {
  115.             o.air = m[0]; // Adobe AIR 1.0 or better
  116.         }
  117.  
  118.     }
  119.  
  120.     if (!o.webkit) { // not webkit
  121.         // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
  122.         m=ua.match(/Opera[s/]([^s]*)/);
  123.         if (m&&m[1]) {
  124.             o.opera=parseFloat(m[1]);
  125.             m=ua.match(/Opera Mini[^;]*/);
  126.             if (m) {
  127.                 o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
  128.             }
  129.         } else { // not opera or webkit
  130.             m=ua.match(/MSIEs([^;]*)/);
  131.             if (m&&m[1]) {
  132.                 o.ie=parseFloat(m[1]);
  133.             } else { // not opera, webkit, or ie
  134.                 m=ua.match(/Gecko/([^s]*)/);
  135.                 if (m) {
  136.                     o.gecko=1; // Gecko detected, look for revision
  137.                     m=ua.match(/rv:([^s)]*)/);
  138.                     if (m&&m[1]) {
  139.                         o.gecko=parseFloat(m[1]);
  140.                     }
  141.                 }
  142.             }
  143.         }
  144.     }
  145.  
  146.     m=ua.match(/Caja/([^s]*)/);
  147.     if (m&&m[1]) {
  148.         o.caja=parseFloat(m[1]);
  149.     }
  150.    
  151.     return o;
  152. }();

yui果然很好很强大,判断了N种~~~~~~~

最后来看看baidu自己的框架。bb就是b2b的意思吧。看看。

baidu BB框架
  1.     Browser: (function(){
  2.         var ua = window.navigator.userAgent.toLowerCase();
  3.         var b = {
  4.             platform: window.navigator.platform,
  5.             msie: /msie/.test(ua) && !/opera/.test(ua),
  6.             opera: /opera/.test(ua),
  7.             safari: /webkit/.test(ua) && !/chrome/.test(ua),
  8.             firefox: /firefox/.test(ua),
  9.             chrome: /chrome/.test(ua)
  10.         };
  11.         var vMark = "";
  12.         for (var i in b) {
  13.             if (b[i]) {
  14.                 vMark = i;
  15.             }
  16.         }
  17.         if (b.safari) {
  18.             vMark = "version";
  19.         }
  20.         b.version = (ua.match(eval("/(?:" + vMark + ")[\/: ]([\d.]+)/")) || [])[1];
  21.         b.ie = b.msie;
  22.         b.ie6 = b.msie && parseInt(b.version) == 6;
  23.         try {
  24.             b.maxthon = b.msie && !!external.max_version;
  25.         }
  26.         catch (e) {
  27.             b.maxthon = false;
  28.         }
  29.         return b;
  30.     })()

maxthon也判断了,基于external.max_version来判断。不过搜狗怎么判断呢?当IE7三。

有人说判断还是基于功能好,如同 if(window.XMLHttpRequest) ,但浏览器本来就在发展互相学习。难免功能交叉的时候。

下面是个很BT的判断IE 的东东。比短!

无敌短啊
  1. /*判断浏览器*/
  2. 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'
  3.  
  4.  
  5. /*判断IE 好短!*/
  6. IE=top.execScript?1:0
  7.  
  8.  
  9. /*判断IE 更短!!!*/  
  10. 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则复制完所有数据。

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. ...
  8. 12