第二十二章

1、  安全的检测是使用:Object.prototype.toString.call(value);

eg:

function isArray(value){

  return Object.prototype.toString.call(value) == “[object  Array]”;

}

PS:JSON的:

  var  isNativeJSON ==windoe.JSON && Object.prototype.toString.call(JSON) == “[object  JSON]”;

2、  作用安全域的构造函数:(不然this会指向window)

function Person(name,age){

if(this instanceof Person){

    this.name = name;

    this.age = age;

}

else{

   return new Person(name,age);

}

}

PS:使用作用安全域的构造函数,就会锁定调用构造函数的环境,如果使用构造函数窃取模式的继承而且不使用原形链,这个继承就有可能被破坏掉

当一个构造函数(Student)继承一个使用作用安全域的构造函数的时候,里面要使用Person.call(this,”ccl”,23);来继承,但是还需要在这个函数下面使用

Student.prototype = new Person();

3、  惰性载入函数:

1)   函数被调用时在处理函数(重写函数)【函数名 = function(){//代码}】

2)   在声明函数时就指定适当的函数【return function(){//代码}】

4、  函数绑定【创建一个函数,在特定的this环境中以指定参数调用另一个函数,通常与回调函数与事件处理程序一起使用】

var handler = {
message: "Event handled",
handleClick: function(event){
alert(this.message);
}
};

1)   自己创建bind()

(1)  创建一个bind()函数接受一个函数和一个环境,并返回给定环境中调用给定函数,并且将所有参数原封不动传递过去

function bind(fn,context){

   return function(){

     return fn.apply(context,argument);

}

}

(2)  调用EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler));

2)   利用原生的bind()方法:EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler));

5、  函数柯里化【使用一个闭包返回一个函数】

1)   创建柯里化的通用方式

function curry(fn){
var args = Array.prototype.slice.call(arguments, 1);//1表示返回数组包含从第二个参数开始 的所有参数 return function(){
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(null, finalArgs);
};
}

调用:var curriedAdd = curry(add, 5);//这里的add后面可以添加多个参数

2)   作为函数绑定的一部分包含在其中,创造出更复杂的bind()函数

function bind(fn, context){
var args = Array.prototype.slice.call(arguments, 2);
return function(){
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(context, finalArgs);
};
}

使用:EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler, "my-btn"));

3)   利用原生的bind()方法:

EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler, "my-btn"));

6、  防篡改对象(一旦把属性把属性定义为防篡改就无法撤销了)

1)   不可扩展对象:Object.preventExtensions(person);

判断是否可以扩展:Object.isExtensible (person)

2)   密封的对象【密封对象不可扩展,而且configuraable会设置为false,也就是不能删除属性和方法,但是属性值是可以修改的,在非严格模式下,删除和修改属性会被忽略,但是在严格模式下,会抛出错误】

Object.seal(person);

判断是否被密封:Object.isSealed (person)

3)   冻结对象【既不可以扩展,又是密封的,而且对象的writable被设置为false,,在非严格模式下,对冻结的对象执行非法操作会被忽略,但是在严格模式下,会抛出错误】

Object.Froze(person);

判断是否被冻结:Object. isFrozen (person)

7、  高级定时器

重复定时器:链式 setTimeout()调用。

setTimeout(function(){
//处理中
setTimeout(arguments.callee, interval);
}, interval);

8、  Yielding Processes

1)   数组分块

function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context, item);
if (array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}

9、  函数节流

function throttle(method, context) {
clearTimeout(method.tId);
method.tId= setTimeout(function(){
method.call(context);
}, 100);
}

10、自定义事件

function EventTarget(){
this.handlers = {};
}
EventTarget.prototype = {
constructor: EventTarget,
addHandler: function(type, handler){
if (typeof this.handlers[type] == "undefined"){
this.handlers[type] = [];
}
this.handlers[type].push(handler);
},
fire: function(event){
if (!event.target){
event.target = this;
}
if (this.handlers[event.type] instanceof Array){
var handlers = this.handlers[event.type];
for (var i=0, len=handlers.length; i < len; i++){
handlers[i](event);
}
}
},
removeHandler: function(type, handler){
if (this.handlers[type] instanceof Array){
var handlers = this.handlers[type];
for (var i=0, len=handlers.length; i < len; i++){
if (handlers[i] === handler){
break;
}
}
handlers.splice(i, 1); }
}
};

使用:

1)

 function handleMessage(event){
alert("Message received: " + event.message);
} //创建一个新对象
var target = new EventTarget();
//添加一个事件处理程序
target.addHandler("message", handleMessage);
//触发事件
target.fire({ type: "message", message: "Hello world!"});
//删除事件处理程序
target.removeHandler("message", handleMessage);
//再次,应没有处理程序
target.fire({ type: "message", message: "Hello world!"});

