jquery.js 很经典,其中有一些设计思路简直非常经典

1.安全的创建一个构造函数并进行调用;

 1  <script>
 2         // 这是一种安全的构造函数的创建方法,在调用构造函数G的时候,不论使用G()进行调用,还是使用new G()进行调用,返回的东西都是相同的
 3         var G = function() {
 4             // 先判定this 是不是G的实例,如果是,则说明this 可以调用G的属性和方法,也可是使用G.prototype 上的属性和方法
 5             if (this instanceof G) {
 6                 return this;
 7             } else {
 8                 // 如果不是G的实例,说明现在的this没有指向G,也就是不能调用G的原型链上的东西,那么在调用的时候,就重新实例化一个G(),这样就可以调用原型链上的东西了
 9                 return new G();
10             }
11         };
12         G.prototype = {
13             length: 123,
14             size: function() {
15                 return this.length;
16             }
17         };
18         // 因为不论使用new G() 还是G()调用构造函数,得到的结果都是一样的,所以以下结果相同;
19         // 最开始都是返回一个构造函数的实例,然后通过原型链,可以调用构造函数的原型对象G.prototype,顺着原型链,可以找到函数的size()方法;
20         console.log(new G().size());
21         console.log(G().size());
22     </script>

 

2. 另一种设计方式,调用构造函数G时,返回G上挂载的对象

 1 <script>
 2         // 设置一个构造函数G,当调用它时,返回挂载在它身上的fn对象
 3         var G = function() {
 4             return G.fn;
 5         };
 6         // 把G上的fn 对象指向G的原型对象,即指向 G.prototype
 7         G.fn = G.prototype = {
 8             length: 12345,
 9             size: function() {
10                 return this.length;
11             }
12         };
13         console.log(G().size());           //12345
14         console.log(new G().size());       //12345
15         console.log(G.prototype.size());   //12345
16 </script>

运行结果:

3. 再进一步,当调用构造函数G时,返回G上的对象fn上的函数 init(),同时把fn对象指向构造函数G的原型对象,即G.prototype

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8 </head>
 9 <body>
10     <script>
11         // 设置一个构造函数G,当调用它时,返回挂载在它身上的fn对象上的 init() 函数
12         var G = function(id) {
13             return G.fn.init(id);
14         };
15         // 把G上的fn 对象指向G的原型对象,即指向 G.prototype
16         G.fn = G.prototype = {
17             length: 12345,
18             size: function() {
19                 return this.length;
20             },
21             init: function(id) {
22                 return document.getElementById(id);
23             }
24         };
25         window.onload = function() {
26             G("box").style.background = 'red';
27             G("box").size();
28         }
29     </script>
30     <div id="box">hello,huanyign2015,这里正在进行测试!</div>
31 </body>
32 </html>

运行结果:

4. 改变this的指向,使this指向G.prototype

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8 </head>
 9 <body>
10     <script>
11         // 设置一个构造函数G,当调用它时,返回挂载在它身上的fn对象上的 init() 函数
12         var G = function(id) {
13             return G.fn.init(id);
14         };
15         // 把G上的fn 对象指向G的原型对象,即指向 G.prototype
16         G.fn = G.prototype = {
17             init: function(id) {
18                 this[0] = document.getElementById(id);
19                 this.length = 1;
20                 return this;
21             },
22             length: 0,
23             size: function() {
24                 return this.length;
25             }
26         };
27         window.onload = function() {
28             G("box")[0].style.background = 'red';
29             G("box2")[0].style.background = '#ccc';
30             console.log(G("box").size());
31             console.log(G("box2"));
32         }
33     </script>
34     <div id="box">第一行,hello,huanyign2015,这里正在进行测试!</div>
35     <div id="box1">第二行,hello,huanyign2015,这里正在进行测试!</div>
36     <div id="box2">第三行,hello,huanyign2015,这里正在进行测试!</div>
37 </body>
38 </html>

运行结果:

5. 当构造函数返回的不是G上的fn对象上的init()函数,而是G上的fn上的init对象的实例的时候,这时就不能调用size()函数了,因为在init()实例的原型链上没有size()函数;

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8 </head>
 9 <body>
10     <script>
11         // 设置一个构造函数G,当调用它时,返回挂载在它身上的fn对象上的 init() 函数对象的实例
12         var G = function(id) {
13             return new G.fn.init(id);
14         };
15         // 把G上的fn 对象指向G的原型对象,即指向 G.prototype
16         G.fn = G.prototype = {
17             init: function(id) {
18                 this[0] = document.getElementById(id);
19                 this.length = 1;
20                 return this;
21             },
22             length: 0,
23             size: function() {
24                 return this.length;
25             }
26         };
27         window.onload = function() {
28             console.log(G("box2"));
29             console.log(G("box").size());
30         }
31     </script>
32     <div id="box">第一行,hello,huanyign2015,这里正在进行测试!</div>
33     <div id="box1">第二行,hello,huanyign2015,这里正在进行测试!</div>
34     <div id="box2">第三行,hello,huanyign2015,这里正在进行测试!</div>
35 </body>
36 </html>

