成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 高級(jí)技巧——“高級(jí)函數(shù)”的注意要點(diǎn)

solocoder / 2987人閱讀

摘要:語法如下注意這里使用的并不是的,是內(nèi)部函數(shù)的。函數(shù)柯里化的基本方法是使用一個(gè)閉包返回一個(gè)函數(shù)。當(dāng)函數(shù)被調(diào)用時(shí),返回的函數(shù)還需要設(shè)置一些傳入的參數(shù)。

安全的類型檢測

typeof操作符

檢測數(shù)據(jù)類型的結(jié)果可能會(huì)不正確;

instanceof操作符

操作符在多個(gè)全局作用域下存在問題:

var value = [];
var isArray = value instanceof Array;
console.log(isArray);

上述代碼都在全局作用域,返回true;但如果value在其他frame中,則返回false。

JSON對(duì)象

該對(duì)象也難以確定是否為原生對(duì)象;

解決辦法:

因?yàn)樵谌魏沃瞪险{(diào)用Object原生的toString()方法,都返回一個(gè)[Object NativeConstructorName]格式的字符串。每個(gè)類在內(nèi)部都有一個(gè)[[Class]]屬性,這個(gè)屬性指定了上述字符串中構(gòu)造函數(shù)的函數(shù)名,如:

console.log(Object.prototype.toString()); //[object Object]
//利用call():
var value = [];
console.log(Object.prototype.toString.call(value)); //[object Array]
//進(jìn)一步完善:
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對(duì)象:
console.log(window.JSON && Object.prototype.toString.call(JSON) == "[object JSON]");

不適用于IE中COM對(duì)象形式實(shí)現(xiàn)的函數(shù)

作用域安全的構(gòu)造函數(shù)

當(dāng)使用new調(diào)用構(gòu)造函數(shù)時(shí),構(gòu)造函數(shù)內(nèi)用到的this對(duì)象會(huì)指向新創(chuàng)建的對(duì)象實(shí)例,如:

function Person (name) {
    this.name = name;
}
var person = new Person("oliver");
console.log(person.name);

問題是當(dāng)沒有使用new操作符,直接調(diào)用構(gòu)造函數(shù),this會(huì)映射到全局對(duì)象window上,導(dǎo)致錯(cuò)誤對(duì)象屬性的意外增加:

function Person (name) {
    this.name = name;
}
var person = Person("oliver");
console.log(window.name); //oliver

解決辦法是創(chuàng)建一個(gè)作用域安全的構(gòu)造函數(shù):

function Person(name) {
    if (this instanceof Person) { //如果this是Person的實(shí)例
        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); //""

但是,如果使用構(gòu)造函數(shù)竊取模式的繼承且不實(shí)用原型鏈,那么這個(gè)繼承很可能被破壞如:

function Person(name) {
    if (this instanceof Person) { //如果this是Person的實(shí)例
        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é)合使用原型鏈或者寄生組合則可以解決這個(gè)問題:

function Person(name) {
    if (this instanceof Person) { //如果this是Person的實(shí)例
        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(); //關(guān)鍵點(diǎn)
var p = new People("Oliver", 18);
console.log(p.name); //Oliver
console.log(p.age); //18
惰性載入函數(shù)

惰性函數(shù)就是函數(shù)執(zhí)行的分支僅會(huì)發(fā)生一次。

第一種

就是在函數(shù)被調(diào)用時(shí)再處理函數(shù):

function createXHR () {
    if (typeof XMLHttpRequest !== "undefined") {
        createXHR = function () { //關(guān)鍵點(diǎn)
            return new XMLHttpRequest();
        }
    } else if (typeof ActiveXObject !== "undefined") {
        createXHR = function () { //關(guān)鍵點(diǎn)
            return new ActiveXObject(["MSXML2.XMLHttp"]);
        }
    } else {
        createXHR = function () { //關(guān)鍵點(diǎn)
            throw new Error("No XHR object available.");
        }
    }
    return createXHR(); //關(guān)鍵點(diǎn)
}
第二種

就是指定適當(dāng)?shù)暮瘮?shù):

function createXHR () {
    if (typeof XMLHttpRequest !== "undefined") {
        return function () { //關(guān)鍵點(diǎn)
            return new XMLHttpRequest();
        }
    } else if (typeof ActiveXObject !== "undefined") {
        return function () { //關(guān)鍵點(diǎn)
            return new ActiveXObject(["MSXML2.XMLHttp"]);
        }
    } else {
        return function () { //關(guān)鍵點(diǎn)
            throw new Error("No XHR object available.");
        }
    }
    return createXHR(); //關(guān)鍵點(diǎn)
}
函數(shù)綁定

函數(shù)綁定要?jiǎng)?chuàng)建一個(gè)函數(shù), 可以在特定的this環(huán)境中以指定參數(shù)調(diào)用另一個(gè)函數(shù)。 該技巧常常和回調(diào)函數(shù)與事件處理程序一起使用, 以便在將函數(shù)作為變量傳遞的同時(shí)保留代碼的執(zhí)行環(huán)境。 由于代碼之中存在著this變量, 而this在當(dāng)前環(huán)境下指向確定的對(duì)象, 但是當(dāng)更改代碼的執(zhí)行環(huán)境時(shí), 就會(huì)出現(xiàn)問題了。 為了解決這個(gè)問題, javascript函數(shù)庫中實(shí)現(xiàn)了一個(gè)bind() 函數(shù)來解決這個(gè)問題。

一個(gè)簡單的bind() 函數(shù)接收一個(gè)函數(shù)和一個(gè)環(huán)境, 并返回一個(gè)在給定環(huán)境中調(diào)用給定函數(shù)的函數(shù), 并且將所有參數(shù)原封不動(dòng)傳遞過去。 語法如下:

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ù)定義了一個(gè)原生的bind() 方法, 進(jìn)一步簡化了操作。

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í)也因?yàn)槎嘀睾瘮?shù)調(diào)用稍微慢一些, 所以最好只在必要時(shí)使用。