2)   其他对象可以继承 EventTarget 并获得这个行为:

function Person(name, age){
EventTarget.call(this);
this.name = name;
this.age = age;
}
inheritPrototype(Person,EventTarget);
Person.prototype.say = function(message){
this.fire({type: "message", message: message});
};

11、拖放:

var DragDrop = function(){
var dragdrop = new EventTarget(),
dragging = null,
diffX = 0,
diffY = 0;
function handleEvent(event){
//获取事件和对象
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
//确定事件类型 switch(event.type){
case "mousedown":
if (target.className.indexOf("draggable") > -1){
dragging = target;
diffX = event.clientX - target.offsetLeft;
diffY = event.clientY - target.offsetTop;
dragdrop.fire({type:"dragstart", target: dragging,
x: event.clientX, y: event.clientY});
}
break;
case "mousemove":
if (dragging !== null){
//指定位置
dragging.style.left = (event.clientX - diffX) + "px";
dragging.style.top = (event.clientY - diffY) + "px";
//触发自定义事件
dragdrop.fire({type:"drag", target: dragging,
x: event.clientX, y: event.clientY});
}
break;
case "mouseup":
dragdrop.fire({type:"dragend", target: dragging,
x: event.clientX, y: event.clientY});
dragging = null;
break;
}
};
//公共接口
dragdrop.enable = function(){
EventUtil.addHandler(document, "mousedown", handleEvent);
EventUtil.addHandler(document, "mousemove", handleEvent);
EventUtil.addHandler(document, "mouseup", handleEvent);
};
dragdrop.disable = function(){
EventUtil.removeHandler(document, "mousedown", handleEvent);
EventUtil.removeHandler(document, "mousemove", handleEvent);
EventUtil.removeHandler(document, "mouseup", handleEvent);
};
return dragdrop;
}();

第二十三章

1、  离线检测:navigator.onLine【true能上网,反之,但是不同浏览器之间还是有些差异】

确定网络是否可用:online 和 offline

EventUtil.addHandler(window, "online", function(){
alert("Online");
});
EventUtil.addHandler(window, "offline", function(){
alert("Offline");
});

在页面加载后,最好先通过 navigator.onLine 取得初始的状态。然后,就是通过上述两个事件来确定网络连接状态是否变化

2、  应用缓存(appcache):applicationCache()对象

3、  Cookie:名称和值都必须经过URL编码【decodeURIComponent()来解码】

1)   读取、写入、删除

var CookieUtil = {
get: function (name){
var cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if (cookieStart > -1){
var cookieEnd = document.cookie.indexOf(";", cookieStart);
if (cookieEnd == -1){
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart
+ cookieName.length, cookieEnd));
}
return cookieValue;
},
set: function (name, value, expires, path, domain, secure) {
var cookieText = encodeURIComponent(name) + "=" +
encodeURIComponent(value);
if (expires instanceof Date) {
cookieText += "; expires=" + expires.toGMTString();
}
if (path) {
cookieText += "; path=" + path;
} if (domain) {
cookieText += "; domain=" + domain;
}
if (secure) {
cookieText += "; secure";
}
document.cookie = cookieText;
},
unset: function (name, path, domain, secure){
this.set(name, "", new Date(0), path, domain, secure);
}
};

使用:

//设置 cookie
CookieUtil.set("name", "Nicholas");
CookieUtil.set("book", "Professional JavaScript");
//读取 cookie 的值
alert(CookieUtil.get("name")); //"Nicholas"
alert(CookieUtil.get("book")); //"Professional JavaScript"
//删除 cookie
CookieUtil.unset("name");
CookieUtil.unset("book"); //设置 cookie,包括它的路径、域、失效日期
CookieUtil.set("name", "Nicholas", "/books/projs/", "www.wrox.com",
new Date("January 1, 2010"));
//删除刚刚设置的 cookie
CookieUtil.unset("name", "/books/projs/", "www.wrox.com");
//设置安全的 cookie
CookieUtil.set("name", "Nicholas", null, null, null, true);

2)   子cookie

var SubCookieUtil = {
get: function (name, subName){
var subCookies = this.getAll(name);
if (subCookies){
return subCookies[subName];
} else {
return null;
}
},
getAll: function(name){
var cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null,
cookieEnd,
subCookies,
i,
parts,
result = {};
if (cookieStart > -1){
cookieEnd = document.cookie.indexOf(";", cookieStart);
if (cookieEnd == -1){
cookieEnd = document.cookie.length;
}
cookieValue = document.cookie.substring(cookieStart + cookieName.length, cookieEnd);
if (cookieValue.length > 0){
subCookies = cookieValue.split("&");
for (i=0, len=subCookies.length; i < len; i++){
parts = subCookies[i].split("=");
result[decodeURIComponent(parts[0])] =
decodeURIComponent(parts[1]);
}
return result;
}
}
return null;
},
//省略了更多代码
};

