高级技巧

1:作用域安全的构造函数

1.1 什么是作用域不安全的构造函数

  构造函数就是一个使用new操作符的函数,使用new操作符时,函数内部的this就指向调用构造函数后产生的实例,一旦你调用构造函数没有使用new,构造函数内部的this就将指向window对象,造成更多意想不到的问题。

正常使用:

 1 function Person(name,age,job)
 2 {
 3     this.name = name;
 4     this.age = age;
 5     this.job = job;
 6 }
 7 
 8 var person = new Person("Tom",29,"SE");
 9 alert(person.name);//Tom
10 alert(person.age);//29
11 alert(person.job);//SE
View Code

错误使用:

 1 function Person(name,age,job)
 2 {
 3     this.name = name;
 4     this.age = age;
 5     this.job = job;
 6 }
 7 
 8 var person = Person("Tom",29,"SE");
 9 alert(window.name);//Tom
10 alert(window.age);//29
11 alert(window.job);//SE
12 alert(person.name);//Error
13 alert(person.age);//Error
14 alert(person.job);//Error
View Code

  为了防止这种错误调用,可以在构造函数内部判断this的指向来进一步完善构造函数。

 1 function Person(name,age,job)
 2 {
 3     if(this instanceof Person)
 4     {
 5         this.name = name;
 6         this.age = age;
 7         this.job = job;        
 8     }
 9     else
10     {
11         return new Person(name,age,job);
12     }
13 }
14 
15 var person = Person("Tom",29,"SE");
16 alert(window.name);//undefined
17 alert(window.age);//undefined
18 alert(window.job);//undefined
19 alert(person.name);//Tom
20 alert(person.age);//29
21 alert(person.job);//SE
View Code

  使用instanceof确保this指向的是Person的实例,无论如何,最后调用构造函数都会使用new操作符。

1.2 作用域安全的构造函数的继承问题

  作用域安全的构造函数实际上锁定了可以调用此构造函数的环境,在使用借用构造函数的方式来继承父类时,如果遇见父类的构造函数是作用域安全的,将会导致继承不到父类。

 1 function Father(name)
 2 {
 3     if(this instanceof Father)
 4     {
 5         this.fatherName = name;
 6         this.firends = ['alex','tom'];    
 7     }
 8     else
 9     {
10         return new Father(name);//将返回一个Father实例
11     }
12 }
13 function Child(name)
14 {
15     Father.call(this,"father1");//这里传入的this指向了Child的实例,获得一个不曾使用的Father实例
16     this.childName = name;
17 }
18 var child1 = new Child("child1");
19 alert(child1.fatherName);//undefined
View Code

  问题关键在于this的指向,联系几种继承方式,原型链继承可以改变this的指向,当用原型链方式继承father时,child中this的指向也可以是father了,所以一综合,就是原来的组合继承方式就可以规避这个问题。

 1 function Father(name)
 2 {
 3     if(this instanceof Father)
 4     {
 5         this.fatherName = name;
 6         this.firends = ['alex','tom'];    
 7     }
 8     else
 9     {
10         return new Father(name);
11     }
12 }
13 function Child(name)
14 {
15     Father.call(this,"father1");
16     this.childName = name;
17 }
18 Child.prototype = new Father("father2");//现在指向Child实例的this也同样指向了Father
19 //father2 被同名属性father1覆盖了
20 var child1 = new Child("child1");
21 alert(child1.fatherName);//father1
View Code

 2:惰性载入函数

  前端总是要判读很多兼容性问题,比如使用Ajax时要创建的XMLHttpRequest对象,各个浏览器之间创建的方式不尽相同,会用到大量try catch语句,很显然,这个判断过程只需要执行一次就可以了,让函数记忆住成功创建的方式,下次使用就会快很多了。

一般方式:

 1 function createRequest()
 2 {
 3     var HttpRequest = null;
 4     try
 5     {
 6         // For Mazilla or Safari or IE7
 7         HttpRequest = new XMLHttpRequest();
 8     }
 9     catch (e)
10     {
11         var XMLHTTPS = new Array( "MSXML2.XMLHTTP.5.0",
12                                     "MSXML2.XMLHTTP.4.0",
13                                     "MSXML2.XMLHTTP.3.0",
14                                     "MSXML2.XMLHTTP",
15                                     "Microsoft.XMLHTTP" );
16         var Success = false;
17         for (var i = 0; i < XMLHTTPS.length && Success == false; i+=1)
18         {
19             try
20             {
21                 HttpRequest = new ActiveXObject(XMLHTTPS[i]);
22                 Success = true;
23             }
24             catch (e) { }
25             if (!Success)
26             {
27                 this.onError("Browser do not support Ajax.");
28             }
29         }
30     }
31     return HttpRequest;
32 }
View Code

惰性载入方式:

 1 function createRequest()
 2 {
 3     var HttpRequest = null;
 4     try
 5     {
 6         // For Mazilla or Safari or IE7
 7         HttpRequest = new XMLHttpRequest();
 8         createRequest = function(){
 9             return XMLHttpRequest();
10         };
11         return HttpRequest;
12     }
13     catch (e)
14     {
15         var XMLHTTPS = new Array( "MSXML2.XMLHTTP.5.0",
16                                     "MSXML2.XMLHTTP.4.0",
17                                     "MSXML2.XMLHTTP.3.0",
18                                     "MSXML2.XMLHTTP",
19                                     "Microsoft.XMLHTTP" );
20         var Success = false;
21         for (var i = 0; i < XMLHTTPS.length && Success == false; i+=1)
22         {
23             try
24             {
25                 HttpRequest = new ActiveXObject(XMLHTTPS[i]);
26                 Success = true;
27                 createRequest = function(){
28                     return new ActiveXObject(XMLHTTPS[i]);
29                 };
30                 return HttpRequest;
31             }
32             catch (e) { }
33             if (!Success)
34             {
35                 this.onError("Browser do not support Ajax.");
36             }
37         }
38     }
39     createRequest = function(){
40         throw new Error("NO XHR object available");
41     };
42     return HttpRequest;
43 }
View Code
原文地址:https://www.cnblogs.com/Flychown/p/6222897.html