欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript 函数

程序员文章站 2022-03-14 09:46:59
...

JavaScript 函数

函数的声明与调用

在Javascript中,函数就是对象,是一等公民,其应用:

  • 被赋值给一个变量
  • 被赋值为对象的属性
  • 作为参数被传入别的函数作为函数的结果被返回
  • 用字面量来创建

由于函数具备给其它数据类型平等的地位,整个函数也会像变量声明一样,具备函数名提升的特性,被提升到代码的头部。

f();
function f(){}

函数的定义

  • 函数的定义由以下4部分组成:关键字function、函数名、参数和函数体。
    定义命名函数:
function funcName(参数列表){
    statements[return [expr]]
}
function sayHi(name, message){
    alert("hello" + name + ", " + message);
}

函数名可由大小写字母、数字、下划线(_)和$符号组成,但是函数名不能以数字开头,且不能是JavaScript中的关键字。

参数设置

函数在定义时根据参数的不同,可以分为两种类型:

  • 无参函数:适用于不需要提供任何数据,即可完成指定功能的情况。

  • 有参函数:适用于开发时函数体内的操作需要用户传递数据的情况。
    形参:形式参数,具有特定的含义,在定义有参函数时设置的参数。
    实参:实际参数,也就是具体的值,在函数调用时传递的参数。

    示例

function maxNum(a, b) {
   a  =    parseInt(a);
   b  =    parseInt(b);
   return a >= b ? a : b;
}

函数的调用

  • 直接调用:函数名(实参值)
    sayHi(“南工院”, “新学期开学了”);
  • 在表达式中调用
    这种方式适合有返回值的函数,返回值作为表达式的一部分参与运算,有时还会和(alert、document)等语句配合输出。
  • 在事件中调用
<!--单击按钮后,单击事件会调用myfun()函数-->
<input type="button " value="单击" onlick="myfun()"/>

注意点

  • return 语句不是函数必须的,但任何函数在任何时候都可以通过return语句+ 返回的值,实现返回。
  • 若在一个文件中,定义函数名字相同,会使用最后定义的函数

变量的作用域

  • 全局变量:不在任何函数内声明的变量(显示定义)或在函数内省略var声明变量(隐式定义)都称为全局变量。

  • 作用范围:它在同一个页面文件中的所有脚本内都可以使用。

  • 局部变量:在函数体内利用var关键字定义的变量称为局部变量,它仅在该函数体内有效。

  • 块级变量:ES6提供的let关键字声明的变量称为块级变量,仅在"{}"中间有效,如if、for或while语句等。

demo.js文件
var num   = 1;
函数var sum = 0;//局部变量
demo.js文件
var num   = 1;  //块级变量
函数let sum = 0;
for循环let i= 2;  //块级变量

  • 在JavaScript中,局部变量只有在函数的执行过程中存在,而在这个过程中会为局部变量在(栈或堆)内存上分配相应的空间,以存储它们的值,然后在函数中使用这些变量,直到函数结束。
  • 一旦函数执行结束,局部变量就没有存在必要了,此时JavaScript就会通过垃圾回收机制自动释放它们所占用的内存空间。

在开发中若要保留局部变量的值,可以通过以下两种方式实现:

// 第1种方式:利用return返回
function test(num  ) {
     num= num+ 1;return num  ;
}
varnum= test(24);
console.log(num);//输出结果:25
// 第2种方式:利用全局变量保存
var memory;function test(num  ) {
      memory = num+ 1;
}
test(24);
console.log(memory);// 输出结果:25
  • 在代码中任何地方都能访问到的对象拥有全局作用域。
  • 所有未声明直接赋值的变量自动拥有全局作用域。
  • 所有window对象的属性拥有全局作用域。
  • 作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。

函数声明

  • 概念:使用function关键字声明函数。

函数表达式

  • 概念:函数表达式指的是将声明的函数赋值给一个变量,通过变量完成函数的调用和参数的传递,是JavaScript中另一种实现自定义函数的方式。
var fn  = function sum(num1, num2) {
    return num1 + num2;
};
fn ();
sum();
function sum(num1, num2) {
     return num1 + num2
;};

这两种不同点:① 函数的定义方式不同② 函数的调用方式不同③ 函数定义与调用顺序不同

  • 第3种声明函数的方式是Function构造函数【了解】
var add = new Function(
     'num1', 
     'num2', 
     'return num1 + num2');
     console.log(add(1, 2));

匿名函数

  • 概念:匿名函数指的是没有函数名称的函数。
  • 作用:可以有效的避免全局变量的污染以及函数名的冲突问题。
  • 说明:既是函数表达式的另一种表示形式,又可通过函数声明的方式实现调用。
//函数表达式中省略函数名
var fn = function (num1, num2) {
return  num1 + num2;
};
fn(1, 2);
//自调用方式
(function (num1, num2) {
       return  num1 + num2;
 })( 1,  2);

