• JavaScript语言精粹2函数对象,函数字面量,调用


    函数,用于指定对象的行为。所谓编程,就是将一组需求,分解成函数和数据结构的技能。

    JavaScript中,函数就是对象,是名/值 对的集合。并拥有一个连接到原型对象的隐藏连接。

    对象字面量,产生一个对象,连接到Object.prototype,函数对象,连接到Function.prototype.

    每个函数对象创建时,会配有一个prototype属性,它的值,是一个拥有constructor属性,且为该函数的对象。

    1 var func = function(){
    2     var num;
    3 };
    4 var a = func.prototype;
    5 console.log(typeof a, a.constructor);//object  function

    函数可以保存在变量,对象和数组中,可以当参数传递给其他对象,函数可以返回函数,可以返回对象。函数是对象,所以函数也拥有方法!比如apply();

    当一个函数被保存为对象的属性时,称它为一个方法。

    创建函数,会给该对象一个“调用”的属性,JavaScript调用函数,理解为调用它的“调用”属性。

    函数字面量

    //创建一个名为add的变量,并用来把求两个数和的函数,赋值给它
    var add = function(a,b){ 
        return a+b;
    };

    函数字面量包括4部分

    1关键字function

    2函数名,函数可以调用自己的名字,递归。无名是匿名函数anonymous

    3形式参数,多个用逗号隔开

    4包含在花括号中的一组语句,即函数主体。

    函数可以被定义在其他函数之中,一个内部函数,除了可以访问自己的参数和变量,还可以访问,嵌套它的函数的参数和变量。

    通过函数字面量创建的函数对象,包含着一个连到,外部上下文的连接,称为闭包closure

    调用一个函数,会暂停当前函数的执行,传递控制权和参数给新函数。除了声明时定义的形式参数外(调用时的实参,小于,形参个数,会默认补给undefined,当大于形参个数时,即忽略超出的)每个函数还接收两个附加的参数this和arguments。this在面向对象中非常重要,它取决调用的模式。

    JavaScipt有四种调用模式:1方法调用模式2函数调用模式3构造器调用模式4apply调用模式

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>方法,函数调用模式this</title>
     6 
     7 </head>
     8 <body>
     9     
    10 </body>
    11 </html>
    12 <script type="text/javascript">
    13     // var value = 10;
    14     var add =function (a,b){
    15         //add(3,4);这样调用函数的时候!this绑定到windows全局对象上
    16         var str = "外函数的字符串";
    17         console.log(this);
    18         // console.log(this.a,this.b); //this绑定到window,此时window中没有a b属性所以 undefined
    19         var speed = function(){
    20             console.log(this);//this绑定在 全局对象window
    21             console.log("inner Mthod");
    22             console.log(a,b,str);//直接调用外函数的变量
    23         };
    24         speed();
    25         return a+b;
    26     };
    27 /*方法调用模式*/
    28 //当一个函数,被保存为,一个对象的属性,称它为一个方法!当一个方法被调用时,this被绑定到该对象上。
    29 
    30     //创建一个对象,它有一个value属性 increment方法
    31     //incrment方法接收一个可选的参数,如果不是数字,就使用默认设定1
    32     var myObject = {
    33         value: 0,
    34         increment: function (inc){
    35             this.value += typeof inc === 'number' ? inc : 1;
    36             console.log(this);
    37         }
    38     };    
    39 
    40     myObject.increment();
    41     document.writeln(myObject.value);//没传参数,即1
    42     myObject.increment(3);
    43     document.writeln(myObject.value);//此时value已经是1,1+3 = 4
    44     //方法可以使 this访问自己,所属的对象,所以它能,从对象中取值或对 对象进行修改
    45     //this理解为是个,绑定!this到对象的绑定发生在,调用的时候!!!  very late binding 使函数对this高度复用
    46 /*函数调用模式*/
    47     console.log(add(3,4)); //add(a,b)是window对象的方法,this此时绑定,全局对象window
    48     console.log(window.add(3,4));
    49 
    50 
    51 //为myObject添加一个方法test_double,且该方法中有一个内部函数test_helper
    52     myObject.test_double = function(){
    53         // var that = this;
    54         console.log(this);//此时,以myObject.test_double()方法调用时,this绑定到当前调用此方法Object 属性value是4
    55         var test_helper = function(){
    56             console.log(this,this.value);//此时方法中的内部函数,test_helper函数不是对象myObject的属性!!
    57             //test_helper是以函数调用模式,this绑定在全局对象!window!
    58             this.value = add(this.value,this.value);//undefiend,假设,有个全局变量var value =10,则此处值为add(10,10);
    59             console.log(this.value);//NaN无法计算的值,假设有全局变量var value =10,则此处值为20
    60         }
    61         test_helper();
    62     };
    63     // myObject.test_double();
    64     // document.writeln(myObject.value);//内部的函数没有修改myObject的属性value,此处为4
    65     //在对象myObject中的一个test_double方法,中的一个内部函数test_helper,中this,是绑定在全局对象window,内部函数this不能访问对象myObject的属性value。---文中的"不能共享,该方法对 对象的访问权"!
    66 
    67 //解决对象myObject方法double中 内部函数help,访问对象myObject属性!只需要在方法double中,赋值this给一个方法的变量that
    68     //为myObject添加一个方法 double,且方法中有个内部函数 help
    69     myObject.double = function (){
    70         var that = this;
    71         var help = function(){
    72             that.value = add(that.value,that.value);//当前myObjec的value是4
    73         }
    74         help();
    75     };
    76     myObject.double();//函数double作为对象属性,即是对象的方法调用模式
    77     document.writeln(myObject.value);
    78 
    79 
    80 </script>
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>构造器函数Apply,this</title>
     6 </head>
     7 <body>
     8     
     9 </body>
    10 </html>
    11 <script type="text/javascript">
    12 //构造器调用模式
    13 /*
    14     JavaScript是一门基于原型继承的语言!对象可以从其他对象继承属性!JavaScript是无类型的!
    15 */
    16     //创建一个名为 Quo的构造器函数,它构造带有status属性的对象    
    17     //一个函数,创建的目的就是为了用 new前缀来调用,它被称为构造器函数!约定保存在一个大写的变量中!
    18     var Quo = function(string){
    19         console.log(this);
    20         this.status = string;
    21     };
    22     //给对象所有实例一个公共方法
    23     Quo.prototype.get_status = function(){
    24         console.log(this);
    25         return this.status;
    26     };
    27 
    28     Quo("Right?");//此时,函数不是对象的属性,即不是对象的方法,以函数调用模式,此时,this绑定到window
    29     //当用 new调用,创建了一个对象,this即绑定到新的对象!新的对象即有status属性
    30 
    31     var myQuo = new Quo("confused");//是用 new前缀调用函数,新建一个对象的实例,一个连接到,该函数的prototype成员,的新对象,且this绑定在该对象上
    32     console.log(myQuo.status);
    33     document.writeln(myQuo.get_status());
    34     //不推荐这种形式的构造器函数,会有更好的代替方式
    35 
    36 
    37 //Apply调用模式
    38 
    39 /*
    40     JavaScript是函数式面向对象的语言,函数是对象,所以函数可以拥有方法
    41 
    42 */
    43 
    44 
    45 
    46     //window全局变量
    47     window.a = 12; // 即 var a = 12;
    48     var add = function(a,b){
    49         console.log(a,b);//传人的实参
    50         console.log(this.a,this.b);//window的全局变量中的 a 和 b,没有定义,即undefined
    51         return a+b+"/ "+(this.a+this.b);
    52     };
    53         //创建一个包含两个数字的数组
    54     var array = [3,4];
    55     //apply方法,接收两个参数,一个是绑定this的值,第二个是数组参数,此时的参数是要应用的函数所带的参数!
    56     //apply方法,构建,一个参数数组传递给调用函数
    57     console.log(add.apply(null,array));//第一个参数,this的绑定值设为null,是全局变量window
    58     //add.apply(null,array); 即 add的this.a 是 window.a ,但没有定义b,所以this.a+this.b无法计算是 NaN
    59 
    60     
    61     //---创建一个reObject对象定义
    62     var reObject ={
    63         a: 2,
    64         b: 5,
    65     };
    66     //此处即是reObject对象应用了add()方法,this绑定的是reObject,即this.a 是reObject的a,如果没定义即,undefined
    67     console.log(add.apply(reObject,[6,9]));
    68 
    69 
    70     //创建一个有status成员的对象
    71     var statusObject = {
    72         status: 'A-OK'
    73     };
    74     //statusObject没有 继承  Quo.prototype! 但是可以调用,get_status(),尽管statusObject没有get_status一个方法
    75     //相当于,statusOject应用了get_status函数,get_status()是没有定义参数
    76     var status = Quo.prototype.get_status.apply(statusObject);
    77     //this绑定(指向)statusObject,则应用的方法 get_status中的this.status即是 statusObject的 status!
    78     console.log(status);
    79 
    80 
    81 </script>
  • 相关阅读:
    Eclipse中自动提示的方法参数都是arg0,arg1的解决方法
    eclipse 下找不到或无法加载主类的解决办法
    将博客搬至CSDN
    java接口中定义成员变量
    重写与重载
    多位数每一位个系数:个位num%10;十位num/10%10.......
    输出 n=6 的三角数字阵(JAVA基础回顾)
    二维数组的遍历之查漏补缺
    For循环打印正三角,倒三角,菱形
    JAVA的continue用法
  • 原文地址:https://www.cnblogs.com/concentration-web/p/6348034.html
Copyright © 2020-2023  润新知