JS 函数

JavaScript 函数

1.函数声明

function关键字

function myFunction(a, b) {
    return a * b;
}

通过一个表达式定义,函数可以赋给一个变量:

var x = function(a, b) {return a * b;}; //实际是一个匿名函数
document.getElementById("p1").innerHTML=x(2, 3);

Function() 构造函数

var myFunction = new Function("a", "b", "return a * b;");
var x = myfunction(3, 4);

2.函数提升

myFunction(5); //这样的函数是可以提升的,即可以先使用,再声明

function myFunction(y) {
    return y * y;
}

表达式定义函数无法提升。

3.函数自调用

(function(){var x = "Hello!!";})()

这样的函数将自调用,没有函数名,调用一次。

4.函数是对象
使用typeof操作符判断,返回的是function
函数有属性和方法

function myFunction(a, b){
    return arguments.length; //返回的是函数传入的参数
}
function myFunction(a, b) {
    return a * b;
}

var txt = myFunction.toString(); //toString 将函数作为一个字符串返回
// var txt = myFuction;有相同作用

5.函数参数

函数显式参数在函数定义时列出

函数隐式参数在函数调用时传递给函数真正的值

对隐式参数没有作类型和个数检测

调用时,为提供隐式参数,那么默认为undefined

function myFuntion(a, b){
    if(b === undefined){
        b = 0;
    }
    /*或者这样写
    b = b || 0;
    */
    return a * b;
}
document.getElementById("p1").innerHTML = myFuntion(4);

