二、JavaScript 函数

本文介绍了JavaScript中的函数,包括系统函数如parseInt、parseFloat和isNaN,以及自定义函数的声明和表达式形式。还讨论了函数的调用、闭包的概念以及事件处理,如onload、onclick等。同时,提到了局部和全局变量的使用以及作用域链的重要性。
摘要由CSDN通过智能技术生成

JavaScript 函数

2.1 初始函数

  • 在 JavaScript 中,函数类似于 Java 中的方法,是执行特定功能的 JavaScript 代码。
  • 但是 JavaScript 中的函数使用更简单,不用定义函数属于哪个类,因此调用时不需要用"对象.函数名()"的方式。
  • 直接使用函数名称来调用函数即可。

JavaScript 中有函数有两种:一种时 JavaScript 自带的系统函数,另一种时用户自行创建的自定义函数。

2.1.1 系统函数

  • 在 JavaScript 中, 常用的系统函数有三种,分别是 parseInt()、parseFloat() 和 isNaN()。
  • 其中前两种函数时用于将非数字的原始值转换成数字的函数.
  • 最后一种系统函数是用于检查是否是非数字的函数。

1.parseInt()

  • parseInt() 函数可以解析一个字符串,并返回一个整数,
  • 语法
parseInt("字符串");
  • 在判断字符串是否为数字前,paseInt() 和 paseFloat() 都会分析该字符串。
  • parseInt() 函数首先查看下标为 0 的字符,判断它是否为一个有效数字。如果不是,则返回 NaN,不在继续执行其他操作。
var num1=parseInt("56.64"); //返回值为56
var num1=parseInt("123abc"); //返回值为123
var num1=parseInt("hello999"); //返回值为NaN
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    var num1=prompt("请输入第一个数");
    var num2=prompt("请输入第二个数");
    var parInt1=parseInt(num1);
    var parInt2=parseInt(num2);
    var result=parInt1+parInt2;
    document.write("两个数相加之和为:"+result);
</script>
</body>
</html>

在这里插入图片描述

2.parseFloat()

  • parseFloat() 函数可以解析一个字符串,并返回一个浮点数,
  • 语法
parseFloat("字符串");
  • parseFloat() 函数与 parseInt() 函数的处理方式相似,从下标 0 开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转换为浮点数。
  • 对于 parseFloat() 函数来说,第一个出现的小数点是有效字符,如果有两个小数点,那么第二个小数点被看做无效。
var num1=parseFloat("3.1415926"); //返回值为 3.1415926
var num1=parseFloat("123abc"); //返回值为 123
var num1=parseFloat("hello999"); //返回值为 NaN
var num1=parseFloat("52.18.97"); //返回值为 52.18

3.isNaN()

  • isNaN() 函数用于检查其参数是否是非数字,
  • 语法
isNaN(x);
  • 如果 x 是特殊的非数字,则返回 true;否则返回 false。
var num1=isNaN("20.5");   //返回值为 false
var num1=isNaN("123abc");   //返回值为 true
var num1=isNaN("48.98");   //返回值为 false
  • isNaN() 函数通常用于检测 oarseInt() 函数和 parseFloat() 函数的结果,以判断它们标识的是否为合格的数字,也可以用 isNaN() 函数来检测算术是否错误。

2.1.2 自定义函数

  • 与 Java 语言一样,JavaScript 需要先定义函数,然后才能调用函数。而在 JavaScript 中,定义函数的方式有两种,分别是函数声明和函数表达式。

1.函数声明

  • 在 JavaScript 中,函数声明由关键字 function、函数名、一组参数及大括号中待执行的 JavaScript语句组成。

  • 语法

function 函数名(参数1,参数2,。。。。。){
    //JavaScript 语句;
    [return 返回值] 
}
  • function 时定义函数的关键字,必须有;
  • 参数是函数的参数。
  • 因为JavaScript 本身是弱类型语言,所以它的参数没有类型检查和类型限定。
  • 函数中的参数是可选的,根据函数是否带参数,可分为不带参数的无参函数和带参数的有参函数。
  • 不带参数语法
function 参数名(){
    //JavaScript 语句;
}
  • return 语句用来规定函数返回的值。
  • 要执行一个函数,必须先调用这个函数,当调用函数时,必须指定函数名及其后面的参数(如果有参数)。函数的调用一般和元素的事件结合使用。
  • 语法
事件名="函数名()";
  • 示例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" onclick="study()" value="显示5次欢迎学习 JavaScript">
