JS言语中心——“函数”

  • 参数

    • 形参(parameter):函数中定义的变量

    • 实参(argument):运行时的函数挪用时传入的参数

  • 上下文(context):经由过程对象来挪用函数时,这个对象就是this就是上下文;

  • 闭包(closure):函数嵌套在函数当中

1 函数挪用的体式格局

有4种要领来挪用JavaScript函数:

  • 作为函数

  • 作为要领

  • 作为组织函数

  • 经由过程call要领和apply要领间接挪用

ES3 和非严厉情势下的ES5中,挪用上下文(this的值)是全局对象。在严厉情势下,挪用上下文则是undefined

1.1 函数挪用

语法:

functionName()

window.name = "hello";
(function () {
    console.log(this); //window
})()

"use strict";
window.name = "hello";
(function () {
    console.log(this); //undefined
})()

1.2 要领挪用

语法:

obj.functionName()

要领和this关键字是面向对象编程范例的中心

要领链

  • 要领链:当要领的返回值是一个对象,这个对象还能够再挪用它的要领。这个要领挪用序列就是要领链;

1.3 组织函数挪用

没有形参的组织函数挪用都能够省略小括号

1.4 间接挪用

  • call要领:运用它自有的实参列表作为函数的实参;

  • apply要领:请求以数组的情势传入参数;

2 函数的实参和形参

2.1 可选形参

当挪用函数的时刻传入的实参比函数声明时指定的形参个数要少,剩下的形参都将是undefined;所以在定义函数的时刻应该给省略的参数赋一个默认值:

function pushArray(o, /* optional */ a) {
    if (a === undefined) a = [];
    // a = a || [];
    for (var property in o) a.push(property);
    return a;
}
var o = {
    name: "Oliver",
    age: 18
};
var a = ["friends"];
console.log(pushArray(o, a).toString()); //friends,name,age

2.2 实参对象

省略的实参都是undefined;多出的参数自动疏忽

别的,能够经由过程arguments来猎取过剩的参数,arguments.length取得参数个数

  • 不定实参函数(varargs function):吸收恣意个数的实参

不定实参函数的实参个数不能为零;

ES5之前,arguments[0]和x指代同一个值;

function pushArray(a) {   
    console.log(a); //Array
    arguments[0] = 10;
    console.log(a); //Array
    console.log(arguments[0]); //10
}
var a = ["friends"];
pushArray(a);

2.3 将对象属性用作实参

最好经由过程名值对的情势传入参数(传入的实参都写入一个零丁的对象当中,在挪用的时刻传入一个对象)

function outputString(obj) {
    var fname = obj.firstName,
        lname = obj.lastName,
        age = obj.age;
    console.log(`your fisrtName: ${fname}; lastName: ${lname}; age: ${age}`);
}
outputString({firstName: "Oliver", lastName: "Young", age: 18}); //your fisrtName: Oliver; lastName: Young; 

3 作为值的函数

函数也是值,能够将函数赋值给变量,存储在对象的属性和数组的元素中,作为参数传入别的一个函数等

函数是对象,能够定义本身的属性

log.conter = 10;
function log () {
    console.log(log.conter);
}
log(); //10

如许函数就不须要再定义一个全局变量

4作为定名空间的函数

将代码放入一个函数内,然后挪用这个函数:

差别的写法:

function log (i) {
    console.log("hello" +i);
}
log(100);

(function log (i) {
    console.log("hello" + i);
}(100))

(function log (i) {
    console.log("hello" + i);
})(100)

小括号括起来防止JavaScript诠释器剖析为函数声明语句

5 闭包

  • 词法作用域(lexical scoping):函数的实行依赖于变量作用域,这个作用域是在函数定义时决议的,而不是函数挪用时决议的。

  • 闭包:函数对象能够经由过程作用域互相关联起来,函数体内部的变量都能够保存在函数作用域内。

上面的log.conter属性就能够运用包含在闭包中:

var pro = (function() {
    var conter = 10;

    function log(argument) {
        console.log(conter++);
    }
    return log;
})();
pro(); //10
pro(); //11
pro(); //12

运用多个嵌套函数:

function counter () {
    var num = 0;
    return {
        count: function () {
            return num ++;
        },
        reset: function () {
            num = 0;
        }
    };
}
var newCounter = counter(); //这里是新的计数器,再赋值一个变量能够获得别的一个计数器,二者不受影响
console.log(newCounter.count()); //0
console.log(newCounter.count()); //1
console.log(newCounter.count()); //2
newCounter.reset();
console.log(newCounter.count()); //0
console.log(newCounter.count()); //1
console.log(newCounter.count()); //2

6 函数属性、要领和组织函数

6.1 length属性

函数的length返回的是形参的数目;函数内部arguments.length返回的是实参的数目

function add(x, y) {
    return arguments.length;
}
console.log(add.length); //2
console.log(add(1)); //1

6.2 prototype属性

6.3 call()和apply()要领

经由过程挪用要领的情势来间接挪用函数,call和apply的第一个实参是要挪用函数的母对象,它是挪用上下文。

比方,以对象o的要领的情势挪用函数f()并传入两个参数:f.call(o, 1, 2)

apply能够传入的参数能够是数组和类数组的。

6.4 bind()要领

ES5的该要领重要作用是将函数绑定至某个对象,要领返回一个新的函数,挪用这个新的函数会把绑定的函数在对象中当作要领来挪用。

function add(y) {
    return this.x + y;
}
var o = {
    x: 100
};
var g = add.bind(o);
console.log(g(100)); //200
  • 柯里化(currying):除了第一个实参外,传入bind的实参也会绑定至this;

function add(x, y) {
    return x + y;
}
var o = {

};
var g = add.bind(o, 100); //x是100
console.log(g(100)); //200 y是100

//上面的o对象能够去掉:
function add(x, y, z) {
    return x + y + z;
}
var g = add.bind(null, 100, 100, 100); //x是100 y是100 z是100
console.log(g()); //300

//又如:
function add(y, z) {
    return this.x + y + z;
}
var g = add.bind({x:100}, 100, 100); //{x是100} y是100 z是100
console.log(g()); //300

6.5 toString()要领

6.6 Function()组织函数

Function()组织函数所建立的函数并非运用此法作用域:

var scope = "global";
function constructFunction () {
    var scope = "local";
    return new Function("return scope");
}
console.log(constructFunction()()); //global

var scope = "global";
function constructFunction () {
    var scope = "local";
    return function () {
        return scope
    };
}
console.log(constructFunction()()); //local

6.7 可挪用的对象

7 函数式编程

7.1 运用函数处置惩罚数组

如要盘算元素的平均值:

var arr = [1,2,3,4,5];
var total = 0;
for (var i = 0; i < arr.length; i++) {
    total += arr[i];
};
var result = total/arr.length;
console.log(result); //3

函数式编程作风:

var arr = [1,2,3,4,5];
function sum (a, b) {
    return a + b;
}
var total = arr.reduce(sum);
var result = total/arr.length;
console.log(result); //3

7.2 高阶函数

  • 高阶函数(higher-order function):就是操纵函数的函数,它吸收一个或多个函数作为参数,并返回一个新函数

function reverse(fun) {
    return function () {
        var result = fun.apply(this, arguments);
        return !result;
    }
}
var even = function (x) {
    return x % 2 === 0;
};

var odd = reverse(even);
console.log(odd(100)); //False
console.log(even(100)); //True

7.3 不完全函数

7.4 影象

  • 影象(memorization):部份结果在函数式编程中被缓存起来,这类缓存技能就是“影象”

    原文作者:JS菌
    原文地址: https://segmentfault.com/a/1190000004879664
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