成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

你真的懂函數(shù)嗎?

wall2flower / 2293人閱讀

摘要:函數(shù)聲明根據(jù)規(guī)則,進(jìn)入執(zhí)行上下文會(huì)自動(dòng)聲明形參并且賦值,但是同名的函數(shù)聲明會(huì)替換這個(gè)變量。的函數(shù)調(diào)用得到其返回值。的意義在于將執(zhí)行的結(jié)果通知給代理函數(shù)進(jìn)行及時(shí)處理?;卣{(diào)函數(shù)的傳遞傳遞的方式有兩種,函數(shù)引用和函數(shù)表達(dá)式。

函數(shù)聲明方式 匿名函數(shù)

function后面直接跟括號(hào),中間沒(méi)有函數(shù)名的就是匿名函數(shù)。

let fn = function() {
    console.log("我是fn")
}
let fn2 = fn
console.log(fn.name) //fn
console.log(fn2.name)//fn,fn和fn2指向的是同一個(gè)function。
具名函數(shù)

function后面有函數(shù)名字的,不是直接跟括號(hào)的的就是具名函數(shù)。
如果把一個(gè)具名函數(shù)賦值給一個(gè)變量,那么這個(gè)具名函數(shù)的作用域就不是window了。

let fn = function fn1() {
  console.log("function")
}
console.log(fn.name) //fn1
console.log(fn1,name) // ReferenceError: fn1 is not defined
箭頭函數(shù)

箭頭函數(shù)是es6知識(shí)點(diǎn),具有以下幾個(gè)特點(diǎn):

如果只有一個(gè)參數(shù),可以省略小括號(hào)。

如果有至少有兩個(gè)參數(shù),必須加小括號(hào)。

如果函數(shù)體只有一句話可以省略花括號(hào),并且這一句作為返回值return。

如果函數(shù)體至少有兩句必須加上花括號(hào)。

箭頭函數(shù)里面是沒(méi)有this的。

let fn = e => e+1
console.log(fn(1)) //2

let fn1 = (i,y) => i+y
console.log(fn1(2,3)) //5

let fn2 = (i,y) => {
  i+=1;
  y+=2;
  return i+y
}
console.log(fn2(5,6)) //13
詞法作用域(靜態(tài)作用域)
靜態(tài)作用域又叫做詞法作用域,采用詞法作用域的變量叫詞法變量。詞法變量有一個(gè)在編譯時(shí)靜態(tài)確定的作用域。詞法變量的作用域可以是一個(gè)函數(shù)或一段代碼,該變量在這段代碼區(qū)域內(nèi)可見(jiàn)(visibility);在這段區(qū)域以外該變量不可見(jiàn)(或無(wú)法訪問(wèn))。詞法作用域里,取變量的值時(shí),會(huì)檢查函數(shù)定義時(shí)的文本環(huán)境,捕捉函數(shù)定義時(shí)對(duì)該變量的綁定。

詞法作用域:變量的作用域是在定義時(shí)決定而不是執(zhí)行時(shí)決定,也就是說(shuō)詞法作用域取決于源碼,通過(guò)靜態(tài)分析就能確定,因此詞法作用域也叫做靜態(tài)作用域。 with和eval除外,所以只能說(shuō)JS的作用域機(jī)制非常接近詞法作用域(Lexical scope)。

通過(guò)詞法作用域樹(shù)能判斷變量指向關(guān)系,但是不能斷定變量的值,變量的值還需要根據(jù)執(zhí)行順序進(jìn)一步作出判斷,看一下例子:

因?yàn)镴avaScript采用的是詞法作用域,bian"liang的作用域基于函數(shù)創(chuàng)建的位置,跟調(diào)用時(shí)的位置無(wú)關(guān)。

var i = 1,
    j = 2,
    k = 3;

