《众妙之门 JavaScript与jQuery技术精粹》 - 读书笔记总结[无章节版][1-60]

近期,反复思考后,还是把所有的笔记通过随笔的方式整理出来放在论坛里,可以让自己对学过的知识有个比较系统而清晰的呈现;

同时,为以后用到相关的知识点做一个整理和查阅。

 

(一)JSON-P 的实例代码展示

 1 <div id="delicious"></div>
 2 <script type="text/javascript">
 3     // 可以在JavaScript中直接使用JSON,并且封装在函数调用中时,可作为API的返回值。
 4     // 这称为JSON-P格式,被很多API函数支持。可以使用数据端点在脚本语句中直接返回JSON-P格式。
 5     function delicious(o){
 6         var out = "<ul>";
 7         for(var i=0; i<o.length; i++){
 8             out += '<li><a href="' + o[i].u + '">' + o[i].d + '</a></li>';
 9         }
10         out += '</ul>';
11         document.getElementById('delicious').innerHTML = out;
12     }
13     // 这里调用了delicious Web服务来获得最新的JavaScript书签(JSON格式),然后将其显示为无序列表。
14     // 其实,JSON可能是在浏览器运行中描述复杂数据最轻松的方式了,甚至可以再PHP中调用json_decode()函数。
15 </script>
16 <script src="http://feeds.delicious.com/v2/json/codepo8/javascript?count=15&callback=delicious"></script>

 

(二)找出一组数字中的最大数

 1 <script type="text/javascript">
 2     var number = [3,342,23,22,124];
 3     var max = 0;
 4     for(var i=0; i<number.length; i++){
 5         if(number[i] > max){
 6             max = number[i];
 7         }
 8     }
 9     alert(max);
10 </script>
11 
12 <!--可以不通过循环而这样实现-->
13 <script type="text/javascript">
14     var number = [3,342,23,22,124];
15     number.sort(function(a,b){return b - a });
16     alert(number[0]);
17 </script>
18 
19 <!--可以利用Math.max()函数,返回一列参数中的最大值-->
20 <script type="text/javascript">
21     alert(Math.max(3,342,23,22,124));
22 </script>

 

(三)利用Math.max()函数解决IE一个小问题

1 <script type="text/javascript">
2     var scrollTop = Math.max(
3         document.documentElement.scrollTop,
4         document.body.scrollTop
5     );
6     alert(scrollTop);
7     // 测试浏览器支持的默认属性。只有一个属性有返回值,另一个将是未定义。
8 </script>

 

(四)利用一个函数将CSS类添加到元素中

 1 <div id="div" class="box"></div>
 2 <input type="button" value="addclass"/>
 3 <script type="text/javascript">
 4     // 经典实例:利用字符串的split()和join()函数,编写addClass()函数。
 5     function addClass(elm, newclass){
 6         var c = elm.className;
 7         elm.className = (c === '') ? newclass : c + ' ' + newclass;
 8     }
 9     // 问题是,当需要在DOM元素中添加一个类时,要么是将它作为第一个类添加,要么是将它和一个空格键一起加在已经存在的类前面。
10     // 当删除该类时,也需要删除相应的空格(这在过去更为重要,因为有些浏览器会因为多余的空格报错)。
11     var button = document.getElementsByTagName('input')[0];
12     var div = document.getElementById('div');
13     button.onclick = function(){
14         addClass(div, 'box2');
15     }
16     // 这个方法的缺点:无法只能判断是否已有新的class类,只会无限制的添加。
17 </script>
18 <script type="text/javascript">
19     function addClass(elm, newclass){
20         // 把字符串转成数组
21         var classes = elm.className.split(' '); 
22         classes.push(newclass);
23         // 把数组转成字符串
24         elm.className = classes.join(' ');
25     }
26     var button = document.getElementsByTagName('input')[0];
27     var div = document.getElementById('div');
28     button.onclick = function(){
29         addClass(div, 'box2');
30     }
31 </script>

 

