摘要:語法如下注意這里使用的并不是的,是內(nèi)部函數(shù)的。函數(shù)柯里化的基本方法是使用一個閉包返回一個函數(shù)。當函數(shù)被調(diào)用時,返回的函數(shù)還需要設置一些傳入的參數(shù)。
安全的類型檢測
typeof操作符
檢測數(shù)據(jù)類型的結(jié)果可能會不正確;
instanceof操作符
操作符在多個全局作用域下存在問題:
var value = []; var isArray = value instanceof Array; console.log(isArray);
上述代碼都在全局作用域,返回true;但如果value在其他frame中,則返回false。
JSON對象
該對象也難以確定是否為原生對象;
解決辦法:
因為在任何值上調(diào)用Object原生的toString()方法,都返回一個[Object NativeConstructorName]格式的字符串。每個類在內(nèi)部都有一個[[Class]]屬性,這個屬性指定了上述字符串中構造函數(shù)的函數(shù)名,如:
console.log(Object.prototype.toString()); //[object Object] //利用call(): var value = []; console.log(Object.prototype.toString.call(value)); //[object Array] //進一步完善: function whichType (value) { console.log(Object.prototype.toString.call(value)); } whichType("Obj"); //[boject String] whichType(["hello"]); //[object Array] whichType(321); //[object Number] //檢測是否為函數(shù): function isFunction (value) { return Object.prototype.toString.call(value) == "[object Function]"; } console.log(isFunction(Object.prototype.toString)); //true //檢測原生JSON對象: console.log(window.JSON && Object.prototype.toString.call(JSON) == "[object JSON]");
不適用于IE中COM對象形式實現(xiàn)的函數(shù)
作用域安全的構造函數(shù)當使用new調(diào)用構造函數(shù)時,構造函數(shù)內(nèi)用到的this對象會指向新創(chuàng)建的對象實例,如:
function Person (name) { this.name = name; } var person = new Person("oliver"); console.log(person.name);
問題是當沒有使用new操作符,直接調(diào)用構造函數(shù),this會映射到全局對象window上,導致錯誤對象屬性的意外增加:
function Person (name) { this.name = name; } var person = Person("oliver"); console.log(window.name); //oliver
解決辦法是創(chuàng)建一個作用域安全的構造函數(shù):
function Person(name) { if (this instanceof Person) { //如果this是Person的實例 this.name = name; } else { return new Person(name); //否則調(diào)用new操作符 } } var person1 = Person("oliver"); console.log(person1.name); //oliver var person2 = new Person("troy"); console.log(person2.name); //troy console.log(window.name); //""
但是,如果使用構造函數(shù)竊取模式的繼承且不實用原型鏈,那么這個繼承很可能被破壞如:
function Person(name) { if (this instanceof Person) { //如果this是Person的實例 this.name = name; } else { return new Person(name); //否則調(diào)用new操作符 } } function People (name,age) { Person.call(this, name); this.age = age; } var p = new People("Oliver", 18); console.log(p.name); //undefined console.log(p.age); //18
結(jié)合使用原型鏈或者寄生組合則可以解決這個問題:
function Person(name) { if (this instanceof Person) { //如果this是Person的實例 this.name = name; } else { return new Person(name); //否則調(diào)用new操作符 } } function People (name,age) { Person.call(this, name); this.age = age; } People.prototype = new Person(); //關鍵點 var p = new People("Oliver", 18); console.log(p.name); //Oliver console.log(p.age); //18惰性載入函數(shù)
惰性函數(shù)就是函數(shù)執(zhí)行的分支僅會發(fā)生一次。
第一種就是在函數(shù)被調(diào)用時再處理函數(shù):
function createXHR () { if (typeof XMLHttpRequest !== "undefined") { createXHR = function () { //關鍵點 return new XMLHttpRequest(); } } else if (typeof ActiveXObject !== "undefined") { createXHR = function () { //關鍵點 return new ActiveXObject(["MSXML2.XMLHttp"]); } } else { createXHR = function () { //關鍵點 throw new Error("No XHR object available."); } } return createXHR(); //關鍵點 }第二種
就是指定適當?shù)暮瘮?shù):
function createXHR () { if (typeof XMLHttpRequest !== "undefined") { return function () { //關鍵點 return new XMLHttpRequest(); } } else if (typeof ActiveXObject !== "undefined") { return function () { //關鍵點 return new ActiveXObject(["MSXML2.XMLHttp"]); } } else { return function () { //關鍵點 throw new Error("No XHR object available."); } } return createXHR(); //關鍵點 }函數(shù)綁定
函數(shù)綁定要創(chuàng)建一個函數(shù), 可以在特定的this環(huán)境中以指定參數(shù)調(diào)用另一個函數(shù)。 該技巧常常和回調(diào)函數(shù)與事件處理程序一起使用, 以便在將函數(shù)作為變量傳遞的同時保留代碼的執(zhí)行環(huán)境。 由于代碼之中存在著this變量, 而this在當前環(huán)境下指向確定的對象, 但是當更改代碼的執(zhí)行環(huán)境時, 就會出現(xiàn)問題了。 為了解決這個問題, javascript函數(shù)庫中實現(xiàn)了一個bind() 函數(shù)來解決這個問題。
一個簡單的bind() 函數(shù)接收一個函數(shù)和一個環(huán)境, 并返回一個在給定環(huán)境中調(diào)用給定函數(shù)的函數(shù), 并且將所有參數(shù)原封不動傳遞過去。 語法如下:
function bind(fn, context) { return function() { return fn.apply(context, arguments); } }
注意這里使用的arguments并不是bind() 的, 是內(nèi)部函數(shù)的。
var handler = { message: "Event handled", handleClick: function(event) { alert(this.message); } }; var btn = document.getElementById("my-btn"); EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler));
ECMAScript5為所有函數(shù)定義了一個原生的bind() 方法, 進一步簡化了操作。
var handler = { message: "Event handled", handleClick: function(event) { alert(this.message); } }; var btn = document.getElementById("my-btn"); EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler));
它們主要用于事件處理程序以及setTimeout() 和setInterval()。 然而被綁定函數(shù)與普通函數(shù)相比有更多的開銷, 它們需要更多內(nèi)存, 同時也因為多重函數(shù)調(diào)用稍微慢一些, 所以最好只在必要時使用。
函數(shù)柯里化它用于創(chuàng)建已經(jīng)設置好了一個或多個參數(shù)的函數(shù)。 函數(shù)柯里化的基本方法是: 使用一個閉包返回一個函數(shù)。 當函數(shù)被調(diào)用時, 返回的函數(shù)還需要設置一些傳入的參數(shù)。
柯里化函數(shù)通常由以下步驟動態(tài)的創(chuàng)建: 調(diào)用另一個函數(shù)并為它傳入要柯里化的函數(shù)和必要參數(shù)。 下面是創(chuàng)建柯里化函數(shù)的通用方式:
function curry(fn) { var args = Array.prototype.slice.call(arguments, 1); return function() { var innerArgs = Array.prototype.slice.call(arguments); var finalArgs = args.concat(innerArgs); return fn.apply(null, finalArgs); } }
這種變化也需要額外的開銷
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78791.html
摘要:為了規(guī)避這個問題,可以使用定時器對事件處理程序進行節(jié)流。當?shù)诙握{(diào)用該函數(shù)時,它會清除前一次的定時器,并設置另一個。如果前一個定時器已經(jīng)執(zhí)行過了,這個操作就沒有任何意義。然而如果前一個定時器尚未執(zhí)行,其實就是將其替換為一個新的定時器。 高級定時器 為了解決setInterval的一些執(zhí)行問題, 下面是采用鏈式setTimeout的方式來規(guī)避: setTimeout(function()...
摘要:防篡改對象不可擴展對象默認情況下,所有對象都是可擴展的不可擴展可以使用這個方法嚴格模式下會拋出錯誤一旦設置防擴展,對象就無法添加新的屬性和方法。已有的屬性方法不受影響,這些屬性方法仍然可以修改和刪除。檢測是否被凍結(jié),用方法 防篡改對象 不可擴展對象 默認情況下,所有對象都是可擴展的: var person = { name: Oliver }; person.age = 18;...
摘要:關于定時器要記住的最重要的事情是指定的時間間隔表示何時將定時器的代碼添加到隊列,而不是何時實際執(zhí)行代碼。多個定時器之間的執(zhí)行間隔會比預期的小解決辦法處理中數(shù)組分塊,,函數(shù)節(jié)流,實際進行處理的方法實際執(zhí)行的代碼初始處理調(diào)用的方法 一、高級函數(shù) 安全類型檢測 Object.protitype.toString.call(value) 作用域安全的構造函數(shù) function Pers...
摘要:如果你對函數(shù)式編程有一定了解,函數(shù)柯里化是不可或缺的,利用函數(shù)柯里化,可以在開發(fā)中非常優(yōu)雅的處理復雜邏輯。同樣先看簡單版本的方法,以方法為例,代碼來自高級程序設計加強版實現(xiàn)上面函數(shù),可以換成任何其他函數(shù),經(jīng)過函數(shù)處理,都可以轉(zhuǎn)成柯里化函數(shù)。 我們經(jīng)常說在Javascript語言中,函數(shù)是一等公民,它們本質(zhì)上是十分簡單和過程化的。可以利用函數(shù),進行一些簡單的數(shù)據(jù)處理,return 結(jié)果,...
摘要:封裝方法也比較簡單,書中對此問題也進行了處理使用定時器,讓函數(shù)延遲秒后執(zhí)行,在此秒內(nèi),然后函數(shù)再次被調(diào)用,則刪除上次的定時器,取消上次調(diào)用的隊列任務,重新設置定時器。 在實際開發(fā)中,函數(shù)一定是最實用最頻繁的一部分,無論是以函數(shù)為核心的函數(shù)式編程,還是更多人選擇的面向?qū)ο笫降木幊蹋紩泻瘮?shù)的身影,所以對函數(shù)進行深入的研究是非常有必要的。 函數(shù)節(jié)流 比較直白的說,函數(shù)節(jié)流就是強制規(guī)定一...
閱讀 2482·2021-11-24 09:39
閱讀 3524·2019-08-30 15:53
閱讀 599·2019-08-29 15:15
閱讀 2907·2019-08-26 13:23
閱讀 3222·2019-08-26 10:48
閱讀 648·2019-08-26 10:31
閱讀 772·2019-08-26 10:30
閱讀 2368·2019-08-23 18:32