function a(o, p, x, q) {
    var x = 4;
    alert(i);

    function b(r, s) {
        var i = 11,
            y = 5;
        alert(i);

        function c(t) {
            var z = 6;
            alert(i);
        };
        
        var d = function() {
            alert(y);
        };
        c(60);
        d();
    };
    b(40, 50);
}
a(10, 20, 30); //1 11 11 5
/**
* 模擬建立一棵語(yǔ)法分析樹(shù),存儲(chǔ)function內(nèi)的變量和方法
*/
var SyntaxTree = {
        // 全局對(duì)象在語(yǔ)法分析樹(shù)中的表示
    window: {
        variables:{
            i:{ value:1},
            j:{ value:2},
            k:{ value:3}
        },
        functions:{
            a: this.a
        }
    },

    a:{
        variables:{
            x:"undefined"
        },
        functions:{
            b: this.b
        },
        scope: this.window
    },

    b:{
        variables:{
                 i:"undefined"
            y:"undefined"
        },
        functions:{
            c: this.c,
            d: this.d
        },
        scope: this.a
    },

    c:{
        variables:{
            z:"undefined"
        },
        functions:{},
        scope: this.b
    },

    d:{
        variables:{},
        functions:{},
        scope: {
           scope: this.b
        }
    }
};
/**
* 活動(dòng)對(duì)象:函數(shù)執(zhí)行時(shí)創(chuàng)建的活動(dòng)對(duì)象列表
*/
let ActiveObject = {
    window: {
        variables: {
            i: { value: 1 }
            j: { value: 2 }
            k: { value: 3 }
        },
        functions: {
                a: this.a
        }
    }

    a: {
        variables: {
            x: { vale: 4 },
            functions: {
                b: this.b
            },
            scope: this.window,
            params: {
                o: { value: 10 },
                p: { value: 20 },
                x: this.variables.x
                q: { vale: "undefined" }
            },
            arguments: [this.params.o, this.params.p, this.params.x]
        }
    }

    b: {
        variables: {
            i: { vale: 11 },
            y: { vale: 5 },
        },
        functions: {
            c: this.c,
            d: this.d
        },
        params: {
            r: { value: 40 }
            s: { value: 50 }
        },
        arguments: [this.params.r, this.params.scope]
        scope: this.a
    }


    c: {
        variables: {
            z: { value: 6 },
            functions: {},
            params: {
                t: { value: 60 }
            },
            arguments: [this.params.t]
            scope: this.b
        }
    }

    d: {
        variables: {},
        functions: {},
        params: {},
        arguments: []
        this.scope: this.b
    }

}
call stack

進(jìn)入call stack 時(shí)的一些規(guī)則:

函數(shù)的所有形參(如果我們是在函數(shù)執(zhí)行上下文中)

由名稱(chēng)和對(duì)應(yīng)值組成的一個(gè)變量對(duì)象的屬性被創(chuàng)建;沒(méi)有傳遞對(duì)應(yīng)參數(shù)的話,那么由名稱(chēng)和 undefined 值組成的一種變量對(duì)象的屬性也將被創(chuàng)建。

所有函數(shù)聲明(FunctionDeclaration, FD)

由名稱(chēng)和對(duì)應(yīng)值(函數(shù)對(duì)象(function-object))組成一個(gè)變量對(duì)象的屬性被創(chuàng)建;如果變量對(duì)象已經(jīng)存在相同名稱(chēng)的屬性,則完全替換這個(gè)屬性。

所有變量聲明(var, VariableDeclaration)

由名稱(chēng)和對(duì)應(yīng)值(undefined)組成一個(gè)變量對(duì)象的屬性被創(chuàng)建;如果變量名稱(chēng)跟已經(jīng)聲明的形式參數(shù)或函數(shù)相同,則變量聲明不會(huì)干擾已經(jīng)存在的這類(lèi)屬性。