(五)事件代理描述

 1 <h2>Great Web resources</h2>
 2 <ul id="resources">
 3     <li><a href="http://opera.com/wsc">opera web standards curriculum</a></li>
 4     <li><a href="http://sitepoint.com">sitepoint</a></li>
 5     <li><a href="http://alistapart.com">A list Apart</a></li>
 6     <li><a href="http://yuiblog.com">YUI Blog</a></li>
 7     <li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li>
 8     <li><a href="http://oddlyspecific.com">Oddly specific</a></li>
 9 </ul>
10 <script type="text/javascript">
11     // 通常事件处理程序是在整个链接中使用循环:
12     (function(){
13         var resources = document.getElementById('resources');
14         var links = resources.getElementsByTagName('a');
15         var all = links.length;
16         for(var i=0; i<all; i++){
17             // Attach a listener to each link
18             links[i].addEventListener('click',handler,false);
19         }
20         function handler(e){
21             var x = e.target;    // get the link that was clicked
22             alert(x);
23             e.preventDefault();
24         }
25     })();
26 </script>
27 
28 <script type="text/javascript">
29     // 也可以通过一个事件处理程序来实现:利用了事件冒泡机制
30     (function(){
31         var resources = document.getElementById('resources');
32         resources.addEventListener('click',handler,false);
33         function handler(e){
34             var x = e.target;
35             if(x.nodeName.toLowerCase() === 'a'){
36                 alert('Event delegation: ' + x);
37                 e.preventDefault();
38             }
39         }
40     })();
41 </script>
42 <script type="text/javascript">
43     // 说明:以上例子在IE6浏览器中会运行失败。对于IE6,需要使用事件模型而不是W3C,这就是我们在这种情况下使用库的原因。
44     // 这种方法的好处在于,可以使用单独的事件处理程序。例如,想要在列表中动态地进行添加操作,如果使用事件代理(即事件冒泡到父级),
45     // 则不需要进行任何改变,只需要在事件处理过程中重新分配处理程序,并对列表重新进行循环操作就可以了。
46 </script>

 

(六)匿名函数和模块模式

 1 <script type="text/javascript">
 2     // JavaScript最令人烦恼的事情是变量的范围没有定义。任何在函数外定义的变量、函数、数组和对象都是全局的,这意味着相同页中的其他脚本都可以进行调用,因而经常出现参数被覆盖现象。
 3     // 解决办法就是将变量封装在一个匿名函数中,在定义完函数后立即调用。
 4 </script>
 5 
 6 <script type="text/javascript">
 7     // 1.先来生成3个全局变量和2个全局函数
 8     var name = 'Chris';
 9     var age = '34';
10     var status = 'single';
11     function createMember(){
12         // [...]
13     }
14     function getMemberDetails(){
15         // [...]
16     }
17     // 该页中其他的脚本如果含有名为status的变量的话就会出问题。如果将它们封装在名为myApplication的匿名函数中,就可以解决这个问题了。但是这样定义使得参数在函数外不起作用,如果这正是所需要的,没有问题。
18     var myApplication = function(){
19         var name = 'Chris';
20         var age = '34';
21         var status = 'single';
22         function createMember(){
23             // [...]
24         }
25         function getMemberDetails(){
26             // [...]
27         }
28     }();
29     // 另外,可以省略定义的名字:
30     (function(){
31         var name = 'Chris';
32         var age = '34';
33         var status = 'single';
34         function createMember(){
35             // [...]
36         }
37         function getMemberDetails(){
38             // [...]
39         }
40     })();
41 </script>
42 
43 <script type="text/javascript">
44     // 2.如果需要部分变量或函数可被外部调用,则需要这样改写程序,为了可以调用createMember()或getMemberDetails()函数,将它们作为myApplication的属性返回:
45     var myApplication = function(){
46         var name = 'Chris';
47         var age = '34';
48         var status = 'single';
49         return {
50             function createMember(){
51                 // [...]
52             },
53             function getMemberDetails(){
54                 // [...]
55             } 
56         }
57     }();
58     // myApplication.createMember() and myApplication.getMemberDetails() now works.
59     // 这种用法被称为模块模式或单例模式。Yahoo用户接口函数库YUI中经常使用它。
60     // 如果要从一个方法中调用另一个方法,还必须在调用时加上myApplication前缀,因此,我更倾向于返回这些我想要其成为全局元素的元素的指针,这样还可以缩短外部调用时的使用长度。
61 </script>
62 
63 <script type="text/javascript">
64     // 我将这种方法称为 “揭示模块模式”。
65     var myApplication = function(){
66         var name = 'Chris';
67         var age = '34';
68         var status = 'single';
69         function createMember(){
70             // [...]
71         },
72         function getMemberDetails(){
73             // [...]
74         } 
75         return {
76             create: createMember,
77             get: getMemberDetails
78         }
79     }();
80     // myApplication.create() and myApplication.get() now work.
81 </script>

 

