• javascript 函数


    arguments

    • 函数的实参被保存在一个类似数组的arguments对象中。
    • arguments变量只是 类数组对象“,并不是一个数组。称其为类数组对象是说它有一个索引编号和Length属性。尽管如此,它并不拥有全部的Array对象的操作方法。
    • 函数参数的默认值是undefined
    • 参数支持设置不同的默认值:function test(arg1, arg2 = 5) {}。
    • 原始参数(比如一个具体的数字)被作为传递给函数。
    • 对象参数,传递的是对象的应用。

    常用:

    1. arguments[n]
    2. arguments.length
    3. arguments.callee(ECMAScript (ES5) forbids use of arguments.callee() in strict mode.)

    递归函数

    形式1: 通过使用函数名

    function factorial(num){
        if(num <=1) {
            return 1;
        } else {
            return num * factoral(num-1);
        }
    };

    缺点:

    var anotherFactorial = factorial;
    factorial = null;
    alert(anotherFactorial(4));  //VM367:5 Uncaught ReferenceError: factoral is not defined

    形式2: 使用 arguments.callee

    function factorial2(num){
        if(num <=1) {
            return 1;
        } else {
            return num * arguments.callee(num-1);
        }
    };
    var anotherFactorial = factorial2;
    factorial2 = null;
    alert(anotherFactorial(4));  //24

    闭包与变量

    • 假设,函数A内部声明了个函数B,函数B引用了函数B之外的变量,并且函数A的返回值为函数B的引用。那么函数B就是闭包函数。
    • 内部函数可以访问定义在外部函数中的所有变量和函数,以及外部函数能访问的所有变量和函数。
    • 当内部函数生存周期大于外部函数时,由于内部函数可以访问外部函数的作用域,定义在外部函数的变量和函数的生存周期就会大于外部函数本身。

    特点:

    1. 函数定义时的作用域链到函数执行时依然有效
    2. 闭包只取得包含函数中任何变量的最终值

    形式1: 

    function func1() {
        var result = new Array();
        for (var i = 0; i < 10 ;i++) {
            result[i] = function(){  // 外部函数变量得生命周期大于函数本身,闭包取到的总是外部函数最后的变量值 10 
                return i;
            }
        };
        return result;
    };
    res = func1();
    res[1]();  //10
    res[9]();  //10

    形式2:

    function func2() {
        var result = new Array();
        for (var i = 0; i < 10 ;i++) {
            result[i] = function(num){   
                return function(){
                    return num;
                }
            }(i);  //  创建一个匿名函数并立即执行,将执行结果赋值给变量,匿名函数的参数复制i的值并又在它的闭包中保持
        };
        return result;
    };
    res = func2();
    res[1]();  //1
    res[9]();  //9

     this对象

    this对象是在函数运行时基于函数执行环境绑定的:

    • 在全局函数中,this等于window。
    • 函数作为某个对象得方法调用时,this等于那个对象。
    • 匿名函数的执行环境具有全局性。

    this等于window示例:

    /*
     每个函数在被调用时,会自动获取两个特殊变量:this、arguments
     内部函数在搜搜这两个变量时只会搜索到其活动对象为止
     因此永远不可能直接访问外部函数中的这两个变量
    */
    var name = "the Window";
    var object = {
        name: "the Object",
        getNameFunc: function(){
            return function(){
                return this.name; 
            }
        }
    };
    alert(object.getNameFunc()());  //the Window

    this等于Object, that等于this示例:

    var name = "the Window";
    var object = {
        name: "the Object",
        getNameFunc: function(){
            that = this;  //getNameFunc作为object的方法,在getNameFunc中this等于object
            return function(){
                return that.name;
            }
        }
    };
    alert(object.getNameFunc()());  //the Object

    模仿块级作用域

    javascript没有块级作用域:

    function outputNumbers(count){
        for (var i=0; i < count; i++) ;  //do nothing
        alert(i); //块语句中定义的变量,在所在函数内都有效
    }

    模拟块级作用域:

    function outputNumbers(count) {
        (function(){
            for (var i = 0; i<count; i++){
                alert(i);
            }
        })();  //定义匿名函数并立即执行,执行完后其定义的变量也会销毁
        alert(i);  //VM1909:7 Uncaught ReferenceError: i is not defined
    }

    访问私有变量

    普通方式:

    特点:

    1. 私有变量 name 在所有实例中都不同
    2. 每一个实例都会重新创建同样的一组私有方法(缺点)
    function MyObject(){
        //私有变量
        var privateVariable = 10;
        //私有方法
        function privateFunction(){
            return false;
        }
        //特权方法
        this.publicMethod = function(){
            privateVariable++;
            return privateFunction();
        }
    }
    var test = MyObject();
    test.publicMethod();  //访问私有变量

    静态私有变量:

    特点:

    1. 只有1个私有作用域
    2. 特权方法是在原型上定义的,因此所有实例都使用同一个函数
    3. 特权方法,作为一个闭包,总是保存着对包含作用域的引用
    4. 由1和3结合,所以任何一个实例改了私有变量,所有实例都感应变化
    var Person;
    (function(){
            var name = "";
            Person = function(value){
                name = value;
            },
            Person.prototype.getName = function(){
                return name;
            },
            Person.prototype.setName = function(value){
                name = value;
            }
        }
    )();
    var person1 = new Person("Nicholas");
    alert(person1.getName());    //Nicholas
    var person2 = new Person("Michael");
    alert(person1.getName());  //Michael
    alert(person2.getName());  //Michael

    call()和apply()

    • call( thisArg[, arg1, arg2, ...]);     //参数列表
    • call( thisArg[, argArray ]);            //参数数组

    两个函数内部的this指针,都会被赋值为 thisArg 对象,这可实现将函数作为另外一个对象的方法运行的目的。

    obj = {
      x: 2,
      y: 5
    };
    function func(){
      return this.x * this.y;
    }
    
    func.call(obj);       // 10
    func.apply(obj);      // 10
  • 相关阅读:
    XAF 如何在工具栏显示多参数
    XAF Study Recources
    常用工具
    Linux下Kill函数用法
    ipv6相关转换
    宣布回归
    微软夏令营
    APEX SDK阅后感
    寻求offer,开始记录我的征程
    衣服模拟结果
  • 原文地址:https://www.cnblogs.com/licongyu/p/5621547.html
Copyright © 2020-2023  润新知