JS函数和对象全解析

 更新时间:2026年01月24日 15:45:04   作者:虚拟系别  
文章主要介绍了JavaScript中的垃圾回收机制、闭包、函数参数以及ES6箭头函数,ES6箭头函数简化了函数写法,并重塑了this的指向规则,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧

一、垃圾回收机制

JS作为高级语言,无需开发者手动分配和释放内存,核心依赖“垃圾回收机制(GC)”自动清理不再使用的内存空间,避免内存泄漏。

1. 核心原则

垃圾回收的核心是“识别并回收不可达对象”——当一个对象无法通过任何引用链访问到时,就会被标记为“垃圾”,等待GC清理。

2. 两种常见回收算法

标记-清除算法(主流):这是现代浏览器最常用的算法,分两步执行:

  • 标记阶段:GC从全局对象(如window、global)出发,遍历所有可访问的对象并做标记;
  • 清除阶段:遍历内存中所有对象,清除未被标记的对象,释放其占用的内存。

引用计数算法(淘汰):通过统计对象被引用的次数判断是否回收——引用次数为0则标记为垃圾。但存在致命缺陷:循环引用时(A引用B,B引用A,且两者均无其他引用),引用次数永远不为0,导致内存泄漏。

3. 实用注意事项

虽然GC自动执行,但不良代码仍可能导致内存泄漏,需注意:

  • 避免意外全局变量:未声明的变量会挂载到window上,长期无法回收,建议用let/const替代var,减少全局变量使用;
  • 及时清除无用引用:如DOM元素删除后,需清空对应的JS引用(例:elem = null);
  • 慎用闭包:闭包会保留外层函数的变量引用,过度使用可能导致内存占用过高(下文详细说)。

二、闭包

闭包是JS的核心特性,也是面试高频考点,理解它能轻松实现模块化、状态保存等功能。

1. 定义与本质

当一个函数嵌套另一个函数,且内层函数引用了外层函数的变量/参数,同时内层函数被外部访问时,就形成了闭包。本质是“内层函数携带了外层函数的作用域上下文”,让外层变量在函数执行结束后仍不被回收。

2. 经典案例

实现计数器(保存状态,避免全局污染)