(七)跨浏览器的事件监听器方法

 1 <!--Stoyan Stefanov 的添加和删除跨浏览器的事件监听器方法-->
 2 <!--作者在他的《JavaScript Patterns》一书中有介绍-->
 3 <script type="text/javascript">
 4     // utils:实用工具
 5     var utils = {    
 6         addListener: null,
 7         removeListener: null
 8     };
 9     // the implementation
10     if(typeof window.addEventListener === 'function'){
11         utils.addListener = function(el, type, fn){
12             el.addEventListener(type, fn, false);
13         };
14         utils.removeListener = function(el, type, fn){
15             el.removeEventListener(type, fn, false);
16         };
17     } else if (typeof document.attachEvent === 'function'){
18         utils.addListener = function(el, type, fn){
19             el.attachEvent('on' + type, fn);
20         }
21     }
22 </script>

 

(八)数组长度缓存的重要性

 1 <script type="text/javascript">
 2     // 数组长度缓存的重要性!!!
 3     for(var i=0; i<myArray.length; i++){
 4         /* do stuff */
 5     }
 6     // 对长度进行缓存可以比反复访问它快上190倍。-Nicholas C.Zakas
 7 </script>
 8 
 9 <script type="text/javascript">
10     // 以下是对数组长度进行缓存的一些方法:
11     /* cached outside loop */
12     var len = myArray.length;
13     for(var i=0; i<len; i++){
14 
15     }
16 
17     /* cached inside loop */
18     for(var i=0, len=myArray.length; i<len; i++){
19 
20     }
21 
22     /* cached outside loop using while */
23     var len = myArray.lenght;
24     while(len--){
25         
26     }
27 </script>

 

(九)JSON.stringify()把对象转换成JSON字符串

 1 <!--
 2     JSON.parse()          把严格的json字符串,转换成对象
 3     JSON.stringify()      把对象转换成json字符串
 4 -->
 5 <script type="text/javascript">
 6     var myDate = {};
 7     myDate.dataA = ['a', 'b', 'c', 'd'];
 8     myDate.dataB = {
 9         'animal': 'cat',
10         'color': 'brown'
11     };
12     myDate.dataC = {
13         'vehicles': [{
14             'type': 'ford',
15             'tint': 'silver',
16             'year': '2015'
17         },{
18             'type': 'honda',
19             'tint': 'black',
20             'year': '2012'
21         }]
22     };
23     myDate.dataD = {
24         'buildings':[{
25             'houses':[{
26                 'streetName': 'sycamore close',
27                 'number': '252'
28             },{
29                 'streetName': 'slimdon close',
30                 'number': '101'
31             }]
32         }]
33     };
34     console.log(myDate);    // Object
35     var jsonDate = JSON.stringify(myDate,null,4);
36     console.log(jsonDate);
37     // 额外的调试小技巧,如果你想要使得终端控制台显示的JSON更为美观可读,可以使用stringify()函数的以下额外参数实现:
38     console.log(
39         JSON.stringify({
40             'foo': "hello", 
41             'bar': "world"
42         },null,4)
43     );
44 </script>

 

(十)针对命名空间变量存在性的检查

 1 <script type="text/javascript">
 2     // 针对命名空间变量存在性的检查:
 3     /* 无效检查 */
 4     if( !MyNamespace ){
 5         MyNamespace = {};    // 如果MyNamespace变量之前未经声明,那么!MyNamespace会报错:RefernceError.
 6     }
 7     /* 有效方式 */
 8     if( !MyNamespace ){
 9         var MyNamespace = {};
10     }
11     // or 
12     var MyNamespace = MyNamespace || {};
13     // or
14     if( typeof MyNamespace == 'undefined'){
15         var MyNamespace = {};
16     }
17 </script>

 

