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

資訊專欄INFORMATION COLUMN

函數(shù) - Javascript語法基礎(chǔ) - Javascript核心

wuaiqiu / 416人閱讀

摘要:在定義函數(shù)的作用域外調(diào)用,得到的返回仍然是函數(shù)創(chuàng)建時(shí)所在的作用域的局部變量。這是因?yàn)樗诘哪涿瘮?shù)的閉包中存放的是第一行的,而不是在循環(huán)中獲得的的當(dāng)前值。

  

原文: http://pij.robinqu.me/JavaScript_Core/JavaScript_Basics/Function.html

  

源代碼: https://github.com/RobinQu/Programing-In-Javascript/blob/master/chapters/JavaScript_Core/JavaScript_Basics/Function.md

本文存在批注,但該網(wǎng)站的Markdown編輯器不支持,所以無法正常展示,請到原文參考。

函數(shù)

Javascript中,要記住函數(shù)是first-class citizen。

定義

函數(shù)聲明語句

function plus(x ,y) {

}

函數(shù)定義表達(dá)式

var plus = function (x, y) {

}

函數(shù)調(diào)用

作為函數(shù)調(diào)用

function a(){};
a();

作為方法調(diào)用

a={};
a.x = function(){};
a.x();

通過call和apply間接調(diào)用函數(shù)(改變this)

call 和 apply帶有多個(gè)參數(shù),call和apply把當(dāng)前函數(shù)的this指向第一個(gè)參數(shù)給定的函數(shù)或?qū)ο笾?,并傳遞其余所有的參數(shù)作為當(dāng)前函數(shù)的參數(shù)。

var O = function () {
    this.foo  = "hello";
    this.hello = function () {
        return "world";
    }
};

var fn = function () {
    console.log("call", this);
};

var o = new O();

fn.call(o);//此時(shí)fn的this指向o

call和apply的不同之處,在于call傳遞的參數(shù)是作為arguments依次傳入的,例如

fn.call(o, 1, 2, 3);
而apply傳遞的參數(shù)是以一個(gè)數(shù)組的方式傳入的,例如
fn.apply(o, [1, 2, 3]);

參數(shù)

當(dāng)傳入?yún)?shù)少于函數(shù)聲明的參數(shù)時(shí),留空的參數(shù)的值是undefined

Javascript允許傳入?yún)?shù)的個(gè)數(shù)大于聲明時(shí)制定的參數(shù)個(gè)數(shù)??梢杂?b>arguments來訪問這些參數(shù)

function f(){
    var i;
    for( i = 0; i < arguments.length ; i++) {
        console.log(arguments[i]);
    }
}

f(1,2,3,4,5,6);

函數(shù)通過取得arguments的長度得到傳入?yún)?shù)的個(gè)數(shù),使用一個(gè)循環(huán)獲取每一個(gè)參數(shù)。

arguments還有兩個(gè)屬性,calleecaller
callee表示正在執(zhí)行的function對象,
caller表示調(diào)用當(dāng)前function的function

例如

function f(){
    console.log(arguments.callee);//[Function: f]
    console.log(arguments.callee.caller);[Function: g]
    var i;
    for( i = 0; i < arguments.length ; i++) {
        console.log(arguments[i]);
    }
}

function g(){
    f(1,2,3,4,5,6);
}

g();

callee 的重要用法之一是在匿名函數(shù)中實(shí)現(xiàn)遞歸

var result = function (x) {
    if (x <= 1) return 1;
    return x * arguments.callee(x - 1);
}(3);

console.log(result);

上例使用了一個(gè)匿名函數(shù)和callee實(shí)現(xiàn)了一個(gè)階乘。

作為值的函數(shù)

javascript中的函數(shù)可以作為值來傳遞

function square(x) {
    return x * x;
}

var s = square;
s(4);
作為命名空間的函數(shù)
(function() {

}());
閉包

Javascript函數(shù)對象的內(nèi)部狀態(tài)不僅包含著函數(shù)的代碼邏輯,還引用當(dāng)前的作用域鏈。函數(shù)對象通過作用域鏈相互關(guān)聯(lián)起來,函數(shù)體內(nèi)部變量包含在函數(shù)作用域內(nèi),這就叫閉包。

例如

var scope = "global scope";
function checkscope() {
    var scope = "local scope";
    function f() { 
        return scope;
    }
    return f;
}

checkscope()();

