JavaScript函数详解

简介: JavaScript函数的详细解析,包括函数的定义和调用方式(如一般格式、匿名函数、构造函数、自调用函数、箭头函数和严格模式)、函数参数(arguments对象、可变参数、默认参数值)、闭包的概念和应用实例。

函数的定义和调用

1.函数的一般格式

function sum(a,b){
   
    return a+b;
}
sum(1,2);//3

2.函数表达式(匿名函数)

var c= function(a,b){
   
    return a+b;
};
// 函数表达式可以保存到变量中,通过变量名来调用
console.log(c(1,2));// 3

3.构造函数

var fct1 = new Function("a","b","return a+b");
console.log(fct1);//打印输出一个函数,如下图
console.log(fct1(1,2));//3

//等同于
var fct2 = function(a,b){
   
    return a+b;
}

在这里插入图片描述

4.自调用函数

函数表达式可以 “自调用”。
自调用表达式会自动调用。
如果表达式后面紧跟 () ,则会自动调用。
不能自调用声明的函数。
通过添加括号,来说明它是一个函数表达式:

//自调用函数
 var a(function ptr(){
   
     console.log("hello!");
 })();
 //控制台输出打印hello,注意我们并未调用它

//匿名自调用函数
var c=(function (){
   
    console.log("hi");
})();

5.箭头函数

ES6新增了箭头函数 ,其格式为

(参数列表)=>{ 函数声明 }
等同于
(参数1,参数2,参数3....)=>{ return 表达式 }
当只有一个参数时,参数外面的括号可有可无。(参数)=>{ 函数声明 }或者参数=>{ 函数声明 }
当没有参数时,写成一对圆括号()=>{ 函数声明 }

//示例
//ES6
let sum1 = (x,y)=>x + y;
console.log(sum1(1,2));//3
//ES5
var sum2 = function(x,y){
   
return x+y;
}
console.log(sum2(1,2));//3

6.Javascript 严格模式

使用"use strict"指令,在严格模式下不可以使用未声明的变量,(JS实在是太随意了).

"use strict"
console.log(a);// Uncaught ReferenceError: a is not defined
a = 3.14;
console.log(a);// Uncaught ReferenceError: a is not defined

在这里插入图片描述
使用 use strict ,在编辑器中也会提示相关错误。
在这里插入图片描述
其中a变量是未声明类型,b变量中的灰色虚线则是var类型不建议使用,使用let,或者const(转为常量)。

7.对象中的方法–函数

绑定到对象上的函数称为方法,和普通函数没啥区别,但是它在内部使用了一个this关键字.

 "use strict"
 var xiaoming = {
   
     name: '小明',
     birth: 2001,
     age: function () {
   
         var y = new Date().getFullYear();
         return y - this.birth;
     }
 };
 xiaoming.age; // function xiaoming.age()
 xiaoming.age(); // 21

等同于

 function getAge() {
   
     var y = new Date().getFullYear();
     return y - this.birth;
 }

 var xiaoming = {
   
     name: '小明',
     birth: 2001,
     age: getAge
 };

 xiaoming.age(); // 21, 正常结果
 getAge(); // NaN
apply()方法 和call()方法

通过apply()方法或者call()方法,将this引用到指定对象。
当需要传递参数时,call可以直接写多个参数,apply需要用数组方式传递(它俩默认第一个参数都是this引用的对象)。

function getAge() {
   
    var y = new Date().getFullYear();
       return y - this.birth;
}

var xiaoming = {
   
    name: '小明',
    birth: 2001,
    age: getAge
};

xiaoming.age(); // 21, 正常结果
getAge(); // NaN
getAge.apply(xiaoming,[]);//通过 apply 可以指定this 指向某个对象,参数列表为空 打印输出 21
getAge.call(xiaoming);//通过call 可以指定this 指向某个对象21

this就是当前对象自身的指代。

函数参数

显示参数和隐式参数(arguments)

参数规则:
1.JavaScript 函数定义显式参数时没有指定数据类型。
2.JavaScript 函数对隐式参数没有进行类型检测。
3.JavaScript 函数对隐式参数的个数没有进行检测。

arguments对象

arguments对象,Javascript免费赠送的一个关键字(皮一下),arguments对象中包含了函数调用的形参数组。

