JS变量、作用域及内存详解
JavaScript 是一门动态、解释型语言,定义了多种不同类型的值,比如数字、字符串、布尔值、对象等。在 JavaScript 中,变量用于算术计算、字符串拼接、逻辑表达式等各种的场景,变量是引用值和原始值的存储体。
变量
变量的定义与命名规则
在 JavaScript 中,变量的定义使用关键字 var
或 let
,如果不带任何关键字直接声明变量,则默认为全局变量。命名规则遵循驼峰式命名规则,下划线方式也很常见。同时在变量命名时,要避开 JavaScript 的保留字。
// 声明变量
var name = '张三';
let age = 18;
const PI = 3.14;
// 不带关键字的变量默认为全局变量
name1 = '李四';
// 命名规则遵循驼峰式规则,在变量命名时应避免使用保留字
var firstName = 'Linda';
var user_name = 'Tom';
原始值与引用值
在 JavaScript 中,基本类型的数据包括 number
、string
、boolean
、null
、undefined
,它们都属于原始值类型,可以直接进行比较。引用值的数据类型包括 object
、array
、function
,它们在进行比较时会判断它们是否是同一个引用。
// 原始值类型的比较
var num1 = 1;
var num2 = 1;
if (num1 === num2) {
console.log('num1 equal num2');
}
// 引用值类型的比较
var arr1 = [1, 2, 3];
var arr2 = arr1;
if (arr1 === arr2) {
console.log('arr1 equal arr2');
}
变量的声明提升
JavaScript 在执行代码时,会先扫描代码中的所有函数和变量的声明,将它们的声明提升到当前作用域的最前面,因此,JavaScript 中的变量和函数可以先使用后声明。
console.log(name); // undefined
var name = '张三';
作用域
作用域定义
在 JavaScript 中,作用域指的是变量或函数的可访问范围。在 ES5 中,JavaScript 采用的作用域是函数作用域。在 ES6 中,JavaScript 新增了块级作用域,在块级作用域中声明的变量只在该作用域内起作用。
函数作用域
在函数中定义的变量不会在函数外部访问到,这种限制作用域的语法被称为封闭性。在 JavaScript 中,函数作用域可以通过内部定义变量的方式来实现,函数内部定义的变量在函数外部是不可访问的。
function test() {
var name = '张三';
}
console.log(name); // ReferenceError: name is not defined
块级作用域
在块级作用域中声明的变量只在该作用域内起作用,不会影响到函数作用域和全局作用域中的变量。
function test() {
var a = 1;
if (true) {
let b = 2;
var c = 3;
}
console.log(a); // 1
console.log(b); // ReferenceError: b is not defined
console.log(c); // 3
}
内存管理
JavaScript 的内存管理方式
JS的内存管理是自动的,开发人员不必关注内存的分配和回收,JavaScript 引擎会根据开发人员的代码流程进行动态的内存管理。
var str = 'Hello World';
var num = 100;
var obj = { name: '张三', age: 18 };
var arr = [1, 2, 3];
var fun = function () {
console.log('function');
}
以上变量在声明时都会占用内存空间,变量在不再需要时,由 JavaScript 引擎进行自动的垃圾回收,释放占用的内存空间。如果引用多个变量的对象或数组失去了所有引用,这些变量将等待 JavaScript 引擎的垃圾回收。
内存泄漏
内存泄漏指的是应该被垃圾回收器回收的对象却被保留在内存中的情况。一些常见的内存泄漏情况包括:
- 全局变量导致的内存泄漏
- 递归循环引用导致的内存泄漏
- DOM 引用导致的内存泄漏
// 全局变量导致的内存泄漏
var name = '张三';
// 递归循环引用导致的内存泄漏
function test() {
var obj1 = {};
var obj2 = {};
obj1.obj2 = obj2;
obj2.obj1 = obj1;
}
test();
总结
JavaScript 中,变量可以分为原始值和引用值。在 JavaScript 中,作用域指的是变量或函数的可访问范围,可以通过封闭函数和块级作用域来实现。在内存管理方面,JavaScript 引擎通过动态管理内存,开发人员无需关注内存的分配和回收。内存泄漏是一种应该被垃圾回收器回收的对象却一直占用着内存的情况。