這段checkscope聲明了一個(gè)局部變量,定義了一個(gè)函數(shù)f,函數(shù)f返回了這個(gè)局部變量的值,最后返回了這個(gè)函數(shù)f。在定義函數(shù)f的作用域外調(diào)用f,得到的返回仍然是函數(shù)f創(chuàng)建時(shí)所在的作用域的局部變量scope。

又例如

var counter = (function() {
    var count = 0;
    return function () {
        return count++ ;
    }
}());

代碼定義了一個(gè)立即執(zhí)行函數(shù)并返回給counter,這個(gè)函數(shù)定義了一個(gè)局部變量count,返回了一個(gè)子函數(shù),該子函數(shù)每次調(diào)用,都會(huì)吧count加一并返回。

閉包的注意事項(xiàng)

觀察下面的示例:

var add_the_handlers = function (nodes) {
    var i;
        for (i = 0; i < nodes.length; i += 1) {
            nodes[i].onclick = function (e) {
                alert(i);
            };
        }
};

這個(gè)函數(shù)期望的結(jié)果,是在運(yùn)行的時(shí)候?yàn)槊總€(gè)node在onclick的時(shí)候alert出各自的序號(hào),但是實(shí)際運(yùn)行的結(jié)果卻不同:所有的node在單擊的時(shí)候alert出來的數(shù)字總是同一個(gè)。

這是因?yàn)閍lert所在的匿名函數(shù)的閉包中存放的i是第一行的i,而不是在循環(huán)中獲得的i的當(dāng)前值。

所以如果希望達(dá)到預(yù)期結(jié)果,應(yīng)該在循環(huán)中創(chuàng)建多個(gè)閉包,在閉包中存放當(dāng)前循環(huán)的i的值:

var add_the_handlers = function (nodes) {
    var i;
        for (i = 0; i < nodes.length; i += 1) {
            nodes[i].onclick = function (i) {
                return function(e){
                    alert(e);
                };
            }(i);
        }
};

這里使用一個(gè)立即執(zhí)行函數(shù)并傳遞當(dāng)前的i的值,返回一個(gè)新生成的函數(shù)。在這個(gè)新生成的函數(shù)的閉包中就保存了當(dāng)前的i的值。

函數(shù)中的this對象

在一個(gè)對象中的this始終引用當(dāng)前對象,但是在函數(shù)中,特別是在閉包中,this有一些特殊的行為。

函數(shù)中的this對象始終綁定在函數(shù)運(yùn)行時(shí)的上下文環(huán)境上。所以在普通模式下調(diào)用一個(gè)全局函數(shù),this始終指向window(客戶端),在嚴(yán)格模式下調(diào)用一個(gè)全局函數(shù),this始終是undefined

示例

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function () {
        return function () {
            return this.name;
        };
    },
    getName : function () {
        return this.name;
    }
};

console.log(object.getNameFunc()());
console.log(object.getName());

getNameFunction()返回了一個(gè)匿名函數(shù),這個(gè)匿名函數(shù)在調(diào)用的時(shí)候,上下文是window(瀏覽器中),所以在瀏覽器中輸出的是the Window

而getName()調(diào)用的時(shí)候上下文是object,所以成功輸出object的name

其實(shí)以上代碼中
object.getNameFunc()()
等效于
var fnc = object.getNameFunc();//這時(shí)候的fnc已經(jīng)脫離了object對象
fnc();

所以如果想要getNameFunction()正確返回Object的Name,需要在返回的匿名函數(shù)的閉包中保存在函數(shù)聲明時(shí)的this,

getNameFunc: function () {
        var that = this;
        return function () {
            return that.name;
        };
    },

這樣就可以了。。

函數(shù)柯里化

函數(shù)柯里化是指,把接受多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換成接受一個(gè)單一參數(shù)的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。

示例

var add1 = add.curry(1);
console.log(add1(2));

其中,add是接受兩個(gè)參數(shù)的函數(shù),add調(diào)用了curry返回一個(gè)只接受一個(gè)參數(shù)的新函數(shù),之后調(diào)用add1便等效于調(diào)用add(1, 2);

javascript并不原生支持curry,可以用prototype來模擬

Function.prototype.curry = function () {
    var slice = Array.prototype.slice,
        args = slice.apply(arguments),
        that = this;
    return function () {
        return that.apply(null, args.concat(slice.apply(arguments)));
    };
};