运行结果:

6.解决能够调用size()函数的问题,需要把init的原型对象指向G.prototype 上就可以了;也就是指向G.fn

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8 </head>
 9 <body>
10     <script>
11         // 设置一个构造函数G,当调用它时,返回挂载在它身上的fn对象上的 init() 函数对象的实例
12         var G = function(id) {
13             return new G.fn.init(id);
14         };
15         // 把G上的fn 对象指向G的原型对象,即指向 G.prototype
16         G.fn = G.prototype = {
17             init: function(id) {
18                 this[0] = document.getElementById(id);
19                 this.length = 1;
20                 return this;
21             },
22             length: 0,
23             size: function() {
24                 return this.length;
25             }
26         };
27         // 把G.fn.init对象的实例加载到G.prototype的原型链上来,这样就可以通过原型链调用size()函数了
28         G.fn.init.prototype = G.fn;
29         window.onload = function() {
30             console.log(G("box2"));
31             console.log(G("box").size());
32         }
33     </script>
34     <div id="box">第一行,hello,huanyign2015,这里正在进行测试!</div>
35     <div id="box1">第二行,hello,huanyign2015,这里正在进行测试!</div>
36     <div id="box2">第三行,hello,huanyign2015,这里正在进行测试!</div>
37 </body>
38 </html>

运行结果:

7. 构造一个Id与元素选择器

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <style>
 9         div,
10         p {
11             padding: 3px;
12             margin: 3px;
13             border: 1px solid green;
14         }
15     </style>
16 </head>
17 <body>
18     <script>
19         // 设置一个构造函数G,当调用它时,返回挂载在它身上的fn对象上的 init() 函数对象的实例
20         var G = function(selector, context) {
21             return new G.fn.init(selector, context);
22         };
23         // 把G上的fn 对象指向G的原型对象,即指向 G.prototype
24         G.fn = G.prototype = {
25             constructor: G,
26             init: function(selector, context) {
27                 this.length = 0;
28                 context = context || document;
29                 if (selector.indexOf("#") == 0) { // 说明选择器是Id
30 
31                     this[0] = document.getElementById(selector.substring(1)); // 构造函数上设置数字索引0属性,值为对应的选中Id元素
32                     this.length = 1; // 构造函数上设置一个length属性,值为元1,因为Id只选中一个元素
33 
34                 } else { // 说明是元素选择器, (备注,在这里只设置支持元素选择器和id选择器)
35                     var aNode = context.getElementsByTagName(selector);
36                     for (var i = 0, len = aNode.length; i < len; i++) {
37                         this[i] = aNode[i]; // 构造函数上设置数字索引属性,值为对应的元素
38                     }
39                     this.length = len; // 构造函数上设置一个length属性,值为元素的个数len
40                 };
41                 this.selector = selector; // 构造函数上设置一个selector属性,值为传入的selector
42                 this.context = context; // 构造函数上设置一个selector属性,值为传入的context
43                 return this;
44             },
45             length: 0,
46             size: function() {
47                 return this.length;
48             }
49         };
50         // 把G.fn.init对象的实例加载到G.prototype的原型链上来,这样就可以通过原型链调用size()函数了
51         G.fn.init.prototype = G.fn;
52         window.onload = function() {
53             console.log(G('#box1')[0]);
54             var aP = G('p');
55             for (var i = 0, len = aP.size(); i < len; i++) {
56                 aP[i].style.backgroundColor = 'blue';
57             }
58         }
59     </script>
60     <div id="box">
61         <p>huanying2015,思维改变世界</p>
62         <p>huanying2015,思维改变世界</p>
63         <p>huanying2015,思维改变世界</p>
64         <p>huanying2015,思维改变世界</p>
65         <p>huanying2015,思维改变世界</p>
66         <ul>huanying2015,思维改变世界,这是ul元素</ul>
67         <p>huanying2015,思维改变世界</p>
68         <p>huanying2015,思维改变世界</p>
69         <p>huanying2015,思维改变世界</p>
70     </div>
71     <div id="box1">第二行,hello,huanyign2015,这里正在进行测试!</div>
72     <div id="box2">第三行,hello,huanyign2015,这里正在进行测试!</div>
73 </body>
74 </html>

运行结果:

 

posted on 2018-03-07 19:47  huanying2015  阅读(235)  评论(0编辑  收藏  举报