zoukankan      html  css  js  c++  java
  • Function 构造器及其对象、方法

    一、基础

    Function 是一个构造器,能创建Function对象,即JavaScript中每个函数实际上都是Function 对象。

    构造方法:  new Function ([arg1[, arg2[, ...argN]],] functionBody)  

    说明:arg1、arg2等为构造器的参数,functionBody为方法体。注意:参数必须用引号包围!

    实例:

    var plus=new Function("a","b","return a+b");  
    var result=plus(1,2);//调用,返回3  

    上述方法创建function等同于普通函数声明方法:

      function plus(a,b){return a+b;};  

    重点:

    1、使用Function构造器生成的对象是在函数创建时解析的(即真正调用时才生成对象的模型),所以比普通函数声明方法低效,因为普通方法是和其它代码一起解析的;

    2、此方法不支持闭包,即不能访问创建他的所在function对象的私有变量,而只能访问自身参数列表中的变量和全局变量,因此一般只作为全局函数时使用。如:

    <script>  
    var test=1;//用于测试的全局变量  
    var plus=new Function("a","b","return a+b+test");  
    alert(plus(1,2));//将提示结果为4,即访问到了test变量  
    function adder(value){  
        var number=value;//定义私有变量  
        alert("标记1");  
        this.method=new Function("a","b","return a+b+number");  
    }  
    var operation=new adder(1);  
    alert("标记2");  
    alert(operation.method(1,2));//提示了标记1与标记2,但此处没结果(出错),若将method的定义中number改为全局变量test,将运行出结果4。可见Function构造器方法确实不能实现闭包。  
    </script>  

    二、原型的属性

    属性:

    1、arguments属性:(已不建议使用)

    function.arguments 属性:代表传入函数的实参,它是一个类数组对象。已废弃。例:

    function test(var1,var2){  
    alert(test.arguments[0]+test.arguments[1]);  
    }  

    注意:

    1)、使用函数名调用;2)、arguments数组访问的是本次函数调用时传入的实参,而非上一次调用时的参数(对于嵌套或循环调用需注意!)。推荐使用函数内部的arguments对象:。

    arguments对象:

    该对象是函数内部的本地变量,而不是函数的属性。使用示例:

    function test(var1,var2){  
    arguments[0]=0;//可改变参数的值  
    alert(arguments[0]+arguments[1]);  
    }  
    test(1,2);//将提示结果为2  

    说明:

    arguments对象并不是一个真正的Array对象,没有数组的属性与方法(length除外)。可通过继承数组的slice方法获得参数数组: 

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

    不建议使用此方法获得参数数组,因为slice方法会影响js引擎的优化(如v8引擎)。最好使用遍历arguments获取参数生成数组。

    arguments对象属性:

    length、callee等。arguments.callee返回该arguments对象所属的函数构造器(即函数),从而可实现匿名函数的递归等。如: 

    function create() {  
       return function(n) {  
          if (n <= 1)  
             return 1;  
          return n * arguments.callee(n - 1);//调用该arguments所属的匿名函数构造器。  
       };  
    }  
    var result = create()(5); // returns 120 (5 * 4 * 3 * 2 * 1)  

    说明:全兼容。

    具体查看:

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments

    2、caller属性:返回调用函数名

    例:

    function myFunc() {  
       if (myFunc.caller == null) {  
          return ("该函数在全局作用域内被调用!");//在全局被调用时caller值为null  
       } else  
          return ("调用我的是函数是" + myFunc.caller);  
    }  

    说明:全兼容。

    3、length:函数期望的参数个数

    length 是函数对象的一个属性值,指明该函数期望多少个参数,意即形参的个数。数量不包括剩余参数。相比之下,  arguments.length 是函数被调用时实际传参的个数。

    4、name:字符串形式返回函数名

    例:alert(test.name);//弹出test函数的函数名test。

    注:有的浏览器不支持。

    5、prototype:原型,最重要的属性

    三、方法

    apply()、call()、bind()、toSource()、toString()、isGenerator()六个。

    1、apply方法

    常用,语法:

     B.prototype.method.apply(A [,args]); 

    作用:

    构造器B的原型的method方法(也即B的对象所具有的方法,理解了原型链此处很好理解)提供给对象A,使用,args为需要传入的method的参数,为数组或数组字面量(如[1,2]的形式)。

    注意:

    B必须为构造器名(即函数名),A为某个将使用此method函数的对象。

    示例: 

    function A(var1,var2){  
        this.v1=var1;  
        this.v2=var2;  
        //this.method=function(){ alert(this.v1+this.v2);}此种方式将不能应用apply等方法  
    }  
    A.prototype.method=function(){ alert(this.v1+this.v2);}  
    function B(){  
        this.v1=10;  
        this.v2=20;  
    }  
    var a=new A(1,2);  
    b=new B();  
    a.method();//提示结果:3  
    A.prototype.method.apply(b);//将构造器A的method方法应用与对象b。因为method没有参数,所以参数数组省略。  
    b.method();//真正调用,若带有参数,此处可不用再写,写在apply参数列表即可。提示结果:30  

    更深细节:

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

    2、call方法

    与apply方法相似,但参数采用参数列表的形式。

    语法:

     fun.call(thisArg[, arg1[, arg2[, ...]]]) 
    此处fun可是任何方法,将fun方法用于thisArg对象,也实现了继承的模拟(thisArg相当于继承了fun方法)。

    示例:

    [plain] view plain copy
     
    function Product(name, price) {  
      this.name = name;  
      this.price = price;  
      
      if (price < 0) {  
        throw RangeError('Cannot create product ' +  
                          this.name + ' with a negative price');  
      }  
    }  
    function Food(name, price) {  
      Product.call(this, name, price); //Food对象继承了Product方法  
      this.category = 'food';  
    }  

    上面的Food相当于:

    [plain] view plain copy
     
    function Food(name, price) {   
        this.name = name;  
        this.price = price;  
        if (price < 0) {  
            throw RangeError('Cannot create product ' +  
                    this.name + ' with a negative price');  
        }  
      
        this.category = 'food';   
    }  

    3、bind方法

    语法:

     fun.bind(thisArg[, arg1[, arg2[, ...]]]) 

    作用:

    将fun方法绑定给thisArg对象。相当于将方法fun写在thisArg的构造器里面,所以fun里面使用到的this此时指的是fun所属的thisArg 对象。

    示例:

    [plain] view plain copy
     
    this.x = 9;   
    var module = {  
      x: 81,  
      getX: function() { return this.x; }  
    };  
    module.getX(); // 返回 81  
    var retrieveX = module.getX;  
    retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域  
      
    // 创建一个新函数,将"this"绑定到module对象  
    // 新手可能会被全局的x变量和module里的属性x所迷惑  
    var boundGetX = retrieveX.bind(module);  
    boundGetX(); // 返回 81  

    Function 是引用类型,所以也具有length属性、valueOf与toString 方法。应该将所有function都看做Function 的对象,函数名即该对象的引用!

    上面只是基本用法,更多知识参考手册!

    参考:

    MDN知识库Function属性与方法:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/caller

    道法自然
  • 相关阅读:
    软件下载
    01_动态规划之01背包问题
    25_使用切片建立一个动态的二位数组.go
    为什么突然想起来写博客
    24_切片的使用
    23_随机数的生成和冒泡排序
    22_数组做函数参数
    21_一维数组和二位数组的使用
    20_指针类型的使用
    19_获取命令参数
  • 原文地址:https://www.cnblogs.com/whqblog/p/9013116.html
Copyright © 2011-2022 走看看