/*
* example1:形參
*/
function test(a, b) {
    /*
    var a = 10
    var b = undefined
    根據(jù)規(guī)則1,在進(jìn)入執(zhí)行上下文時(shí)會(huì)自動(dòng)對(duì)形參聲明并且賦值。
    */ 
  console.log(a)
  var c = 10;
  function d() {}
  var e = function _e() {};
  (function x() {});
}
test(10); // 10
/*
* example2:函數(shù)聲明
*/
function test(a, b) {
  console.log(a)
  function a() {}
  var e = function _e() {};
}
test(10); // ? a() {} .根據(jù)規(guī)則2,進(jìn)入執(zhí)行上下文會(huì)自動(dòng)聲明形參并且賦值,但是同名的函數(shù)聲明會(huì)替換這個(gè)變量。

function test(a, b) {
  console.log(a)
  var a = 30;
  var a = function _e() {};
}
test(10); // 10 .根據(jù)規(guī)則2,進(jìn)入執(zhí)行上下文會(huì)自動(dòng)聲明形參并且賦值,但是同名的函數(shù)聲明會(huì)替換這個(gè)變量。
/*
* example3:變量聲明
*/
console.log(foo);//會(huì)打印出foo函數(shù),根據(jù)規(guī)則3,同名的變量聲明不會(huì)干擾函數(shù)聲明和形參

 function foo(){
    console.log("foo");
}

var foo = 1;
this和arguments 函數(shù)調(diào)用

在es5中,函數(shù)有四種調(diào)用方式:

1. fn(p1,p2)
2. obj.fn(p1,p2)
3. fn.call(context,p1,p2)
4. fn.apply(context,p1,p2)

第三和第四種才是正常的js函數(shù)調(diào)用方式,其他兩種就是語(yǔ)法糖。

fn(p1,p2)     等價(jià)于 fn.call(undefined,p1,p2) 等價(jià)于 fn.apply(context,[p1,p2])
obj.fn(p1,p2) 等價(jià)于 obj.fn.call(obj,p1,p2)   等價(jià)于 obj.fn.apply(obj,[p1,p2])
如果你傳的 context 就 null 或者 undefined,那么 window 對(duì)象就是默認(rèn)的 context(嚴(yán)格模式下默認(rèn) context 是 undefined)
this是什么??

this是call的第一個(gè)參數(shù)?。。。?/strong>

var obj = {
  foo: function(){
    console.log(this)
  }
}

var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window
obj.foo() 相當(dāng)于 obj.foo.call(obj) 也就相當(dāng)于把函數(shù)名前面的作為call的第一個(gè)參數(shù),也就是this,如果沒(méi)有就是window。
bar() 相當(dāng)于 bar.call(undefined) 

在執(zhí)行函數(shù)的時(shí)候,this是隱藏的一個(gè)參數(shù),且必須是一個(gè)對(duì)象,如果不是,js是自動(dòng)把它轉(zhuǎn)為對(duì)象。

function fn() {
    console.log(this)
    console.log(arguments)
}
fn.call(1,2,3) // Number?{1}  [2,3]
arguments

arguments是偽數(shù)組它類(lèi)似于Array,但除了length屬性和索引元素之外沒(méi)有任何Array屬性。
call和apply里面除了第一個(gè)參數(shù)之外的都是arguments,如果arguments的個(gè)數(shù)少建議使用call,使用apply也可以,如果不確定就使用apply。
使用一下方法吧arguments轉(zhuǎn)為真正的數(shù)組:

var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

// ES2015
const args = Array.from(arguments);
const args = [...arguments]
bind

MDN 官方文檔對(duì) bind() 的定義:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

大概意思就是,bind會(huì)返回一個(gè)新的函數(shù)(并沒(méi)有的調(diào)用原來(lái)的函數(shù)),這個(gè)新函數(shù)會(huì)call原來(lái)的函數(shù),call的參數(shù)由你決定??蠢樱?/p>

        this.x = 9;
        var module = {
          x: 81,
          getX: function() { return this.x; }
        };
        
        var retrieveX = module.getX;
        var boundGetX = retrieveX.bind(module);
        boundGetX(); // 81