//处理事件
document.body.onclick  = function () {
     alert('Hi, everybody!');
     };
  • 自调用方式也称为立即执行函数,此函数只能是函数表达式,不能是函数声明。
  • 它的作用是:创建一个独立的作用域,避免被同名变量覆盖。
    箭头函数
  • 概念:ES6中引入了一种新的语法编写匿名函数,我们称之为箭头函数。
  • 特点:一个箭头函数表达式的语法比一个函数表达式更短。
    参数(p1, p2, ..., pN) => { statements }函数体
示例
// 设置1个参数
var fn1 = x => x + 2;
// 输出结果:6
console.log(fn1(4));

// 设置2个参数
var fn2 = (x, y) => x + y;
// 输出结果:3
console.log(fn2(1, 2) );

箭头函数中箭头"=>"不是操作符或者运算符,但是箭头函数相比普通的函数受操作符的优先级影响。

回调函数

  • 概念:回调函数指的是一个函数A作为参数传递给一个函数B,然后在B的函数体内调用函数A。函数A称为回调函数。
  • 提示:匿名函数常用作函数的参数传递,实现回调函数。
  • 应用:函数体中某部分功能由调用者决定,此时可以使用回调函数。
  • 在JavaScript中还为数组提供了很多利用回调函数实现具体功能的方法。
方法名称 功能描述
find() 返回数组中满足回调函数的第一个元素的值,否则返回
undefinedevery() 测试数组的所有元素是否都通过了回调函数的测试
some() 测试数组中的某些元素是否通过由回调函数实现的测试
forEach() 对数组的每个元素执行一次提供的函数
map() 创建一个新数组,其结果是该数组中的每个元素都调用一次提供的回调函数后返回的结果
reduce() 对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值
reduceRight() 接收一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值
  • 以map()方法为例,对arr数组中的每个元素都按顺序调用一次回调函数。
    array.map(function(currentValue,index,arr), thisValue)
var arr   = ['a', 'b', 'c'];
arr.map(function(value, index) {
console.log(value, index);
});
  • 参数:
    map()的参数是一个回调函数fn。
    fn的第1个参数表示当前数组的元素。
    fn的第2个参数表示对应元素的索引下标。
  • 返回值:回调函数每次执行后的返回值会组合起来形成一个新数组。示例结果:在控制台依次可查看到 ,“a 0”、“b 1"和” c 2"。

map()方法实现二维数组的转置

 vararr= [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; // 待转置的数组
 varreverse = arr[1].map(function (col, i) {   // 利用i获取转置后数组元素的下标
 return arr.map(function (row) {   // 返回转置后新组合而成的数组元素
 return row[i];    // 返回转置前数组元素的指定索引的元素});});

具体实现

闭包函数

  • 在JavaScript中,内嵌函数可以访问定义在外层函数中的所有变量和函数,并包括其外层函数能访问的所有变量和函数。但是在函数外部则不能访问函数的内部变量和嵌套函数。此时就可以使用"闭包"来实现。

  • 所谓"闭包"指的是有权访问另一函数作用域内变量(局部变量)的函数,也就是闭包由函数以及创建该函数的词法环境组合而成。

  • 它最主要的用途是以下两点:
    可以在函数外部读取函数内部的变量。
    可以让变量的值始终保持在内存中。

  • 注意由于闭包会使得函数中的变量一直被保存在内存中,内存消耗很大,所以闭包的滥用可能会降低程序的处理速度,造成内存消耗等问题。

闭包函数的实现
常见创建方式:就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量

function fn() {
var times = 0;
var c = function () {
                 return ++times;
            };
    return c;   
 }

var count = fn(); // count是一个闭包
// 访问测试示例
console.log(count());
console.log(count());
console.log(count());
console.log(count());
console.log(count());

用闭包模拟私有方法,提供类似面向对象的数据隐藏和封装。

var makeCounter= function() {
    var privateCounter= 0;
    function changeBy(val  ) {
       privateCounter+=   val  ;
}return {
    increment: function() {
       changeBy(1);
    },
    decrement: function() {
        changeBy(-1);
    },
    value: function() {
        return privateCounter;
    }
  }  
};
var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */示例

常用内置函数

内置函数与任何对象无关,可直接使用

  • decodeURI:对用encodeURI方法编码的字符串进行解码。
  • decodeURIComponent:对用encodeURIComponent方法编码的字符串进行解码。
  • encodeURI:将字符串编码为一个有效的统一资源标识符(URI)。
  • encodeURIComponent:将字符串编码为URI的一个有效组成部分。
  • eval:解析JavaScript代码并执行。
  • parseFloat:返回由字符串转换得到的浮点数。
  • parseInt:返回由字符串转换得到的整数。
  • isFinite:返回一个Boolean值,指明所提供的数字是否为有限值。
  • isNaN:返回一个Boolean值,指明提供的值是否为保留值NaN(不是数字)。
  • escape:对字符串进行编码以便它们能在所有计算机上可读。
  • unescape:对用escape进行编码的字符串进行解码。
相关标签: 函数