【又见JavaScript】函数中的知识点整理

相关概念

  • 函数——解耦的方式

  • 最基本的函数写法 - 函数声明

  • 命名建议:小驼峰  myFirstFun(); or 公司内部规范

    function test(param){ 函数执行语句; }

匿名函数表达式(函数字面量)

var test = function test1(){}

// 这种声明情况:
var test = function test1(){
  var a = 1,
      b = 2;
      console.log(a,b); // 1,2
  // test1(); 在函数内部调用,会无限次调用,递归,
  // 电脑不好的谨慎尝试!
}
// 注意!
// test1(); 在函数外调用,是报错“is not defined” ,不可见
// 这个函数的名称可以被调取,是test1
console.log(test.name); // test1
  • 这种声明,实际上,在将函数赋给变量test的时候,会忽略后面写的test1;所以是否写function后面的名称test1,在外部对函数test()进行调用是没有影响的;

    没在 function 后面写函数名称的情况下,这个函数是属于匿名函数

    // 匿名函数表达式
    var test = function(){
      var a = 1,
          b = 2;
          console.log(a,b); // 1,2
    }
    

函数的形参和实参问题

  • 函数形参的默认值为 undefined

  • 隐形参数arguments[]

  • 隐形参数arguments[]与函数的第一个形参是有一定的对应关系的:

    arguments[0] 为 undefined,也就是没有传实参的值的时候,第一个形参有初始化值,不是undefined,形参就会使用初始化值;反之,有传实参值的时候,就是实参的值;

    通过代码来理解:

    // 注意是ES6写法,ES5不支持,低版本浏览器不兼容
    function test (a = 1, b){
      console.log(a);
      console.log(b);
    }
    test(); // 1 undefined
    test(2); // 2 undefined
    test(undefined,2); // 1 2
    
    // 不用上述ES6方法也可以实现
    
    // 通过或运算实现 最推荐写
    function test1 (a, b){
      // 当没有传实参值的时候,arguments为undefined,形参的值就会是后面的那个值
      var a = arguments[0] || 1;
      var b = arguments[1] || 2;
      console.log(a + b);
    }
    test1();  // 3
    test1(3,4); // 7
    
    // typeof 方法实现
    function test2 (a, b){
      // 相对复杂,但是易懂
      let a,b;
      if(typeof(arguments[0]) !== 'undefiend'){
        a = arguments[0];
      }else {
        a = 1;
      }
      if(typeof(arguments[1]) !== 'undefiend'){
        b = arguments[0];
      }else {
        b = 2;
      }
      console.log(a + b); 
    }
    test2(); // 3
    test2(3,4); //7
    
    // 三元运算实现 推荐
    function test3 (a,b){
      var a = typeof(arguments[0]) !== 'undefined' ? arguments[0] : 1;
      var b = typeof(arguments[1]) !== 'undefined' ? arguments[1] : 2;
      console.log(a + b);
    }
    test3(); // 3
    test3(3,4); // 7
    
  • 函数的形参和实参的个数可以不相等

    • console.log(函数名.length) 看形参个数
    • console.log(arguments) 看实参情况
    // 代码逻辑:一个函数被调用时,累加它的实参值
    // 实参求和的类似题目!!
    function sum(){
      var args = 0;
      for (var i = 0; i < arguments.length; i++){
        args += arguments[i];
      }
      console.log(args);
    }
    sum(1,2,3,4,5,6,11);
    
    • 在函数内可以更改在调用时传入的实参的值;但是如果形参没有传入实参的值,在函数内部给形参赋值是没有意义的;

      // 调用时传入实参
      function test(a,b){
        a = 3;
        console.log(arguments[0]); // 3
      }
      test(1,2);  // 传入形参a和b的值的情况
      // 调用时没有传入实参
      function test1(a,b){
        b = 3;
        console.log(arguments[1]); // undefined
      }
      test1(1); // 仅仅传入形参a的值,b并没有传的情况
      
    • 函数中,形参和实参他们所存储的位置不同,但形参和实参是有对应关系的

return 函数的返回值

  • 对于普通函数,就算你没有在函数内写上 return,JS 引擎会在函数内部的最后隐式添加上return undefined

    • return后面的语句不会被执行,而且return也可以返回一系列的数据;
    • 对于构造函数,会默认return this;
    function test(name){
      return name || '您没有填写姓名!';
    }
    console.log(test('greeny')); // greeny
    console.log(test()); // '您没有填写姓名!'
    
  • 函数体内部可以访问 or 修改外部的变量,但是函数体外部不能访问内部的变量

    a = 1; // 在全局声明、赋值变量
    
    function test1(){
      var b = 2;
      console.log(a,b); // 1 2
      function test2(){
        var c = 3;
        console.log(a,b,c); // 1 2 3
      }
      test2();
      console.log(c); // 报错 is not defined
    }
    //console.log(b,c); // 报错 is not defined
    test1(); // 1 2
    
  • 递归问题

    • 递归:总是走到出口时,才向上一步的返回结果
    • 要使用递归解决问题,要注意:先:找到递归的计算规律,再:找出函数结束的出口
    • 性能上不占优势,慎用;
    // n的阶乘 不能用for循环 -> 递归实现
    // n! = n * (n-1)! 规律
    function fact(n){
      if(n === 1){
        return 1;// 此时return后出现值,会导致前面的队列发生变化
      }
      return n * fact(n - 1);// 此时一直在等有一个值出现
    }
    // n = 5
    // fact(5) = 5* fact(4); ---> fact(5) = 5 * 24 = 120 ----> final result
    // fact(4) = 4* fact(3); ---> fact(4) = 4 * 6 = 24
    // fact(3) = 3* fact(2); ---> fact(3) = 3 * 2 = 6
    // fact(2) = 2* fact(1); ---> fact(1) = 1; --> fact(2)=2 * 1 =2;
    
    console.log(fact(5)); // 120
    

构造函数

系统自带的构造函数
var obj = new Object(); // 与对象字面量相等
obj.name = '张三';
obj.sex = '男士';
自定义构造函数
  • 大驼峰,用于与普通函数区分

    function Teacher(){
      this.name = '张三';
      this.sex = '男';
      this.smoke = function(){
        console.log('im smoking');
      }
    }
    var teacher = new Teacher();
    // 此时this才指向Teacher
    
this 的指向

在没有实例化构造函数对象的时候就指向window,否则在不同的实例化对象中,指向那个实例化的对象,而不是构造函数本身。

在代码中理解:

function Compute(){
  var res = 0;
  this.plus = function() {
   	loop(arguments,'add',res);
  }
  this.times = function() {
    res = 1;
    loop(arguments,'mul',res);
  }
  function loop(args,method,res){
    for(var i = 0; i < args.length; i++){
      var item = args[i]
      if (method === 'add') {
          res += item;
      }else if (method === 'mul') {
      	  res *= item;        
      }
    }
    console.log(res);
  }
}
var compute = new Compute();
compute.plus(2,4,6); // 12
compute.times(3,5,7); // 105
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值