使用:

//假设 document.cookie=data=name=Nicholas&book=Professional%20JavaScript
//取得全部子 cookie
var data = SubCookieUtil.getAll("data");
alert(data.name); //"Nicholas"
alert(data.book); //"Professional JavaScript"
//逐个获取子 cookie
alert(SubCookieUtil.get("data", "name")); //"Nicholas"
alert(SubCookieUtil.get("data", "book")); //"Professional JavaScript"

4、  IE用户数据

1)   使用 CSS 在某个元素上指定 userData 行为,就可以使用setAttribute()方法来保存数据:

<div style="behavior:url(#default#userData)" id="dataStore"></div>

var dataStore = document.getElementById("dataStore");
dataStore.setAttribute("name", "Nicholas");
dataStore.setAttribute("book", "Professional JavaScript");
dataStore.save("BookInfo");

2)   下一次载入时,可以使用load()来获取数据:

dataStore.load("BookInfo");

dataStore.getAttribute("name")

3)   removeAttribute()方法明确指定要删除某元素数据,只要指定属性名称。删除之后,必须像下面这样再次调用 save()来提交更改。

dataStore.removeAttribute("name");

dataStore.save("BookInfo");

5、  Web存储机制:

1)   storage类型(只存储字符串):

(1)  clear(),删除所有值; Firefox 中没有实现

(2)  getItem(name) 可以直接调用

(3)  key(index) 获得 index 位置处的值的名字

(4)  removeItem(name) 可以直接调用

(5)  setItem(name,value) 可以直接调用

(6)  length值对数量,无法判断对象中所有数据的大小,不过 IE8 提供了一个 remainingSpace 属性,用于获取还可以使用的存储空间的字节数

2)   sessionStorage 对象

(1)  存储方法:

(1st)     使用方法存储数据

sessionStorage.setItem("name", "Nicholas");

(2nd)     使用属性存储数据

sessionStorage.book = "Professional JavaScript";

PS:只适用于IE8:

sessionStorage.begin();
sessionStorage.name = "Nicholas";
sessionStorage.book = "Professional JavaScript";
sessionStorage.commit();

(2)  读取数据:

(1st)     使用方法存储数据

var name = sessionStorage.getItem("name");

(2nd)     使用属性存储数据

var book = sessionStorage.book;

结合 length 属性和 key()方法来迭代 sessionStorage 中的值:

for (var i=0, len = sessionStorage.length; i < len; i++){
var key = sessionStorage.key(i);
var value = sessionStorage.getItem(key); }

(3)  使用 for-in 循环来迭代 sessionStorage 中的值:

for (var key in sessionStorage){
var value = sessionStorage.getItem(key);
alert(key + "=" + value);
}

(4)  删除数据

(1st)     使用 delete 删除一个值——在 WebKit 中无效

delete sessionStorage.name;

(2nd)     使用方法删除一个值

sessionStorage.removeItem("book");

3)   globalStorage 对象:

//保存数据
globalStorage["wrox.com"].name = "Nicholas";
//获取数据
var name = globalStorage["wrox.com"].name;

PS: 事先不能确定域名,那么使用 location.host 作为属性名比较安全

4)   localStorage 对象:

//使用方法存储数据
localStorage.setItem("name", "Nicholas");
//使用属性存储数据
localStorage.book = "Professional JavaScript";
//使用方法读取数据
var name = localStorage.getItem("name");
//使用属性读取数据
var book = localStorage.book;

5)   为了兼容只支持 globalStorage 的浏览器:

function getLocalStorage(){
if (typeof localStorage == "object"){
return localStorage;
} else if (typeof globalStorage == "object"){
return globalStorage[location.host];
} else {
throw new Error("Local storage not available.");
}
}

使用:var storage = getLocalStorage();

6)   storage 事件:

(1)  属性【IE8 和 Firefox 只实现了 domain 属性】:

domain:发生变化的存储空间的域名;

key:设置或者删除的键名;

newValue:如果是设置值,则是新值;如果是删除键,则是 null;

  • oldValue:键被更改之前的值;

(2)  侦听 storage 事件:

EventUtil.addHandler(document, "storage", function(event){
alert("Storage changed for " + event.domain);
});

6、  IndexedDB(数据库,使用对象保存数据)

1)   每一次 IndexedDB 操作,都需要注册 onerror 或 onsuccess 事件处理程序,以确保适当地处理结果

var request, database,errorInfo;