函數(shù)柯里化

它用于創(chuàng)建已經(jīng)設(shè)置好了一個(gè)或多個(gè)參數(shù)的函數(shù)。 函數(shù)柯里化的基本方法是: 使用一個(gè)閉包返回一個(gè)函數(shù)。 當(dāng)函數(shù)被調(diào)用時(shí), 返回的函數(shù)還需要設(shè)置一些傳入的參數(shù)。

柯里化函數(shù)通常由以下步驟動(dòng)態(tài)的創(chuàng)建: 調(diào)用另一個(gè)函數(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);
    }
}

這種變化也需要額外的開銷

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78791.html

相關(guān)文章

  • JavaScript 高級(jí)技巧——“高級(jí)定時(shí)器”注意要點(diǎn)

    摘要:為了規(guī)避這個(gè)問題,可以使用定時(shí)器對(duì)事件處理程序進(jìn)行節(jié)流。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器,并設(shè)置另一個(gè)。如果前一個(gè)定時(shí)器已經(jīng)執(zhí)行過了,這個(gè)操作就沒有任何意義。然而如果前一個(gè)定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個(gè)新的定時(shí)器。 高級(jí)定時(shí)器 為了解決setInterval的一些執(zhí)行問題, 下面是采用鏈?zhǔn)絪etTimeout的方式來規(guī)避: setTimeout(function()...

    rubyshen 評(píng)論0 收藏0
  • JavaScript 高級(jí)技巧——“防篡改對(duì)象”注意要點(diǎn)

    摘要:防篡改對(duì)象不可擴(kuò)展對(duì)象默認(rèn)情況下,所有對(duì)象都是可擴(kuò)展的不可擴(kuò)展可以使用這個(gè)方法嚴(yán)格模式下會(huì)拋出錯(cuò)誤一旦設(shè)置防擴(kuò)展,對(duì)象就無法添加新的屬性和方法。已有的屬性方法不受影響,這些屬性方法仍然可以修改和刪除。檢測是否被凍結(jié),用方法 防篡改對(duì)象 不可擴(kuò)展對(duì)象 默認(rèn)情況下,所有對(duì)象都是可擴(kuò)展的: var person = { name: Oliver }; person.age = 18;...

    atinosun 評(píng)論0 收藏0
  • JS程序設(shè)計(jì)高級(jí)技巧

    摘要:關(guān)于定時(shí)器要記住的最重要的事情是指定的時(shí)間間隔表示何時(shí)將定時(shí)器的代碼添加到隊(duì)列,而不是何時(shí)實(shí)際執(zhí)行代碼。多個(gè)定時(shí)器之間的執(zhí)行間隔會(huì)比預(yù)期的小解決辦法處理中數(shù)組分塊,,函數(shù)節(jié)流,實(shí)際進(jìn)行處理的方法實(shí)際執(zhí)行的代碼初始處理調(diào)用的方法 一、高級(jí)函數(shù) 安全類型檢測 Object.protitype.toString.call(value) 作用域安全的構(gòu)造函數(shù) function Pers...

    Codeing_ls 評(píng)論0 收藏0
  • 高級(jí)函數(shù)技巧-函數(shù)柯里化

    摘要:如果你對(duì)函數(shù)式編程有一定了解,函數(shù)柯里化是不可或缺的,利用函數(shù)柯里化,可以在開發(fā)中非常優(yōu)雅的處理復(fù)雜邏輯。同樣先看簡單版本的方法,以方法為例,代碼來自高級(jí)程序設(shè)計(jì)加強(qiáng)版實(shí)現(xiàn)上面函數(shù),可以換成任何其他函數(shù),經(jīng)過函數(shù)處理,都可以轉(zhuǎn)成柯里化函數(shù)。 我們經(jīng)常說在Javascript語言中,函數(shù)是一等公民,它們本質(zhì)上是十分簡單和過程化的??梢岳煤瘮?shù),進(jìn)行一些簡單的數(shù)據(jù)處理,return 結(jié)果,...

    shixinzhang 評(píng)論0 收藏0
  • 高級(jí)函數(shù)技巧-函數(shù)防抖與節(jié)流

    摘要:封裝方法也比較簡單,書中對(duì)此問題也進(jìn)行了處理使用定時(shí)器,讓函數(shù)延遲秒后執(zhí)行,在此秒內(nèi),然后函數(shù)再次被調(diào)用,則刪除上次的定時(shí)器,取消上次調(diào)用的隊(duì)列任務(wù),重新設(shè)置定時(shí)器。 在實(shí)際開發(fā)中,函數(shù)一定是最實(shí)用最頻繁的一部分,無論是以函數(shù)為核心的函數(shù)式編程,還是更多人選擇的面向?qū)ο笫降木幊蹋紩?huì)有函數(shù)的身影,所以對(duì)函數(shù)進(jìn)行深入的研究是非常有必要的。 函數(shù)節(jié)流 比較直白的說,函數(shù)節(jié)流就是強(qiáng)制規(guī)定一...

    whinc 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<