• javascript 函数介绍


    javascript函数使用的时候,往往都比较单一,这里介绍几种不同于我们之前使用的函数调用方式!

    1、函数表达式包含名称,用于递归

    var f = function s(num) {
        if (num < 1) {
            return 1;
        } else {
            return num * s(num - 1);
            //return 语句会导致函数停止运行
        }
    }

    一般要实现递归的功能的时候,使用函数表达式包含名称的使用比较方便!

    调用方式:

    var num = f(5);//120

    2、函数表达式定以后立即执行

    var s = (function (x) {
        return x * x
    }
    (10));
    console.log(s); //100

    3、函数声明
    函数声明并非真正的语句,ECMAScript规范只是允许它们作为顶级语句!

    4、函数链式调用

    function s() {
        console.log(1);
        this.s1 = function () {
            console.log("2");
            this.s2 = function () {
                console.log("3");
            }
            return this;
        }
        return this;
    }

    调用方式:

    s().s1().s2();

    5、构造函数调用
    如果函数函数或者方法调用之前使用new关键字,就是构造函数调用的方式。
    var s = new Object(); //如果构造函数没有参数可以采用下面一行,省略括号
    var s = new Object;
    构造函数调用创建的对象是会继承构造函数的prototype的属性!并将这个对象用做调用上下文操作,因此可以使用this关键字!

    6、函数的参数对象

    arguments;
    arguments[0]//传入的第一个参数
    arguments[1]//传入的第二个参数
    arguments.length; //参数的长度
    //arguments并不是一个真正的数组,它是一个实参对象
    callee 和 caller //参数对象的属性
    arguments.callee //当前正在执行的函数
    arguments.caller //当前正在执行的函数的函数
    function s() {
      console.log(arguments.callee); //执行当前函数 等价于s();
      console.log(arguments.caller); //显示当前函数的函数代码块
    }

    7、函数自定义属性调用
    //每次调用都会加1

    s.index = 0;
    function s() {
      return s.index++;
    }
    s(); console.log(s.index);//1
    s();
    console.log(s.index);//2
    s();
    console.log(s.index);//3
    console.log(s.index);//3
    //自定义属性计算阶乘 //isFinite() 函数用于检查其参数是否是无穷大 function s(n) {   if (isFinite(n) && n > 0 && n == Math.round(n)) {   if (!(n in s)) {     s[n] = n * s(n - 1);   }   return s[n];   } else {     return NaN;   } } s[1] = 1;
    s(2);//2
    s(3);//6
    s(5);//120

    8、函数的命名空间

    //定义一个扩展函数,用来将第二个及后续的参数复制到第一个参数上
    var extend = (function () {
        for (var p in {
            toString : null
        }) {
            return function extend(o) {
                for (var i = 0; i < arguments.length; i++) {
                    var source = arguments[i];
                    for (var prop in source) {
                        o[prop] = source[prop];
                    }
                }
                return o;
            }
        }
        return function patch_extend(o) {
            for (var i = 0; i < arguments.length; i++) {
                var source = arguments[i];
                for (var prop in source) {
                    o[prop] = source[prop];
                }
                for (var j = 0; j < protoprops.length; j++) {
                    prop = protoprops[j];
                    if (source.hasOwnProperty(prop)) {
                        o[prop] = source[prop];
                    }
                }
            }
            return o;
        }
        var protoprops = ['toString', 'valueOf', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumable', 'toLocaleString'];
    }());

    9、闭包的使用

    var a = "1"; //全局
    function chech() {
        var a = "2"; //局部
        function f() {
            return a;
        }
        return f(); //执行 f()时依然在局部
    }
    chech(); //这里返回2
    //另外一个例子:
    var a = "1"; //全局
    function chech() {
        var a = "2"; //局部
        function f() {
            return a;
        }
        return f;
    }
    chech()(); //这里返回2
    //javascript 函数执行的时候用到了作用域链,这个作用域链是在函数定义的时候创建的,嵌套的函数f()定义在这个作用域链中,其中的a一定是局部变量,无论何时执行f(),这种绑定是一种有效的。
    //计数例子
    var count = (function () {
        var num = 1;
        return function () {
            return num++;
        }
    }
        ());
    //多个嵌套函数共同调用
    function count() {
        var num = 1;
        return {
            reset : function () {
                return num = 1;
            },
            conum : function () {
                return num++;
            }
        };
    }
    var a = count();
    var b = count();
    a.conum(); //1
    a.conum(); //2
    b.reset(); //1
    a.conum(); //3
    //每次调用count会创建不同的作用域对象,两者并不会被干扰
    //闭包例子:
    /*function repeat (func, times, wait) {
     *    } //这个函数能返回一个新函数,比如这样用
     *    var repeatedFun = repeat(alert, 10, 5000)
     *    //调用这个 repeatedFun ("hellworld")
     *    //会alert十次 helloworld, 每次间隔5秒
     *    var repeatedFun = repeat(alert, 10, 100);
     *    repeatedFun ("hellworld");
     */
    function repeat(func, times, wait) {
        return function (str) {
            var i = 0;
            var count = 0;
            var timer = setInterval(function () {
                    count++;
                    if (count % (wait / 1000) == 0) {
                        alert(str);
                        i++;
                        if (i == times) {
                            window.clearInterval(timer);
                        }
                    }
                }, 1000);
        }
    }
    var repeatedFun = repeat(alert, 10, 5000);
    repeatedFun('hellworld');

    10、实参的个数检测

    function check(args) {
        var actual = args.length; //实参的真实个数
        var expected = args.callee.length; //期望的实参个数
        if (actual !== expected) {
            throw Error('参数异常');
        }
    }
    function sum(x, y, z) {
        check(arguments);
        return x + y + z;
    }

    11、apply和call

    //1、每个函数都包含两个非继承而来的方法:apply()和call()。
    //2、他们的用途相同,都是在特定的作用域中调用函数。
    //3、接收参数方面不同,apply()接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
    //call()方法第一个参数与apply()方法相同,但传递给函数的参数必须列举出来。
    //例1:
    //代码如下:
    window.firstName = "diz";
    window.lastName = "song";
    var myObject = {
        firstName : "my",
        lastName : "Object"
    };
    function HelloName() {
          console.log("Hello " + this.firstName + " " + this.lastName, " glad to meet you!");
    }
    HelloName.call(window); //huo .call(this);
    HelloName.call(myObject);
    运行结果为:
    Hello diz song glad to meet you!
    Hello my Object glad to meet you!
    //例子2:
    function sum(num1, num2) {
        return num1 + num2;
    }
    console.log(sum.call(window, 10, 10)); //20
    console.log(sum.apply(window, [10, 20])); //30

    12、bind函数

    function f(y) {
        return this.x + y;
    }
    var o = {
        x : 1
    };
    var g = f.bind(o);
    g(2); //3
    //例子2
    function sum(x, y) {
        return x + y;
    }
    var s = sum.bind(null, 1); //这里的1绑定到x上
    s(2); //3
    //s(2)中的2绑定到y上了
    function f(y, z) {
        return this.x + y + z;
    }
    var g = f.bind({
            x : 1
        }, 2); //这里this.x绑定到了x:1,y绑定到了2上
    g(3); //这里3绑定到了z上
    //结果为:6

    13、函数的toString方法

    //和所有的Javascript对象一样,所有的函数都有toString()方法,ECMAScript规定它返回一个字符串!
    //大多数的代码返回的都是函数的源代码,少数会返回[native code];
    function s() {
        console.log(this);
    }
    console.log(s.toString());

    14、Function()创建函数

    //Function()构造函数所创建的函数可以穿入任意数量的参数,最后一个参数就是函数的函数体
    //例如:
    var d = new Function("a", "b", "return a;")
        //关于Function创建函数以下需要注意
        //Function创建函数并非是使用词法作用域,相反,函数体代码的编译总是会在顶层函数执行:
        如下代码:
        var scope = "global";
    function s() {
        var scope = "local";
        return new Function('return scope'); //此处提前执行,是找不到局部变量的
    }
    s(); //返回global

    15、高阶函数

    //高阶函数,即操作函数的函数,它接收一个或多个函数作为参数,返回一个新的函数!
    function not(f) {
        return function () {
            var result = f.apply(this, arguments);
            return !result;
        }
    }
    var even = function () {
        return even % 2 === 0;
    }
    var odd = not(even);
    [1, 3, 5, 7, 9].every(odd); //true

    16、记忆函数

    function s(f) {
        var cache = {};
        return function () {
            //将实参转换为字符串形式,并将其用做缓存的键
            var key = arguments.length + Array.prototype.join.call(arguments, ',');
            if (key in cache) {
                console.log(cache[key]);
                return cache[key];
            } else {
                console.log(cache[key]);
                return cache[key] = f.apply(this, arguments);
            }
        }
    }
    //使用1
    function gcd(a,b){
        var t;
        if(a<b){
            t = b;b = a; a = t;
        }
        while(b != 0){
            t = b;b = a%b; a = t;
            return a;
        }
    }
    var gcmo = s(gcd);
    gcmo(85,187);
    //使用2
    var fac = s(function(n){
        return (n <= 1) ? 1 : n*fac(n-1);
    });
    fac(5);//120
  • 相关阅读:
    [GAMES101]计算机图形学 Assignment 作业1 透视投影 解析手记
    [GAMES101]计算机图形学 Assignment 0
    [算法竞赛入门经典] 象棋 ACM/ICPC Fuzhou 2011, UVa1589 较详细注释
    最长上升子序列
    Qt快速入门第三版PDF
    [C++]UVaLive7324 ASCII Addtion
    [算法竞赛入门经典]Message Decoding,ACM/ICPC World Finals 1991,UVa213
    由数据查询慢来浅谈下oracle中的like和instr函数的模糊查询效率问题
    swift学习资料 + 教程
    weblogic DataSource 配置注意事项
  • 原文地址:https://www.cnblogs.com/shizhouyu/p/4527537.html
Copyright © 2020-2023  润新知