<script type="text/javascript">
  function study()
  {
    for (let i = 0; i <5 ; i++) {
      document.write("<h4>欢迎学习 JavaScript</h4>")
    }
  }
</script>
</body>
</html>
  • study() 是创建的无参函数;
  • onclick 标识按钮的单击事件,当单击按钮时调用函数 study()。

效果图

在这里插入图片描述

  • 运行一次,页面只能输出5行 “欢迎学习 JavaScript” 。如果需要根据用户的要求每次输出不同的行数,需要用到有参构造函数。
  • 语法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input name="btn" type="button"  value="显示5次欢迎学习 JavaScript" onclick="study(prompt('请输入显示欢迎学习 JavaScript 的次数',''))"/>
<script type="text/javascript">
    function study(count)
    {
        for (let i = 0; i <count ; i++) {
            document.write("<h4>欢迎学习 JavaScript</h4>")
        }
    }
</script>
</body>
</html>
  • count 表示传递的参数,不需要定义数据类型,将 prompt() 方法返回的值作为参数传递给函数 study(count)。
    在这里插入图片描述

2.函数表达式

  • 在 JavaScript 中,把一个函数赋给一个变量,此时形成了函数表达式。
  • 语法
var 变量=function(参数1,参数2,参数3,....){
    //JavaScript 语句;
}
  • 既然有两种定义函数的发昂视,说明二者一定有不一样的地方。
  • 下面使用函数声明的方式定义两个函数名都为 f1() 的函数。
  • 使用函数表达式的方式定义脸啊哥哥函数名都为 f2() 的函数。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    //函数声明
    function f1(){
        console.log("今天天气真好!");
    }
    f1();
    function f1(){
        console.log("今天天气好晴朗,处处好风光");
    }
    f1();
    var f2=function (){
        console.log("哇");
    }
    //函数表达式
    f2();
    var f2=function (){
        console.log("娃哈哈~");
    }
    f2();
</script>
</body>
</html>

在这里插入图片描述

  • 使用函数声明的方式定义两个函数名相同的函数,后面的函数会覆盖掉前面的函数;
  • 而使用函数表达式的方式定义函数,会从上到下逐行执行代码输出结果。

2.1.3 函数自调用

  • 与 Java 不同的是,在自定义函数中,如果函数有名字,如 “function study(){}”,则被称为命名函数;
  • 如果函数没有名字,如"function(){}",则被称为匿名函数。
(function(){
    //函数体
})();
  • 将 “function(){}” 匿名函数放在一对"()" 中,就实现了调用,被称为函数自调用。

  • 特点

    • 没有名字;
    • 在声明的同时直接调用;
    • 不会出现命名冲突。

2.1.5 回调函数

//字符串类型作为参数使用
function f1(x,y){
    console.log(x+y);
}
f1("hello","你好");
function f2(x){
    console.log(x);
}
f2(true);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
  function f1(fn){
    console.log("f1函数调用了");
    fn();
  }
  function f2(){
    console.log("f2函数调用了");
  }
  f1(f2);
</script>
</body>
</html>

在这里插入图片描述

  • f2 函数作为参数传递到 f1() 中,并且在 f1() 函数中执行 fn() 函数,这时,f2() 函数可以被称作回调函数。
  • 如果没有指定函数名称,可以被称作匿名回调函数。

2.2 局部变量和全局变量

  • 在 JavaScript 中,根据变量作用范围的不同,可分为局部变量和全局变量。

2.2.1 局部变量和全局变量的概念及使用

  • 局部变量实在函数内部声明的变量(必须使用 var) ,只能在函数内部访问它。特点是可以在不同的函数中使用名称相同的局部变量。
  • 全局变量是在函数外声明的变量,网页上的所有脚本和函数都能访问它。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
  //全局变量
  var x=10;
  function f1()
  {
    //局部变量
    var y=5;
    console.log(x);
    console.log(y);
  }
  f1();
</script>
</body>
</html>
  • 全局变量和局部变量的区别:作用域不同、声明位置不同、生存期不同。
    • 作用域:局部变量仅作用在函数中,而全局变量作用于整个脚本。
    • 声明位置:局部变量声明的位置在函数中,而全局变量可以声明在使用之前的任何位置。
    • 生存期:局部变量在函数运行以后被删除,而全局变量在页面关闭后被删除。

2.2.2 隐式全局变量

  • 局部变量实在函数内部声明的变量(必须使用var)。如果变量声明时没有var,责备称为隐式全局变量。
  • 语法
var a1=1; //全局变量
a2=2;  //隐式全局变量
  • 在函数内部声明一个局部变量
