• function 类型


    一、函数的声明方式

    1、普通的函数声明

    function box(num1,num2){
        return num1+num2;
    }
    alert(box(1,2));

    2、使用变量初始化函数

    var box=function(num1,num2){
        return num1+num2;
    }
    alert(box(1,2));

    3、使用Function构造函数

    var box=new Function("num1","num2","return num1+num2");
    alert(box(1,2));

    第三种不推荐,因为这种语法导致解析两次代码(第一次解析常规ECMAScript代码,第二次解析传入构造函数中的字符串)
    ,从而影响性能,但我们可以通过这种语法来理解,函数是对象,函数名是指针的概念

    二、作为值的函数,函数可以传递函数

    1、函数的返回值可以来传递

    function box(sum,num){
        return sum+num;
    }
    function sum(num){
        return num+10;
    }
    var result=box(sum(10),10);   //这里传递的是函数的返回值,和普通变量没区别
    alert(result);

    2、把函数本身作为参数来传递,而不是作为结果

    function box(sum,num){
       return sum(num);
    }
    function sum(num){
        return num+10;
    }
    var result=box(sum,10)   //这里sum是函数,当做参数传递到另外一个函数里,而不是返回值
    alert(result)

    三、函数内部属性

     1、arguments类数组对象,包含了传入函数中所有参数,这个对象还有一个callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数

    function box(num){
        if(num<=1){
            return 1;
        }else{
            return num*box(num-1);    //3*2*1
        }
    }
    alert(box(3));

    以上是一个阶乘或者是递归,box调用了自己,如果很多自我调用修改也许会麻烦,所以用到arguments.callee来调用自己

    function box(num){
        if(num<=1){
            return 1;
        }else{
            return num*arguments.callee(num-1);    //arguments.callee 调用自身,实现递归
        }
    }
    alert(box(3));

     2、this

    四、函数的属性和方法

    1、length   函数希望接收参数个数

    function box(a,b){
        return a+b;
    }
    alert(box.length)    //2

    2、prototype  原型,下面有两个方法 apply()和call(),每个函数都包含这两个非继承而来的方法,这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值

    function box(a,b){
        return a+b;
    }
    function sum(a,b){
        return box.apply(this,[a,b]);   //this表示window作用域,[]表示传递的参数
    }
    function sum1(a,b){
        return box.apply(this,arguments);   //这个可以当数组传递
    }
    alert(box(10,10));alert(sum(10,10));
    alert(sum1(10,10));

    call()和apply()方法相同,他们的区别在于接收参数方式不同。对于call()方法,第一个参数也是作用域,没有变化,变化只是其余的参数都是直接传递给函数的

    function box(a,b){
        return a+b;
    }
    function sum(a,b){
        return box.call(this,a,b);   //this表示window作用域,[]表示传递的参数
    }
    alert(box(10,10));
    alert(sum(10,10));

    以上是对象冒充,其实call()和apply()最大的作用是修改作用域

    var color="hongse";
    var box={
        color:"lanse"
    }
    function sayColor(){
        alert(this.color);
    }
    sayColor.call(window);    
    sayColor.call(this);    //this就是window
    sayColor.call(box);

    ----------------------------------------------进阶----------------------------------------------

    1、当函数作为对象的方法时,this指向该对象

    2、作为普通函数调用时(当函数不作为对象属性调用时,也就是普通函数方式,此时的this总是指向全局对象,在JavaScript中,这个全局对象是Window对象

    例子1:

    var myObject={
      name:"sven",
      getName:function(){
        return this.name;
      }
    }
    console.log(myObject.getName())     //sven
    var myObject1=myObject.getName;
    
    window.name="lee";
    
    console.log(myObject1())     //lee

    例子2:

    var div=document.getElementById('div1');
    div1.onclick=function(){
      console.log(this);     //这里的this是dom节点
      function callback(){
        console.log(this);    //这里的this是window,因为是作为普通函数调用的
      }
      callback();
    }
    -------修改方法,callback.call(this)

    3、使用new调用构造器时,如果构造器显示返回一个object类型的对象,那么这次结果最终会返回这个对象,而不是之前期待的this

    例1

    var myObject=function(){
      this.name="sven";
      return {
        name : "anne"                  //返回object类型
      }
    }
    var obj=new myObject();
    console.log(obj.name)           //输出 anne

    4、Function.prototype.call 或 Function.prototype.apply 调用

    跟普通函数相比,用Function.prototype.call 或 Function.prototype.apply可以动态的改变传入函数的this

    例1

    var obj1={
      name:"sven",
      getName:function(){
        return this.name;
      }
    }
    var obj2={
      name:"annr"
    }
    console.log(obj1.getName());          //输出 sven
    console.log(obj1.getName.call(obj2));   //输出 anne
    -------------call是function方法-----------

    5、call和apply

    apply接收两个参数,第一个参数指定了函数体内this对象的指向,第二个是个集合(可以是数组,也可以是类数组)

    var func=function(a,b,c){
      console.log([a,b,c]);
    }
    func.apply(null,[1,2,3])    //[1,2,3]

    其实和之前学的是一样的,调用函数的时候,都省略了call或apply,比如调用 a(),其实是a.apply()的缩写,只不过,第一个参数是null,函数体内的this会指向默认的宿主对象,在浏览器中则是window

    var func=function(a,b,c){
      console.log(this===window);
    }
    func.apply(null,[1,2,3])

    ***借用其他对象的方法

    有时候我们使用call或者apply的目的不在于指定this指向,而是另有用途,比如借用其他对象的方法,传入null代替某个具体的对象

    Math.max.apply(null,[1,2,5])     //5

    借用Array.prototype对象上的方法,往arguments中添加一个新的元素,通常会借用Array.prototye.push方法

    (function(){
      Array.prototype.push.call(arguments,3)
      console.log(arguments)
    })(1,2)     //[1,2,3]
    
    
    把任意对象传入Array.prototype.push
    var a={};
    Array.prototype.push.call(a,"frist");
    a[0];       //frish   
    a.length;   //1

    想把arguments转成真正的数组的时候,可以借用Array.prototype.slice方法,想截去arguments列表的头一个元素的时候,可以借用Array.prototype.shift方法

    (function(){
      Array.prototype.slice.call(arguments)
      console.log(arguments)
    })(1,2)         //[1,2]
    
    
    (function(){
      Array.prototype.shift.call(arguments)
      console.log(arguments)
    })(1,2)     //[2]
  • 相关阅读:
    [rabbitmq] python版本(二) 工作队列
    [rabbitmq] python版本(一)HelloWorld
    rabbitmq安装上手
    leetcode1 两数之和
    mybatis学习笔记(一)入门上手
    神经网络简介
    hexo+github pages搭建个人博客
    简单RTSCamera实现
    数据结构复习:树
    LINQ
  • 原文地址:https://www.cnblogs.com/change-oneself/p/5027149.html
Copyright © 2020-2023  润新知