6.Arguments 对象
arguments 对象包含函数调用的参数数组,这样,当隐式参数过多时,也可以通过arguments来调用

        function findMax(){
            var i, max = arguments[0];
            if(arguments.length < 2) return max;

            for (i = 1; i < arguments.length; i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
        document.getElementById("p1").innerHTML = findMax(3, 4, 5, 6);
  1. 对象作为参数传递
    对象作为参数传递至函数,那么在函数内修改对象的属性,函数外定义的对象的属性会改变
var a = {"id": 1, "name": "wong"};
        function func(x){
            x["id"] = 2;
        }
        func(a)
        document.getElementById("p1").innerHTML = a["id"];
  1. 函数对象的call()和apply()方法使用
    两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。
        function myFunction(a, b){
            return a * b;
        }
        var object = myFunction.call(object, 2, 3);
        document.getElementById("p1").innerHTML = object;
        function myFunction(a, b){
            return a * b;
        }
        var array = [2, 3];
        var object = myFunction.apply(object, array);
        document.getElementById("p1").innerHTML = object;
  1. js 内嵌函数
    在 JavaScript 中,所有函数都能访问它们上一层的作用域,JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。
        function count(){
            var counter = 0;
            function plus(){
                counter += 1;
            }
            plus();
            return counter;
        }
        document.getElementById("p1").innerHTML = count();
  1. 函数闭包

个人理解: 外部函数中定义一个内部函数,通过这个内部函数来调用外部函数所定义的变量,这个变量不致被垃圾回收,同时也只有这个内部函数可以调用,保证变量安全。

对函数理解,当只有一个function的变量时,相当于这只是一个变量类型,在变量后加上(),表名执行这个函数的运行。

        var f = function(){
            return 2 * 3;
        }

        var ff = f;
        document.write(ff); //function(){ return 2 * 3; }
        document.write("<br>");
        document.write(ff()); //6
        document.write("<br>");
        document.write(typeof ff); //function
        document.write("<br>");
        document.write(typeof ff()); //number

闭包举例:

        function a(){ //外部函数
            var i = 0; //一个变量
            function b(){ //内部函数,调用变量i
                alert(++i); 
            }
            return b; //返回的是内部函数,而不是内部函数return的值
        }
        var c = a(); // c 为函数b,此时a中的变量不会被销毁
        c(); //三次调用,每次++i,i依次递加,显示1,2,3
        c();
        c();
        var add = (function(){
            var counter = 0;
            return function(){return ++counter;}
        })();
        document.write(typeof add); //function
        alert(add());
        alert(add());
        alert(add());

上面第一个代码比较好理解,第二个代码稍微有点不好理解,掌握函数基本概念也是比较好理解的。,首先,有两个匿名函数,这两个匿名函数内嵌关系,外层函数内定义一个counter变量和一个 return 的内层函数,即调用此外层函数时,返回的是一个内层函数:function(){return counter++;} 第一条语句的最后一个括号就是说外层函数自调用。这样add赋值就是内层函数,注意 add是一个函数.下面三个alert()中的add()就是调用add这个函数,由于add这个函数是将counter自加再显示,所以会有三个alert,分别是1,2,3。

上述代码修改后等价如下:

        function f1(){
            var counter = 0;
            function f2(){
                return ++counter;
            }
            return f2;
        }
        var add = f1();

        alert(add());
        alert(add());
        alert(add());
  1. 高阶函数
    高阶函数,就是让函数作为参数传入一个函数

一个简单的高阶函数:

        function f1(a, b, f){
            return f(a)+f(b);
        }
        document.write(f1(-2, 3, Math.abs)); //5

Array中的高阶函数,map(),reduce(),filter(),sort()

        function f(a){
            return a * a;
        }
        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        var arrNew = arr.map(f);
        document.write(arrNew); //1,4,9,16,25,36,49,64,81
        function f(a, b){
            return a + b;
        }
        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        var ans = arr.reduce(f); //[x1, x2, x3, x4].reduce(f) 等价 f(f(f(x1, x2), x3), x4)
        document.write(ans); //45
        function f(element, index, self){ //element为当前元素,index为当前元素在原数组中的位置,self为原数组,一般只用第一个参数即可
            return self.indexOf(element) === index; //返回true,保留该元素,否则过滤掉该元素
        }
        var arr = [1, 2, 3, 4, 5, 6, 9, 9, 9];
        var ans = arr.filter(f);
        document.write(ans); //1,2,3,4,5,6,9

sort()方法注意:sort()方法默认把所有元素先转换为String再排序,故’10’排在了’2’的前面,因为字符’1’比字符’2’的ASCII码小。即转化为String后按字典序排

        function f(element, index, self){
            return self.indexOf(element) === index;
        }
        var arr = [2, 20, 10, 1];
        var ans = arr.sort();
        document.write(ans); //1,10,2,20

如果想排序整数,可以重写一个函数传进sort()

        function f(x, y){ //从小到大
            if(x < y){ //前一个小于后一个,不用交换位置,返回-1
                return -1;
            }
            else if(x > y){ //前一个大于后一个,交换位置,返回1
                return 1;
            }
            return 0;
        }
        var arr = [2, 20, 10, 1];
        var ans = arr.sort(f);
        document.write(ans); //1,2,10,20
        function f(x, y){ //从大到小
            if(x < y){ //前一个小于后一个需要交换位置,返回1
                return 1;
            }
            else if(x > y){ //前一个大于后一个不需要交换位置,返回-1
                return -1;
            }
            return 0;
        }
        var arr = [2, 20, 10, 1];
        var ans = arr.sort(f);
        document.write(ans); //20,10,2,1
        function f(x, y){
            if(x < y){
                return 1;
            }
            else if(x > y){
                return -1;
            }
            return 0;
        }
        var arr = ["CCC", "aaa", "BBB"];
        var ans = arr.sort();
        document.write(ans); //BBB,CCC,aaa

上述代码比较了字符串,通过字典序比较的,如果想忽略字母大小写影响,加一个回调函数即可

        function f(x, y){
            var s1 = x.toUpperCase();
            var s2 = y.toUpperCase();
            if(s1 < s2){
                return -1;
            }
            if(s1 > s2){
                return 1
            }
            return 0; 
        }
        var arr = ["CCC", "aaa", "BBB"];
        var ans = arr.sort(f);
        document.write(ans); //aaa,BBB,CCC

单例模式,函数柯里化,泛化this,uncurrying

  1. 箭头函数
    简写形式的函数表达式,并且它拥有词法作用域的this值(即不会新产生自己作用域下的this,arguments,super和new.target等对象),箭头函数总是匿名

语法:

N个参数:
(param1, param2, ..., paramN) => {statements}
单个参数:
param => {statements}
可变参数:
(param1, param2, ...rest) => {statements}
无参数:
() => {statements}

直接返回:
param => param * param;
相当于:
function(param){
    return param * param;
}

返回是对象,且是单表达式,注意加()
x => ({foo: x});

同时支持设置默认值:
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();

箭头函数内部的this词法作用域是由上下文决定的

        var obj = {
            birth: 1990,
            getAge: function(){
                var b = this.birth; //1990
                var fn = function(){
                    return new Date().getFullYear() - this.birth; //this 指向windows或undefined
                }
                return fn();
            }
        }
        document.write(obj.getAge()); 
        var obj = {
            birth: 1990,
            getAge: function(year){
                var b = this.birth; //1990
                var fn = y => y - this.birth; //仍是1990
                return fn.call({birth: 2000},2018); //第一个参数被忽略,this已绑定
            }
        }
        document.write(obj.getAge()); //28

即call apply方法的第一个参数将失效

不绑定arguments

        function foo(){
            var f = () => arguments[0]; //不指向箭头函数的arguments,指向所在域的arguments
            return f(2);
        }

        document.write(foo(1)); //1

箭头函数没有自己的 arguments 对象,不过在大多数情形下,rest参数可以给出一个解决方案:

        function foo(){
            var f = (...args) => args[0]; //不指向箭头函数的arguments,指向所在域的arguments
            return f(2);
        }

        document.write(foo(1)); //2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值