《JavaScript高級程式設計》心得筆記-----第五篇章

来源:http://www.cnblogs.com/qzccl/archive/2016/03/25/5320938.html
-Advertisement-
Play Games

第二十二章 1、 安全的檢測是使用:Object.prototype.toString.call(value); eg: PS:JSON的: 2、 作用安全域的構造函數:(不然this會指向window) PS:使用作用安全域的構造函數,就會鎖定調用構造函數的環境,如果使用構造函數竊取模式的繼承而且 ...


第二十二章

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、  解耦

第二十五章

    


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Js 程式採用Unicode字元集編碼的; Js語言嚴格區分大小寫(變數, 函數, 關鍵字,標識符) Js語言會忽略空格 換行 製表符 Js語句以 ;(分號) 結尾, 但是如果語句獨占一行是可以省略; 註:不是所有換行處都可以省略 ; 只有在缺少了分號,javascript無法正確解析代碼時, ja ...
  • 最近公司各種上線,所以回家略感疲憊就懶得寫了,這次我準備把剩下的所有方法全部分析完,可能篇幅過長...那麼廢話不多說讓我們進入正題。 沒看過前幾篇的可以猛戳這裡: underscore.js源碼解析(一) underscore.js源碼解析(二) underscore.js源碼解析(三) under ...
  • × 目錄 [1]相對定位 [2]固定定位 前面的話 一般地,說起定位元素是指position不為static的元素,包括relative、absolute和fixed。前面已經詳細介紹過absolute絕對定位的基礎和應用,這篇博客介紹和梳理相對定位relative和固定定位fixed的相關知識 相 ...
  • 以下內容都是關於在nodejs中的this而非javascript中的this,nodejs中的this和在瀏覽器中javascript中的this是不一樣的。 在全局中的this 全局中的this預設是一個空對象。並且在全局中this與global對象沒有任何的關係,那麼全局中的this究竟指向的 ...
  • 一個簡單例子: 2.2版本需要引用jquery,要習慣把js代碼寫到頁面底部,經測試,發現此代碼不支持IE10/11,以下提供相容IE的function,替換js部分即可 最後,需要註意的是不要在本地調度,你會發現不會生效,因為Flash的安全限制 擴展閱讀:http://www.365mini.c ...
  • 第9章,裝飾網站導航 限制訪問,處於隱私方面考慮,瀏覽器已經開始限制可以對偽類:visited應用哪些CSS屬性了。其中包括對已訪問過的鏈接定義color、background-color、border-color等樣式(除非已經為那些鏈接的正常狀態定義了顏、背景色和邊框色) 對於<a>標簽可以對所 ...
  • 1.在Html中引入相關的文件:引入風格文件(js/css/jq) 2.創建myFocus標準的Html的結構並填充內容 <div id="picBox"> <div class="pic"> <ul> <li></li> <li></li> </ul> </div> </div> 3.調用 myF ...
  • 在JS中有全局作用域和函數作用域,而在Nodejs中也自己的作用域,分為全局作用域(global)和模塊作用域。 js作用域: 以前學js的時候我們的全局對象是window,如: 我們定義的全局變數預設是給window添加一個屬性或者方法。 報錯,因為num是在函數中定義的,在函數外部是訪問不了函數 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...