if (database.version != "1.0"){
request = database.setVersion("1.0");
request.onerror = function(event){
errorInfo = event.target.errorCode;//错误信息
};
request.onsuccess = function(event){
database = event.target.result;//数据库实例对象
};
} else {
alert("Database already initialized. Database name: " + database.name +
", Version: " + database.version);
}

第二十四章

1、  可维护性

2、  解耦

《JavaScript高级程序设计》心得笔记-----第五篇章的更多相关文章

  1. JavaScript高级程序设计学习笔记第五章--引用类型(函数部分)

    四.Function类型: 1.函数定义的方法: 函数声明:function sum (num1, num2) {return num1 + num2;} 函数表达式:var sum = functi ...

  2. JavaScript高级程序设计学习笔记第五章--引用类型

    一.object类型 1.创建object类型的两种方式: 第一种,使用构造函数 var person = new Object();或者是var person={};/与new Object()等价 ...

  3. JavaScript高级程序设计---学习笔记(五)

    1.2D上下文 1)填充与描边 填充和描边的两个操作取决于两个属性:fillStyle和strokeStyle.两个属性的值可以是字符串.渐变对象或模式对象,默认值都是#000000 例: html: ...

  4. javascript高级程序设计阅读笔记(一)

    javascript高级程序设计阅读笔记(一) 工作之余开发些web应用作为兴趣,在交互方面需要掌握javascript和css.HTML5等技术,因此读书笔记是必要的. javascript简介 J ...

  5. 【javascript学习——《javascript高级程序设计》笔记】DOM操作

    DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口).DOM描绘了一个层次节点树,允许开发人员添加.移除和修改. 1.节点层次 <html> <head& ...

  6. javascript高级程序设计学习笔记

    javascript高级程序设计,当枕头书已经好久了~zz  现在觉得自己在js的开发上遇到了一些瓶颈,归根究底还是基础太薄弱,所以重新刷一遍js高程希望有更新的认识. 一.javascript简介 ...

  7. 《JavaScript高级程序设计》笔记——第一章到第三章

    2019年,新年伊始,我打算好好重读一下<JavaScript高级程序设计>这本前端必备经典书.每天半小时. 以下内容摘自<JavaScript高级程序设计> 2019-2-1 ...

  8. JavaScript高级程序设计---学习笔记(一)

    今天,2017.3.17开始利用课余时间仔细学习<JavaScript高级程序设计>,将需要掌握的知识点记录下来,争取把书里的所有代码敲一遍并掌握. 1.标识符命名最好是第一个字母小写,剩 ...

  9. 《javascript高级程序设计》笔记三

    第三章 基本概念 任何语言的核心必然会描述这门语言最基本的工作原理.这部分内容对我们来说,读起来很乏味,甚至会产生困意,但这部分内容却是重要的!我有幸拜读<JavaScript高级程序设计> ...

随机推荐

  1. UVA 1484 - Alice and Bob&#39;s Trip(树形DP)

    题目链接:1484 - Alice and Bob's Trip 题意:BOB和ALICE这对狗男女在一颗树上走,BOB先走,BOB要尽量使得总路径权和大,ALICE要小,可是有个条件,就是路径权值总 ...

  2. innodB的隐式锁

    http://blog.csdn.net/taozhi20084525/article/details/19545231 一.知识准备之隐式锁 参考:http://www.uml.org.cn/sjj ...

  3. oracle 有用站点

    使用oradebug修改数据库scn – 提供专业ORACLE技术咨询和支持@Phone13429648788 - 惜分飞 Solaris上使用DTrace进行动态跟踪 老熊的三分地-Oracle及数 ...

  4. redis实现与分析

    http://www.kuqin.com/shuoit/20141019/342739.html

  5. Quoit Design

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission ...

  6. java发送邮件 实现编辑html代码

    这个例子相当的简单,一看就懂(  此例仅支持163发送163及qq邮箱) 首先要导入两个必须jar包:mail-1.4.4.jar 和 commons-email-1.2.jar这两个jar包是我用的 ...

  7. 6. Android框架和工具之 JSON解析

    Android进阶笔记17:3种JSON解析工具(org.json.fastjson.gson)

  8. 【原创】C++链表如何像Python List一样支持多种数据类型

    用过Python的码友都知道,Python中List支持多种数据类型,如下面代码所示链表li内的数据类型可以是整数,同时也可以是字符串,当然也可以是其他数据类型. 1: >>> li ...

  9. iOS 6编程Cookbook(影印版)

    <iOS 6编程Cookbook(影印版)> 基本信息 原书名:iOS 6 Programming Cookbook 作者: Vandad Nahavandipoor 出版社:东南大学出版 ...

  10. Nginx 反向代理,流量转发到固定内网 IP 方法

    主配置文件: user nginx; worker_processes ; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pi ...