retrieveX.bind(module)返回了一個(gè)新的函數(shù)boundGetX,然后調(diào)用這個(gè)新的函數(shù)的時(shí)候,把這個(gè)函數(shù)里面的this綁定到了module對(duì)象上,所以this.x就相當(dāng)于module.x也就是等于81.

柯里化
在計(jì)算機(jī)科學(xué)中,柯里化(英語(yǔ):Currying),又譯為卡瑞化或加里化,是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。這個(gè)技術(shù)由克里斯托弗·斯特雷奇以邏輯學(xué)家哈斯凱爾·加里命名的,盡管它是Moses Sch?nfinkel和戈特洛布·弗雷格發(fā)明的。

說(shuō)的明白一點(diǎn)就是,給函數(shù)傳遞一部分參數(shù),讓它返回一個(gè)函數(shù)去處理其他參數(shù),舉個(gè)例子,求三個(gè)數(shù)之和:

let addOne = function add(x) {
  return function(y) {
    return function(z) {
      return x+y+z
    }
  }
}

let one = addOne(3)
console.log(one)//? (y) {return function (z) {return x + y + z}}
let two = one(4)
console.log(two)//? (z) {return x + y + z}
let three = two(5)
console.log(three)//12

javascript函數(shù)柯里化--詳細(xì)說(shuō)明鏈接

高階函數(shù)

在數(shù)學(xué)和計(jì)算機(jī)科學(xué)中,高階函數(shù)是至少滿足下列一個(gè)條件的函數(shù):

接受一個(gè)或多個(gè)函數(shù)作為輸入

輸出一個(gè)函數(shù)

舉一些高階函數(shù)的例子:

/*
*接受一個(gè)或多個(gè)函數(shù)作為輸入
*/
1. Array.prototype.filter()
2. Array.prototype.forEach()
3. Array.prototype.reduce()
4. Array.prototype.map()
5. Array.prototype.find()
6. Array.prototype.every()
/*
*輸出一個(gè)函數(shù)
*/
1. fn.bind(args)
回調(diào)函數(shù)
函數(shù)A作為參數(shù)(函數(shù)引用)傳遞到另一個(gè)函數(shù)B中,并且這個(gè)函數(shù)B執(zhí)行函數(shù)A。我們就說(shuō)函數(shù)A叫做回調(diào)函數(shù)。如果沒(méi)有名稱(chēng)(函數(shù)表達(dá)式),就叫做匿名回調(diào)函數(shù)。

名詞形式:被當(dāng)做參數(shù)的函數(shù)就是回調(diào)
動(dòng)詞形式:調(diào)用這個(gè)回調(diào)
注意回調(diào)跟異步?jīng)]有任何關(guān)系

回調(diào)函數(shù)的使用場(chǎng)合

資源加載:動(dòng)態(tài)加載js文件后執(zhí)行回調(diào),加載iframe后執(zhí)行回調(diào),ajax操作回調(diào),圖片加載完成執(zhí)行回調(diào),AJAX等等。

DOM事件及Node.js事件基于回調(diào)機(jī)制(Node.js回調(diào)可能會(huì)出現(xiàn)多層回調(diào)嵌套的問(wèn)題)。

setTimeout的延遲時(shí)間為0,這個(gè)hack經(jīng)常被用到,settimeout調(diào)用的函數(shù)其實(shí)就是一個(gè)callback的體現(xiàn)

