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将筛选出继承出来的属性,这样就可以避免混用的发生。
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'
经测试能用。
!!!
