Javascript高级浅谈一二

创建函数的方式

  • 声明式

      function foo(){
          consolo.log(arguments);
      }
      foo(1,2,'3',{name:'ksir'});
    
  • 表达式

      var foo = function() {
          console.log(arguments);
      };
      foo(1,2,'3',{name:'ksir'});
    }
    
  • 构造函数
      //Function(arg1,arg2,...,argN,body);所有的参数类型均为字符串
      //arg1,arg2,...,argN 为可选的形参列表,表达为创建出来的函数的形参列表,数据类型字符串类型
      //body 为必选参数,字符串类型,表达为:创建出来的函数的函数体部分
      //var = new Function('val1','val2','return val1+val2');
      var foo = new Function('return arguments[0] + arguments[1];');
      console.log(foo(1));
      console.log(foo);
      //函数也是对象
      //__proto__
      console.log(!!foo.__proto__);
    

所有的函数都是Function的实例,也就是说所有的函数的构造函数都是Function,所以所有的函数的原型对象为Function.prototype

将函数称为函数对象

其他对象称为普通对象

绘制函数的原型链

arguments对象属性

  • length 实参的个数
  • callee 返回正在执行的函数,应用在匿名函数递归调用

函数的相关属性

  • caller 返回调用当前函数的函数
  • length 形成那的个数
  • name 存储函数的名字

模拟函数重载

    //如果函数没有传递实参,就直接打印false
    //如果传递一个实参,就将其直接打印出来
    //如果传递两个实参,就将两个实参拼接起来,然后打印出来
    //如果传递一个实参并且类型为数字的话,加1在打印
    function foo(){
    // console.log(arguments.length);
        if (arguments.length === 0) {
            console.log('false');
        }else if(arguments.length === 1 ){
            if (typeof arguments[0] === 'number') {
                console.log(arguments[0] + 1);
            }else{
                console.log(arguments[0]);
            }
        }else if (arguments.length === 2 ){
            console.log(arguments[0] + '' + arguments[1]);
            }else{
            console.log('传入的参数大于2');
        }
    }
    foo();
    foo(1);
    foo('a');
    foo(1,'a');

递归调用

概念: 函数调用自身

  • 递归调用的时候,都要加上递归调用的开始条件
    function foo(){
        foo();
    }
    foo();
  • 实例1:求等差数列第n项的值
    //第一项的值 v
    //等差: d
    //n 等差数列第n项

    function foo(v,d,n){

        if(n < 1 ){
            return undefined;
        }else if( n === 1 ){
            return v;
        }else {
            return foo(v,d,n -1) + d;
        }
    }
    foo (2,2,5);
  • 实例2: fibonacci第n项
    function fib(n){
        if(n < 1){
            return undefined;
        }else if (n === 1 || n === 2){
            return 1;
        }else{
        return fib(n - 1) + fib(n - 2)
        }
    }
    console.log(fib(6));

    //匿名函数的递归调用
    var v = (function (n){
            if(n < 1){
                return undefined;
            }else if (n === 1 || n === 2){
                return 1;
            }else{
                return arguments.callee(n - 1) + arguments.callee(n - 2)
            }
        }(8));
    console.log(v);  

词法作用域

规定变量的作用是由变量定义的位置决定,而不是由使用变量的位置决定,在词法作用域中,只有函数可以分割作用域,在函数内部是一个完整的作用域,与外界隔离,也就是在函数内部可以访问函数外部的数据,单函数外部无法访问内部的数据

变量名(函数名)提升

在js预解析阶段执行的操作
js本身是边解析边执行的

在预解析阶段: 首先分析代码语法,如果有语法错误,就直接抛出异常,其次,将变量名以及函数名提升到当前作用域的最顶端

in 运算符

前面的属性名字须用字符串来表示,如果为变量,那么会将变量的值隐式转换成字符串,然后去判断变量的值是否为指定对象的属性(可以为继承过来的属性)

注意后面的参数必须为对象,否则会报错

赞 赏
微信扫一扫