鏈?zhǔn)秸{(diào)用:鏈?zhǔn)秸{(diào)用的時(shí)候,在賦值器(setter)方法中(或者本身沒(méi)有返回值的方法中)很容易實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,而取值器(getter)相對(duì)來(lái)說(shuō)不好實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,因?yàn)槟阈枰≈灯鞣祷啬阈枰臄?shù)據(jù)而不是this指針,如果要實(shí)現(xiàn)鏈?zhǔn)椒椒ǎ梢杂没卣{(diào)函數(shù)來(lái)實(shí)現(xiàn)。

setTimeout、setInterval的函數(shù)調(diào)用得到其返回值。由于兩個(gè)函數(shù)都是異步的,即:他們的調(diào)用時(shí)序和程序的主流程是相對(duì)獨(dú)立的,所以沒(méi)有辦法在主體里面等待它們的返回值,它們被打開(kāi)的時(shí)候程序也不會(huì)停下來(lái)等待,否則也就失去了setTimeout及setInterval的意義了,所以用return已經(jīng)沒(méi)有意義,只能使用callback。callback的意義在于將timer執(zhí)行的結(jié)果通知給代理函數(shù)進(jìn)行及時(shí)處理。

回調(diào)函數(shù)的傳遞

傳遞的方式有兩種,函數(shù)引用和函數(shù)表達(dá)式。

$.get("myhtmlpage.html", myCallBack);//這是對(duì)的
$.get("myhtmlpage.html", myCallBack("foo", "bar"));//這是錯(cuò)的,那么要帶參數(shù)呢?
$.get("myhtmlpage.html", function(){//帶參數(shù)的使用函數(shù)表達(dá)式
myCallBack("foo", "bar");
});
箭頭函數(shù)與es5的函數(shù)主要區(qū)別

箭頭函數(shù)的主要區(qū)別在this,箭頭函數(shù)是沒(méi)有this這個(gè)概念的,看例子:

setTimeout(function(a){
  console.log(this) //這個(gè)this指的是{name:"Jack"}
  setTimeout(function(a){
    console.log(this) //這個(gè)this指的是window,因?yàn)闆](méi)有bind,調(diào)用setTimeout的是window
  },1000)
}.bind({name:"Jack"}),1000)
setTimeout(function(a){
  console.log(this) //這個(gè)this指的是{name:"Jack"}
  setTimeout(function(a){
    console.log(this) //這個(gè)this指的是{name: "Jack"},因?yàn)閎ind了外面的this也就是{name: "Jack"}
  },1000)
}.bind({name:"Jack"}),1000)
setTimeout(function(a){
  console.log(this) //這個(gè)this指的是{name:"Jack"}
  setTimeout(a=>console.log(this),1000)//這個(gè)this指的是{name:"Jack"},因?yàn)榧^函數(shù)沒(méi)有this的概念,它指的this就是外面的this,也就是{name:"Jack"}
}.bind({name:"Jack"}),1000)

至此基本上說(shuō)了js的所有函數(shù)內(nèi)容,只是簡(jiǎn)單舉個(gè)例子,更深入的研究還需要看一些其他大佬的博客哦~~~~

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/93395.html

相關(guān)文章

  • 真的JavaScript基礎(chǔ)類(lèi)型

    摘要:基本類(lèi)型有六種,,,,,。類(lèi)型是類(lèi)數(shù)組,具有基礎(chǔ)類(lèi)型檢測(cè)檢測(cè)基礎(chǔ)類(lèi)型用只適合檢測(cè)基礎(chǔ)類(lèi)型基礎(chǔ)類(lèi)型轉(zhuǎn)換基本類(lèi)型轉(zhuǎn)換時(shí),首先會(huì)調(diào)用,然后調(diào)用。該方法在轉(zhuǎn)基本類(lèi)型時(shí)調(diào)用優(yōu)先級(jí)最高。 夯實(shí)Javascript基礎(chǔ)。 基本類(lèi)型有六種: null,undefined,boolean,number,string,symbol。 基本類(lèi)型的值是保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段 基礎(chǔ)類(lèi)型特性 基礎(chǔ)類(lèi)型最重要的...

    baishancloud 評(píng)論0 收藏0
  • 真的JavaScript基礎(chǔ)類(lèi)型

    摘要:基本類(lèi)型有六種,,,,,。類(lèi)型是類(lèi)數(shù)組,具有基礎(chǔ)類(lèi)型檢測(cè)檢測(cè)基礎(chǔ)類(lèi)型用只適合檢測(cè)基礎(chǔ)類(lèi)型基礎(chǔ)類(lèi)型轉(zhuǎn)換基本類(lèi)型轉(zhuǎn)換時(shí),首先會(huì)調(diào)用,然后調(diào)用。該方法在轉(zhuǎn)基本類(lèi)型時(shí)調(diào)用優(yōu)先級(jí)最高。 夯實(shí)Javascript基礎(chǔ)。 基本類(lèi)型有六種: null,undefined,boolean,number,string,symbol。 基本類(lèi)型的值是保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段 基礎(chǔ)類(lèi)型特性 基礎(chǔ)類(lèi)型最重要的...

    ernest.wang 評(píng)論0 收藏0
  • 真的JavaScript基礎(chǔ)類(lèi)型

    摘要:基本類(lèi)型有六種,,,,,。類(lèi)型是類(lèi)數(shù)組,具有基礎(chǔ)類(lèi)型檢測(cè)檢測(cè)基礎(chǔ)類(lèi)型用只適合檢測(cè)基礎(chǔ)類(lèi)型基礎(chǔ)類(lèi)型轉(zhuǎn)換基本類(lèi)型轉(zhuǎn)換時(shí),首先會(huì)調(diào)用,然后調(diào)用。該方法在轉(zhuǎn)基本類(lèi)型時(shí)調(diào)用優(yōu)先級(jí)最高。 夯實(shí)Javascript基礎(chǔ)。 基本類(lèi)型有六種: null,undefined,boolean,number,string,symbol。 基本類(lèi)型的值是保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段 基礎(chǔ)類(lèi)型特性 基礎(chǔ)類(lèi)型最重要的...

    seasonley 評(píng)論0 收藏0
  • 作用域閉包,真的?

    摘要:曾幾何時(shí),閉包好像就是一個(gè)十分難以捉摸透的東西,看了很多文章,對(duì)閉包都各有說(shuō)法,以致讓我十分暈,什么內(nèi)部變量外部變量的,而且大多數(shù)都只描述一個(gè)過(guò)程,沒(méi)有給閉包的定義,最后,舉幾個(gè)例子,告訴你這就是閉包。 曾幾何時(shí),閉包好像就是一個(gè)十分難以捉摸透的東西,看了很多文章,對(duì)閉包都各有說(shuō)法,以致讓我十分暈,什么內(nèi)部變量、外部變量的,而且大多數(shù)都只描述一個(gè)過(guò)程,沒(méi)有給閉包的定義,最后,舉幾個(gè)例子...

    yangrd 評(píng)論0 收藏0
  • 真的switch?聊聊switch語(yǔ)句中的塊級(jí)作用域

    摘要:最近在代碼中不小心不規(guī)范的,在里面定義了塊級(jí)變量,導(dǎo)致頁(yè)面在某些瀏覽器中出錯(cuò),本文討論以下語(yǔ)句中的塊級(jí)作用域。而與無(wú)關(guān)每一個(gè)并不會(huì)構(gòu)成一個(gè)獨(dú)立的塊級(jí)作用域。 ??最近在代碼中不小心不規(guī)范的,在switch里面定義了塊級(jí)變量,導(dǎo)致頁(yè)面在某些瀏覽器中出錯(cuò),本文討論以下switch語(yǔ)句中的塊級(jí)作用域。 switch語(yǔ)句中的塊級(jí)作用域 switch語(yǔ)句中的塊級(jí)作用域可能存在的問(wèn)題 規(guī)范和檢...

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

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

0條評(píng)論

閱讀需要支付1元查看
<