function f1(){
    num=200; //num按理说应该是一个局部变量
}
f1(num);
  • num本应时局部变量,但没有使用 var 来声明,所以变成了一个隐式全局便令,在函数外部可以访问到num。

2.3 作用域和作用域链

2.3.1 作用域和块级作用域

  • 作用域(Scope) 就是变量与函数的可访问范围,即作用域控制这变量与函数的可见性和生命周期。
  • 块级作用域是由大括号限定的。在块级作用域下,所有的变量都定义在大括号内,从定义开始到大括号结束这个范围内可以使用,除了这个范围就无法访问。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
  //正常带有大括号的语句
  {
    var num=10;
  }
  console.log(num);//10
  if(true)
  {
   var num=20;
  }
  console.log(num);//20
  for (let i = 0; i < 5; i++) {
    var num=30;//30
  }
  console.log(num);//30
  //函数
  function f1(){
    var num=50;
  }
  f1();
  console.log(num);
</script>
</body>
</html>
  • 结果依次为 10、20、30 会报错。

  • 在前三种大括号的情况里面定义的变量,在大括号外面也能使用,即违背了块级作用域的概念。

  • 结论

    • JavaScript 没有块级作用域。
  • f1() 函数内部定义的变量 num 在外部无法访问,原因是在函数作用域下,变量只在函数内部存在。

2.3.2 作用域链

  • 当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级执行上下文的变量对象中查找,一直找到全局上下文的变量对象,即全局对象。
  • 这样由多个执行上下文的变量对象构成的链表就被成为作用域链(Scope Chain)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>作用域链</title>
</head>
<body>
<script type="text/javascript">
  var num=10;  //在script标签里面定义的变量,就是0级作用域
  function f1(){
    var num=20;  //1级作用域
    function f2(){
      var num=30;  //2级作用域
      function f3(){
        var num=50;    //3级作用域
        console.log(num); //50
      }
      f3();
    }
    f2();
  }
  f1();
</script>
</body>
</html>
  • 运行时会发现,控制台输出的值为50.
  • 根据作用域链的概念,一开始执行函数时,现在内部找变量,在内部已经找到,因此就得到了 50.
  • 如果 3 级作用域中没有 var num =50,则会向上一级查找,那么输出的就是30.
  • 如果 2 级作用域没有 var num=30,就会继续向上找,直到找到为止。
  • 如果最终没有找到,则会报错。

2.4 闭包

  • 在函数外部无法读取函数内的局部变量,而闭包是指有权访问另一个函数作用域中的变量的函数。
  • 主要分为两部分
    • 在函数的内部,在定义一个函数。
    • 把内部的函数作为返回值。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>闭包</title>
</head>
<body>
<script type="text/javascript">
  function f1(){
    var num=1;
    function f2(){
      
      alert(num)
    }
    returnf2;
  }
  var result=f1();
  result();
</script>
</body>
</html>
  • f1() 外层函数中声明了一个内部函数 f2(),然后通过 f2() 去操作 f1() 的局部变量,最后把内部函数 f2() 作为返回值。

  • 代码中的内部函数 f2() 就是闭包。

  • 可以把闭包简单地理解成 “定义在函数内部的函数。”

  • 闭包主要的作用

    • 可以读取函数内部的变量
    • 可以让这些变量的值始终保存在内存中。
  • 闭包的缺点

    • 由于闭包可以读取函数内部的变量,所以闭包可以在父函数外部改变父函数内部变量的值。
    • 闭包会是的函数中的变量都被保存在内存中,所以内存消耗大。

不能滥用闭包,否则会造成网页性能的问题。

2.5 事件

事件介绍
onload一个压敏啊或一幅图像完成加载。
onclick鼠标单击某个对象。
onmouseover鼠标指针移到某元素上。
onmouseout鼠标指针离开某元素
onkeydown某个键盘按键被按下
onchange域的内容被改变。

读取函数内部的变量

  • 可以让这些变量的值始终保存在内存中。
  • 闭包的缺点
    • 由于闭包可以读取函数内部的变量,所以闭包可以在父函数外部改变父函数内部变量的值。
    • 闭包会是的函数中的变量都被保存在内存中,所以内存消耗大。

不能滥用闭包,否则会造成网页性能的问题。

2.5 事件

事件介绍
onload一个压敏啊或一幅图像完成加载。
onclick鼠标单击某个对象。
onmouseover鼠标指针移到某元素上。
onmouseout鼠标指针离开某元素
onkeydown某个键盘按键被按下
onchange域的内容被改变。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值