学习第十三天(2019-11-26)
Posted xiaoxb17
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习第十三天(2019-11-26)相关的知识,希望对你有一定的参考价值。
第二十二章 高级技巧
一、高级函数
1、安全的类型检测
1 function isArray(value){ 2 return Object.prototype.toString.call(value) == "[object Array]"; 3 }
也可以基于这一思路测试某个值是不是原生函数或正则表达式:(这一技巧广泛用来检测原生JSON对象)
1 //判断是否原生函数 2 function isFunction(value){ 3 return Object.prototype.toString.call(value) == "[object Function]"; 4 } 5 //判断是否原生函数 6 function isFunction(value){ 7 return Object.prototype.toString.call(value) == "[object RegExp]"; 8 }
1 function Person(name,age,job){ 2 if(this instanceof Person){ //判断this是否是正确的类型 3 this.name = name; 4 this.age = age; 5 this.job = job; 6 }else{ 7 return new Person(name,age,job); 8 } 9 } 10 11 var per1 = Person("Nicholas",29,"Software Engineer"); 12 alert(window.name); //"" 13 alert(per1.name); //"Nicholas" 14 15 var per2 = new Person("Shelby",34,"Ergonomist"); 16 alert(per2.name); //"Shelby"
多个程序员在一个页面上写javascript代码的环境中,推荐使用作用域安全的构造函数作为最佳实践。
3、惰性载入函数
对于多分支的if语句,有些时候并不需要每次都查询if语句,对于此情况,引入了惰性载入技巧,惰性载入表示函数分支只会执行一次,有两种方法可以实行该技巧:
方法1、在函数被调用时处理函数,在第一次调用时该函数会被覆盖为另一个按合适方式执行的函数。
1 function createXHR(){ 2 if(typeof XMLHttpRequest != "undefined"){ 3 createXHR = function(){ //将原函数覆盖 4 return new XMLHttpRequest(); 5 }; 6 }else if(typeof ActiveXObject != "undefined"){ 7 createXHR = function(){ //将原函数覆盖 8 if(typeof arguments.callee.activeXString != "string"){ 9 var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len; 10 for(i=0,len=versions.length;i < len;i++){ 11 try{ 12 new ActiveXObject(versions[i]); 13 arguments.callee.activeXString = versions[i]; 14 break; 15 }catch(ex){ 16 //跳过 17 } 18 } 19 } 20 return new ActiveXObject(arguments.callee.activeXString); 21 }; 22 }else{ 23 createXHR = function(){ //将原函数覆盖 24 throw new Error("No XHR object available."); 25 }; 26 } 27 return createXHR(); 28 }
方法2、在声明函数时指定适当的函数,这样第一次调用函数不损失性能,在代码首次加载时会损失性能
1 var createXHR = (function(){ 2 if(typeof XMLHttpRequest != "undefined"){ 3 return function(){ 4 return new XMLHttpRequest(); 5 }; 6 }else if(typeof ActiveXObject != "undefined"){ 7 return function(){ 8 if(typeof arguments.callee.activeXString != "string"){ 9 var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len; 10 for(i=0,len=versions.length;i < len;i++){ 11 try{ 12 new ActiveXObject(versions[i]); 13 arguments.callee.activeXString = versions[i]; 14 break; 15 }catch(ex){ 16 //跳过 17 } 18 } 19 } 20 return new ActiveXObject(arguments.callee.activeXString); 21 }; 22 }else{ 23 return function(){ 24 throw new Error("No XHR object available."); 25 }; 26 } 27 })();
4、函数绑定
函数绑定要创建一个函数,可以在特定的this环境中以指定参数调用另一个函数。该技巧常常和回调函数与事件处理程序一起使用。
1 var handler = { 2 message : "Event handled", 3 4 handleClick : function(event){ 5 alert(this.message); 6 } 7 }; 8 9 var btn = document.getElementById("my-btn"); 10 EventUtil.addHandler(btn,"click",handler.handleClick); //按钮按下显示undefined,不显示Event handled
上述代码的问题在于没有保存handler.handleClick的环境,所以this最后指向了DOM按钮,而非handler(IE8中this指向window),可以使用闭包解决问题:
1 var handler = { 2 message : "Event handled", 3 4 handleClick : function(event){ 5 alert(this.message); 6 } 7 }; 8 9 var btn = document.getElementById("my-btn"); 10 EventUtil.addHandler(btn,"click",function(event){ 11 handler.handleClick(event); //按钮按下显示Event handled 12 });
由于闭包难以理解和调试,大部分js库为此实现了可以将函数绑定到指定环境的函数,一般叫做bind(),简单的bind函数,接收一个函数和环境,返回一个给定函数中调用给定函数的函数,并且将所有参数原封不动传过去。
1 //bind函数解决方案 2 function bind(fn,context){ 3 return function(){ 4 return fn.apply(context,arguments); 5 }; 6 }
5、函数柯里化
函数柯里化用于创建已经设置好了一个或多个参数的函数。基本方法和函数绑定一样:使用闭包返回一个函数。区别在于:函数被调用时返回的函数还需要设置一些传入参数。
二、防篡改对象
1、不可扩展对象
1 var person = { name : "name"}; 2 Object.preventExtensions(person); 3 4 person.age = 28; 5 alert(person.age); //undefined 6 //Object.isExtensible()可检测对象是否可扩展
1 var person = { name : "name" }; 2 alert(Object.isExtensible(person)); //true 3 alert(Object.isSealed(person)); //false 4 5 Object.seal(person); 6 alert(Object.isExtensible(person)); //false 7 alert(Object.isSealed(person)); //true
JavaScript中经常以事件的形式应用观察者模式。虽然事件常常和DOM一起使用,但也可以通过实现自定义事件在自己的代码中应用。使用自定义事件有助于将不同部分的代码相互之间解耦,让维护更加容易,并减少引入错误的机会。
拖放对于桌面和Web应用都是一个非常流行的用户界面范例,它能够让用户非常方便地以一种直观的方式重新排列或者配置东西。在JavaScrip中可以使用鼠标事件和一些简单的计算来实现这种功能类型。将拖放行为和自定义事件结合起来可以创建一个可重复使用的框架,它能应用于各种不同的情况下。
第二十三章 离线应用与客户端存储
开发离线Web应用需要几个步骤。首先是确保应用知道设备是否能上网,以便下一步执行正确的操作。然后,应用还必须能访问一定的资源(图像、JavaScript、CSS 等),只有这样才能正常工作。 最后,必须有一块本地空间用于保存数据,无论能否上网都不妨碍读写。html5及其相关的API让开发离线应用成为现实。
一、离线检测
HTML5定义了navigator.onLine属性,true表示能上网。
1 var socket = new WebSocket("ws://www.example.com/server.php"); 2 var CookieUtil = { 3 get:function(name){ 4 var cookieName = encodeURIComponent(name) + "=" , 5 cookieStart = document.cookie.indexOf(cookieName), 6 cookieValue = null; 7 8 if(cookieStart > -1){ 9 var cookieEnd = document.cookie.indexOf(";",cookieStart); 10 if(cookieEnd == -1){ 11 cookieEnd = document.cookie.length; 12 } 13 cookieValue = decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length,cookieEnd)); 14 } 15 16 return cookieValue; 17 }, 18 set:function(name,value,expires,path,domain,secure){ 19 var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value); 20 21 if(expires instanceof Date){ 22 cookieText += "; expires=" + expires.toGMTString(); 23 } 24 if(path){ 25 cookieText += "; path=" + path; 26 } 27 if(domain){ 28 cookieText =+ "; domain=" + domain; 29 } 30 if(secure){ 31 cookieText += "; secure=" + secure; 32 } 33 document.cookie = cookieText; 34 }, 35 unset:function(name,path,domain,secure){ 36 this.set(name,"",new Date(0),path,domain,secure); 37 } 38 };
使用上述方法的例子:
1 //设置cookie 2 CookieUtil.set("name","Nicholas"); 3 CookieUtil.set("book","Professional JavaScript"); 4 5 //读取 6 alert(CookieUtil.get("name")); //"Nicholas" 7 alert(CookieUtil.get("book")); //Professional JavaScript 8 9 //删除 10 CookieUtil.unset("name"); 11 CookieUtil.unset("book"); 12 13 //设置cookie,包括它的路径、域、失效日期 14 CookieUtil.set("name","Nicholas","/books/projs","www.wrox.com",new Date("January 1,2010")); 15 16 //删除刚设置的cookie 17 CookieUtil.unset("name","/books/projs","www.wrox.com"); 18 19 //设置安全cookie 20 CookieUtil.set("name","Nicholas",null,null,null,true);
子 cookie 是存放在单个 cookie 中的更小段的数据。也就是使用cookie值来存储多个名称值对 儿。子cookie常见的的格式如下所示:
name=name1=value1&name2=value2&name3=value3&name4=value4&name5=value5
注:使用cookie时尽量少存储信息,不存敏感信息,因为cookie数据并非存储在一个安全环境中。
以上是关于学习第十三天(2019-11-26)的主要内容,如果未能解决你的问题,请参考以下文章