既然它是形参数组,就表示它应该有任意多个。

//来试试找一个隐式参数的最大参数值
 "use strict"
 function getmax(){
   
      let max;
      max = arguments[0];
      for(let i =0;i<arguments.length;i++){
   
          if(max<arguments[i+1]){
   
              max = arguments[i+1];
          }
      }
      console.log("max:"+max);
  }
  getmax(8,11,7,2,3);//11

然后显示参数的话,就是正常的那样,需要注意的是ES6中,形参可以有初始值(默认值)。

可变参数…rest

 "use strict"
 function getAll(a,b,...rest) {
   
     console.log("a:"+a);
     console.log("b:"+b);
     console.log(rest)
 }

在这里插入图片描述

显示参数,形参默认值(ES6)

"use strict"
function sum(x,y=100){
   
    return x+y;
}
sum(1);//101
sum(2,3);//5

Javascript闭包(重点)

先来看两个例子,函数既可以访问内部变量,又可以访问外部变量。

 "use strict"
 // 函数可以访问由函数内部定义的变量
 function sum() {
   
     var a =4;// 局部变量
     return a+a;
 }
 console.log(sum());//打印8
 //函数也可以访问函数外部定义的变量
 var b=4;//类似全局变量,web页面中全局变量window对象\
 console.log(b);
 function sub1() {
   
     return b-1;
 }
console.log(sub1())

如果内部变量和外部变量重名的话,访问函数内部的变量,且内部变量不会修改外部变量(局部变量不会修改全局变量);

"use strict"
var a =8;
function rem() {
   
    var a =10;
    return a*a;
}
console.log(a);//外部a 8
console.log(rem());//100

全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。而在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用。

闭包就是为了封装一个私有变量,在Java中可以通过类和private修饰成员变量来实现,但是JS中并没有类只可以通过闭包来实现。

经典计数器counter()

//counter 通过函数访问外部变量来计数
var counter = 0;
function count(){
   
    counter = counter+1;
    return counter;
}
count();//1
count();//2
count();//3
//貌似很正常?不,实际上很不安全,你可以在外部任意的修改counter的值
counter = 0;// 0 counter被非法修改,那如果我放到函数的内部呢?
count();//1 此处原本应该是4!
"use strict"
//counter 通过函数访问内部变量来计数
function count(){
   
    var counter = 0;
    counter +=1;
    return counter;
}
count();//1
count();//1
count();//1
//由于每次调用count()函数,都将counter的初值设为了0,所以无论调用多少次都只能是1
// 看到这里,不禁又怀念起了对象,类,私有属性对吧?

那么如何实现,安全的计数器呢?
在JavaScript中,可以函数嵌套函数,并且嵌套函数可以访问上一层的函数变量。

"use strict"
function count(){
   
    var counter = 0;
    function add(){
   
        counter +=1;
    }
    add();
    return counter;
};
count();// 1
count();// 1 每次调用时,函数还是会将counter 初值设置为0
// 只要能在外部访问add()便可以实现安全的计数器
 "use strict"
 var ct=(function count(){
   
     var counter = 0;
     return function add(){
    console.log(counter+1);return counter+=1}
 })();//0 自调用函数,执行一次,将counter值设为0
 ct();//1
 // counter=0; 在严格模式下 counter=0;属于未定义会直接报错
 ct();//2 
 ct();//3

ES6 箭头函数的闭包?(如下)

"use strict"
var ct=( () => {
   
     var counter = 0;
     console.log(counter);
     return () => {
    console.log(counter+1);return counter+=1};
 })();
 ct();//1
 ct();//2
// counter=0; 在严格模式下 counter=0;属于未定义会直接报错
 ct();//3 counter的访问只能通过ct()来访问修改

好啦,就到这里!

相关文章
|
10天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
6天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2506 14
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
6天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1519 14
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
8天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
531 13
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19282 30
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18836 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17524 13
Apache Paimon V0.9最新进展
|
8天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
458 48
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
|
1天前
|
云安全 存储 运维
叮咚!您有一份六大必做安全操作清单,请查收
云安全态势管理(CSPM)开启免费试用
355 4
叮咚!您有一份六大必做安全操作清单,请查收
|
2天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。