zoukankan      html  css  js  c++  java
  • JS对象类型函数篇函数参数

    JS中函数定义时不需要指定参数的类型,函数调用时也不会对传入的参数进行类型检查,甚至参数的个数也不做检查,了解这些特殊情况,避免开发出错。

    参数个数

    当实参比形参的个数少时,多余的形参会被设置成undefined。

    function fn(a,b,c){
      console.log(c) // undefined
    }
    
    fn(1,2) 
    

    当实参比形参的个数多时,多余的实参在函数中无法直接获取到,可以通过arguments对象获取。

    function fn(a,b) {
      console.log(arguments[0],arguments[1],arguments[2]) // 1 2 3
    }
    
    fn(1,2,3)
    

    JS函数中的参数在内部是用一个数组表示的,可以通过arguments对象访问这个参数数组,从而获取到传入给函数的每一个参数。

    注意: arguments对象是一个类数组对象,不是Array对象的实例。可以使用方括号语法访问每一个元素。

    arguments对象的length属性显示实参的个数,函数的length属性显示形参的个数。

    function fn(a,b) {
      console.log(arguments.length) // 3
      console.log(fn.length) // 2
    }
    fn(1,2,3)
    

    参数同步

    在严格模式下,arguments对象的值和形参是独立的。在非严格模式下,它们的值是同步的。

    // 示例1
    
    function fn(a) {
      'use strict'
      console.log(a, arguments[0]) // 1 1
      
      a = 2
      console.log(a, arguments[0]) // 2 1
      
      arguments[0] = 3
      console.log(a, arguments[0]) // 2 3
    }
    fn(1)
    
    
    // 示例2
    function fn(a) {
      console.log(a, arguments[0]) // 1 1
      
      a = 2
      console.log(a, arguments[0]) // 2 2
      
      arguments[0] = 3
      console.log(a, arguments[0]) // 3 3
    }
    fn(1)
    

    callee属性

    arguments对象的callee属性是一个指针,指向拥有这个arguments对象的函数。

    注意: 严格模式下禁止使用该属性,会报错

    // 阶层函数
    function factorial(num) {
      if(num <=1) {
    	return 1
      } else {
    	return num * factorial(num - 1)
      }
    }
    
    factorial(3) // 6
    

    上面的函数有一个问题,就是函数的执行和函数名耦合在了一起,这时可以使用callee属性解决这个问题。

    function factorial(num) {
      if(num <=1) {
    	return 1
      } else {
    	return num * arguments.callee(num - 1)
      }
    }
    
    factorial(3) // 6
    

    由于callee属性在严格模式下报错,可以使用具名函数表达式。

    var factorial = function fn(num){
      if(num <=1){
        return 1
      }else {
         return num * fn(num - 1)
      }
    }
    factorial(3) // 6
    

    caller属性

    arguments对象的caller属性不是一个标准属性,不赞成用于生产环境,但浏览器都支持它。该属性保存了调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值是null。

    注意: 严格模式下禁止使用该属性,会报错

    // 示例1
    function outer() {
      inner()
    }
    
    function inner() {
      // inner是当前函数,outer是调用当前函数的函数
      console.log(inner.caller) // outer() { inner() }
    }
    outer()
    
    // 示例2
    function inner() {
      console.log(inner.caller)
    }
    
    inner() // null 
    

    函数重载

    函数重载简单理解就是同一个函数,可以根据不同的参数(比如类型不同或数量不同)执行不同的处理逻辑。

    由于JS无法为同一个函数编写不同的定义标签,所以真正的重载是做不到的,只能通过检查传入函数中参数的类型和数量作出不同的反应,来模仿方法的重载。

    function doAdd(){
        if(arguments.length == 1){
            alert(arguments[0] + 10);
        }else if(arguments.length == 2){
            alert(arguments[0] + arguments[1]);
        }
    }
    doAdd(10);//20
    doAdd(30,20);//50
    

    参数传递

    【基本类型值】向参数传递基本类型值时,被传递的值会复制给一个局部变量(命名参数或arguments对象中的一个元素)

    function fn(num) {
      num += 10
      return num
    }
    
    var count = 10
    var result = fn(count)
    
    console.log(count) // 10 原始值不会改变
    console.log(result) // 20
    

    【引用类型值】向参数传递引用类型值时,被传递的值的引用地址复制给一个局部变量,所以局部变量的变化会反映到外部函数上。

    function fn(obj) {
      obj.name = 'hello'
    }
    var person = new Object()
    fn(person)
    
    console.log(person.name) // 'hello'
    

    如果在函数内部重写引用类型的形参,被传递的值就会成为一个局部变量,局部变量会在函数执行结束后立即销毁

    function fn(obj) {
      obj = new Object();
      obj.name = 'hello';
    }
    var person = new Object()
    fn(person)
    
    console.log(person.name) // undefined
    
    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    Leetcode Plus One
    Leetcode Swap Nodes in Pairs
    Leetcode Remove Nth Node From End of List
    leetcode Remove Duplicates from Sorted Array
    leetcode Remove Element
    leetcode Container With Most Water
    leetcode String to Integer (atoi)
    leetcode Palindrome Number
    leetcode Roman to Integer
    leetcode ZigZag Conversion
  • 原文地址:https://www.cnblogs.com/yesyes/p/15351892.html
Copyright © 2011-2022 走看看