JavaScript函数核心机制:定义方式、提升规则与内部属性详解

作者:代码拾荒

时间:2026-10-22

浏览:142

本文深入解析JavaScript中Function类型的核心特性。详细对比函数声明、函数表达式及Function构造函数的定义差异,重点阐述函数声明提升机制对执行顺序的影响。同时探讨JavaScript中函数无重载的覆盖行为,解析length与prototype属性,并详解apply和call方法在改变this指向及扩充作用域时的具体应用与区别。

文章目录

JavaScript函数基础与定义方式

在JavaScript中,引用类型是一种重要的数据结构,主要包含Object、Date、Array、RegExp和Function这五种类型。本文将重点聚焦于Function这一数据结构进行深入探讨。

在JavaScript中,函数本质上是一个对象,每个函数都是Function类型的实例。与其他引用类型相同,函数也具备特定的属性和方法。

JavaScript中函数的定义主要有以下几种方式。

第一种方式是通过函数声明语法来定义函数。


  function sum(num1,num2){
  return num1+num2;
 }

第二种方式是利用函数表达式进行定义。

需要注意的是,在函数表达式的末尾必须添加分号。


var sum=function(num1,num2){
   return num1+num2;
}

第三种方式是利用Function构造函数来创建函数。

使用Function构造函数时,可以接收任意数量的参数。其中,最后一个参数始终被视为函数体,而前面的参数则用于枚举函数的参数列表。


var sum=new Function("num1","num2","return num1+num2")

尽管可以使用构造函数定义函数,但这种方式可读性较差,通常不推荐使用。

函数名实际上只是指向函数的一个指针,因此函数名与其他包含对象指针的变量没有本质区别。这意味着一个函数可以拥有多个名称。那么,函数声明和函数表达式之间究竟存在哪些区别呢?

函数声明提升机制解析

解析器在加载执行环境数据时,对函数声明和函数表达式的处理机制不同。解析器会优先读取函数声明,使得函数声明在任何代码执行之前即可被调用,这就是所谓的“函数声明提升”。相比之下,函数表达式必须等待解析器执行到其所在代码块时才会被真正执行。以下两个示例可以直观展示这一差异。


console.log(sum(10,10));

function sum(n1,n2){
  return n1+n2;
}

以上代码会正常执行

再看!

console.log(sum(10,10));

var sum=function(n1,n2){
  return n1+n2;
}

以上执行器就会报错!

函数重载与覆盖行为

JavaScript中的函数不支持重载机制。

如果声明了两个同名函数,后声明的函数会覆盖先声明的函数。


function sun(a){
 return a+100;
}
function sun(a){
 return a+200;
}

var result=sum(2)//202

函数的内部属性与外部方法

接下来讨论函数的内部属性。

这些内部属性主要包括this和arguments。

关于这两个属性的具体细节,此处不再展开叙述。

函数还具备特定的属性和方法。

函数拥有两个主要属性:length和prototype。

length属性表示函数期望接收的命名参数个数。


function a(name){
 //todo
}
function b(name,age){
 //todo
}
function c(){
 //todo
}

a.length //1
b.length //2
c.length //0

prototype属性对于引用类型至关重要,后续将有专门章节进行详细讲解,此处不再赘述。

apply与call方法的应用

每个函数都包含两个非继承的方法:apply和call。

这两个方法的主要用途是在特定的作用域中调用函数,其核心作用是设置函数体内this关键字所指向的值。

首先介绍apply()方法,它接收两个参数:第一个参数是函数运行的作用域,第二个参数是参数数组。第二个参数可以是数组实例,也可以是arguments对象。


function sum(num1,num2){
  return num1+num2;
}

function test1(a,b){
  return sum.apply(this,arguments);
}

function test2(c,d){
  return sum.apply(this.[c,d]);
}

console.log(test1(1,1)) //2

console.log(test2(1,1)) //2

call方法与apply方法功能相似,主要区别在于call方法的第二个参数必须将参数逐个列举出来,而不是以数组形式传递。

使用call和apply来扩充作用域的最大优势在于,对象可以与任何方法解耦,从而保持代码的灵活性。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章