function createCounter() {
  let count = 0; // 外层函数变量,被内层引用
  return function() {
    count++; // 内层函数访问外层变量
    return count;
  };
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

解析:createCounter执行后,按常理count会被GC回收,但因内层函数被counter引用,闭包保留了count的引用,使其能持续累加,且count无法被外部直接修改,实现了“私有变量”的效果。

3. 应用场景与坑点

常用场景:

  • 模块化封装:隐藏内部变量,只暴露需要的方法(类似JS模块的雏形);
  • 延迟执行:如定时器、事件回调中访问外层变量;
  • 状态缓存:如上述计数器、防抖节流中的状态保存。

注意坑点:

闭包会延长外层变量的生命周期,过度使用会增加内存负担,甚至导致内存泄漏。建议:仅在需要保存状态/封装变量时使用,使用完毕后可通过“清空引用”(如counter = null)释放内存。

三、函数参数

JS函数参数看似简单,实则有诸多进阶技巧,能大幅提升代码灵活性,覆盖默认值、剩余参数、解构传参等场景。

1. 默认参数(ES6+)

ES6前需通过逻辑判断设置默认值(如param = param || 'default'),但存在缺陷(若参数为0、false等假值,会被误判为无参)。ES6新增默认参数语法,简洁且精准:

// 基础用法
function greet(name = 'Guest', age = 18) {
  console.log(`Hello ${name}, you are ${age} years old`);
}
greet(); // Hello Guest, you are 18 years old
greet('Tom'); // Hello Tom, you are 18 years old
// 注意:默认参数需放在参数列表末尾
function fn(a, b = 2) {} // 合法
function fn(b = 2, a) {} // 不推荐,易混淆

2. 剩余参数(…rest)

当函数参数数量不确定时,用剩余参数(…+变量名)接收多余参数,返回一个数组(区别于arguments的类数组),便于遍历操作:

// 求和函数(支持任意数量参数)
function sum(...nums) {
  return nums.reduce((total, num) => total + num, 0);
}
console.log(sum(1,2,3)); // 6
console.log(sum(4,5,6,7)); // 22
// 剩余参数与普通参数结合(剩余参数必须在最后)
function fn(a, b, ...rest) {
  console.log(a, b); // 1 2
  console.log(rest); // [3,4,5]
}

3. 参数解构(ES6+)

当参数为对象/数组时,可通过解构直接提取属性/元素,简化代码:

// 对象解构传参
function getUserInfo({ name, age, gender = 'male' }) {
  console.log(`姓名:${name},年龄:${age},性别:${gender}`);
}
getUserInfo({ name: 'Tom', age: 20 }); // 姓名:Tom,年龄:20,性别:male
// 数组解构传参
function getSum([a, b, c]) {
  return a + b + c;
}
console.log(getSum([1,2,3])); // 6

四、ES6箭头函数:简洁与this的重塑

箭头函数是ES6最常用的语法糖,不仅简化函数写法,更重塑了this的指向规则,解决了传统函数this指向混乱的问题。

1. 基础语法

// 无参数,单语句
const fn1 = () => console.log('Hello');
// 单参数,单语句(可省略括号)
const fn2 = num => num * 2;
// 多参数,多语句(需加括号和大括号,return不可省略)
const fn3 = (a, b) => {
  const total = a + b;
  return total;
};
// 返回对象(需加小括号,避免大括号被解析为代码块)
const fn4 = () => ({ name: 'Tom', age: 20 });

2. 核心特性:this指向

传统函数(普通函数、构造函数)的this指向“调用者”,而箭头函数没有自己的this,其this继承自外层执行上下文的this,且一旦绑定无法修改(call、apply、bind也无效)。

// 传统函数this指向问题
const obj = {
  name: 'Tom',
  sayHi: function() {
    setTimeout(function() {
      console.log(this.name); // undefined(this指向window)
    }, 1000);
  }
};
// 箭头函数解决this问题
const obj2 = {
  name: 'Tom',
  sayHi: function() {
    setTimeout(() => {
      console.log(this.name); // Tom(this继承自sayHi的this,即obj2)
    }, 1000);
  }
};

3. 适用与不适用场景

适用场景:

    • 回调函数(定时器、数组方法forEach/map等),避免this指向混乱;
    • 简单的工具函数(无复杂this需求),简化语法。

不适用场景:

    • 构造函数:箭头函数无法作为构造函数(无prototype,不能用new关键字);
    • 对象方法:若方法需访问对象自身的this,建议用普通函数;
    • 需要arguments对象的场景:箭头函数没有arguments,需用剩余参数替代。

到此这篇关于JS函数和对象全解析的文章就介绍到这了,更多相关js函数和对象内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript 拖放效果实现代码

    javascript 拖放效果实现代码

    JavaScript擅长于修改页面中的DOM元素,但是我们使用JavaScript通常只是实现一些简单功能,例如实现图片的翻转,网页中的标签页,等等。这篇文章将向你展示如何在页面中,对创建的元素实现拖放。
    2010-01-01
  • 兼容FF/IE跟随鼠标的层的效果

    兼容FF/IE跟随鼠标的层的效果

    兼容FF/IE跟随鼠标的层的效果...
    2007-08-08
  • mescroll.js上拉加载下拉刷新组件使用详解

    mescroll.js上拉加载下拉刷新组件使用详解

    这篇文章主要为大家详细介绍了mescroll.js上拉加载下拉刷新组件的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • js获取html参数及向swf传递参数应用介绍

    js获取html参数及向swf传递参数应用介绍

    HTML页面是在客户端执行的,这样要获取参数必须使用客户端脚本如JavaScript,在这点上与服务器端脚本获取参数方式有所不同接下来将详细介绍下感兴趣的你可不要错过了哈
    2013-02-02
  • 微信小程序缓存支持二次开发封装实现解析

    微信小程序缓存支持二次开发封装实现解析

    这篇文章主要介绍了微信小程序缓存支持二次开发封装实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • JS实现简单加减购物车效果

    JS实现简单加减购物车效果

    这篇文章主要为大家详细介绍了JS实现简单加减购物车效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • JS实现页面超时后自动跳转到登陆页面

    JS实现页面超时后自动跳转到登陆页面

    这篇文章主要介绍了JS实现页面超时后自动跳转到登陆页面,需要的朋友可以参考下
    2015-01-01
  • 如何用JS判断数组中是否存在某个值或者某个对象的值

    如何用JS判断数组中是否存在某个值或者某个对象的值

    数组是我们编程中经常使用的的数据结构之一,在处理数组时,我们经常需要在数组中查找特定的值,下面这篇文章主要给大家介绍了关于如何用JS判断数组中是否存在某个值或者某个对象的值的相关资料,需要的朋友可以参考下
    2023-01-01
  • jQuery实现动态文字搜索功能

    jQuery实现动态文字搜索功能

    本文主要介绍了jQuery实现动态文字搜索功能的分析过程,文章底部提供了完整的代码。具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • js实现浏览本地文件并显示扩展名的方法

    js实现浏览本地文件并显示扩展名的方法

    这篇文章主要介绍了js实现浏览本地文件并显示扩展名的方法,涉及javascript文件上传及字符串操作的相关技巧,非常简单实用,需要的朋友可以参考下
    2015-08-08

最新评论