(十一)关于JavaScript的十个古怪之处和秘密

 1 <script type="text/javascript">
 2     // 1.Null 是一个对象
 3     alert(typeof null);    // object
 4     alert(null instanceof Object);    //false
 5 </script>
 6 
 7 <script type="text/javascript">
 8     // 2.NaN 是一个数字,并且NaN不等于自身
 9     alert(typeof NaN);    // number
10     alert(NaN === NaN);    //false
11 </script>
12 
13 <script type="text/javascript">
14     // 3.空数组 == false
15     alert(new Array() == false);    // true
16     // 空数组非常奇特:它们实际上等于true,但是在和布尔值比较时,却被看做false
17     var someVar = [];    // empty array
18     alert(someVar == false);    // true
19     if(someVar){ alert('hello') };        // alert runs
20     // 为了避免强制类型转换,我们使用值、类型比较符 "==="
21     var someVar = 0;
22     alert(someVar == false);    // true
23     alert(someVar === false);    // false zero is a number, not a boolean
24     // 如果你想更深入地了解JavaScript比较两个数值的内部原理的话,请查看文件说明书 ECMA-262 的11.9.2节。
25 </script>
26 
27 <script type="text/javascript">
28     // 4.正则表达式replace()函数可以接受回调函数
29     alert('10 13 21 49 32'.replace(/d+/g,'*'));        // replace all numbers with *
30     // 如果我们想要控制只替换30以下的数,怎么做 ?
31     alert('10 13 21 49 32'.replace(/d+/g,function(){
32         return parseInt(match) < 30 ? '*' : match;
33     }));
34 </script>
35 
36 <script type="text/javascript">
37     // 5.正则表达式不仅仅是比较和替换
38     // test()函数比较有趣,它和比较工作方式相同但它并不返回比较值:它只确认类型是否匹配,这样会使计算更轻便。
39     alert(/w{3,}/.test('Hello'));    // false
40     // 动态模式
41     function findWord(word, string){
42         var instanceOfWord = string.match(new RegExp('\b'+word+'\b', 'ig'));
43         alert(instanceOfWord);
44     }
45     findWord('car', 'Carl went to buy a car but had forgotten his credit card.');
46 </script>
47 
48 <script type="text/javascript">
49     // 6.你可以伪造范围
50     var animal = 'dog';
51     function getAnimal(adjective){
52         alert(adjective +' '+ this.animal);
53     }
54     getAnimal('lovely');    // lovely dog
55     
56     var myObj = {animal: 'camel'};
57     getAnimal.call(myObj, 'lovely');    // lovely camel
58 </script>
59 
60 <script type="text/javascript">
61     // 7.函数可以执行自身
62     (function(){
63         alert('hello');
64     })();
65 
66     var someVar = 'hello';
67     setTimeout(function(){ alert(someVar); }, 1000);    // goodbye
68     var someVar = 'goodbye';
69 
70     var someVar = 'hello';
71     setTimeout((function(someVar){
72         return function(){ alert(someVar); }    // hello
73     })(someVar),1000);
74     var someVar = 'goodbye';
75 </script>
76 
77 <script type="text/javascript">
78     // 8.火狐读取和返回RGB格式,而不是十六进制
79     var ie = navigator.appVersion.indexOf('MSIE') != '-1';
80     var t = document.getElementsByTagName('title')[0];
81     alert(ie ? t.currentStyle.color : getComputedStyle(t,null).color);
82 </script>
83 
84 <script type="text/javascript">
85     // 9.    0.1 + 0.2 !== 0.3
86     // 这类问题涉及机器精读的概念
87 </script>
88 
89 <script type="text/javascript">
90     // 10.未定义可以被定义
91     var someVar;
92     alert(someVar == undefined);    // true
93 </script>

 

posted @ 2016-05-16 19:44  _yh  阅读(338)  评论(0编辑  收藏  举报