function add(n1, n2) {
    return n1 + n2;
}

var add1 = add.curry(1);
console.log(add1(2));

curry創(chuàng)建了一個(gè)新函數(shù),在新函數(shù)的閉包中保存了原先傳遞的參數(shù)。

函數(shù)的屬性和方法

length 函數(shù)的length表示函數(shù)實(shí)參的數(shù)量,是只讀的

prototype 指向一個(gè)該函數(shù)的原型對象的引用

toString 返回一個(gè)字符串

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

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

相關(guān)文章

  • JavaScript核心語法-基礎(chǔ)語法

    摘要:基礎(chǔ)語法區(qū)分大小寫是一種區(qū)分大小寫的語法,意味著的關(guān)鍵字變量名函數(shù)名以及其他一切的字符表示都要使用一致的大小寫形式?;镎Z化物語空格和換行會(huì)忽略代碼中出現(xiàn)的空格換行制表符。如果不用花括號(hào)獨(dú)立獨(dú)立編寫一個(gè)語句,語法并不報(bào)錯(cuò),但不推薦。 JavaScript基礎(chǔ)語法 區(qū)分大小寫 JavaScript是一種區(qū)分大小寫的語法,意味著JavaScript的關(guān)鍵字、變量名、函數(shù)名以及其他一切的字符...

    soasme 評論0 收藏0
  • 數(shù)組 - Javascript語法基礎(chǔ) - Javascript核心

    摘要:數(shù)組創(chuàng)建數(shù)組數(shù)組字面量使用構(gòu)造函數(shù)數(shù)組本質(zhì)上是所以要判斷是不是數(shù)組,需要通過判斷。數(shù)組長度使用屬性獲取元素的個(gè)數(shù)。例如函數(shù)的對象就是這樣 原文: http://pij.robinqu.me/JavaScript_Core/JavaScript_Basics/Array.html 源代碼: https://github.com/RobinQu/Programing-In-...

    molyzzx 評論0 收藏0
  • Javascript Objects - Javascript語法基礎(chǔ) - Javascript核心

    摘要:創(chuàng)建對象對象直接量構(gòu)造函數(shù)原型繼承類繼承對象擁有自有屬性和繼承屬性。遍歷順序是以廣度優(yōu)先遍歷所以使用便可以判斷是否是對象自有的屬性。可執(zhí)行對象通過如下方法可以創(chuàng)建一個(gè)可執(zhí)行對象既可以當(dāng)作對象來使用有原型鏈,也可以當(dāng)作函數(shù)來直接調(diào)用 原文: http://pij.robinqu.me/Javascript_Core/Javascript_Basics/Objects.html ...

    wzyplus 評論0 收藏0
  • Javascript語句 - Javascript語法基礎(chǔ) - Javascript核心

    摘要:多數(shù)運(yùn)算符都是由標(biāo)點(diǎn)符號(hào)表示,比如和。通常會(huì)根據(jù)需要對操作數(shù)進(jìn)行類型轉(zhuǎn)換左值是一個(gè)古老的屬于,它是指表達(dá)式只能出現(xiàn)在賦值運(yùn)算符的左側(cè)。也稱為嚴(yán)格相等運(yùn)算符,它用來檢測兩個(gè)操作數(shù)是否嚴(yán)格相等。運(yùn)算符的檢測規(guī)則是和運(yùn)算符的求反。 源代碼: https://github.com/RobinQu/Programing-In-Javascript/blob/master/chapters/...

    lavnFan 評論0 收藏0
  • JavaScript 闖關(guān)記》之簡介

    摘要:瀏覽器只是實(shí)現(xiàn)的宿主環(huán)境之一,其他宿主環(huán)境包括和。年月,版發(fā)布,成為國際標(biāo)準(zhǔn)。事件定義了事件和事件處理的接口。對于已經(jīng)正式納入標(biāo)準(zhǔn)的來說,盡管各瀏覽器都實(shí)現(xiàn)了某些眾所周知的共同特性,但其他特性還是會(huì)因?yàn)g覽器而異。 JavaScript 是面向 Web 的編程語言,絕大多數(shù)現(xiàn)代網(wǎng)站都使用了 JavaScript,并且所有的現(xiàn)代 Web 瀏覽器(電腦,手機(jī),平板)均包含了 JavaScri...

    baihe 評論0 收藏0

發(fā)表評論

0條評論

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