(五)前端,如此简单!---变量

js中有三种方式可以声明变量:varletconst

可以从以下方面来区分他们。

一、作用域

  • 在函数外

    var globalVar = "我是全局变量"; // var会声明全局变量
    let letVar = "我不是window属性"; // let声明的不会声明全局变量
    const constVar = "我也不是"; // const声明的也不会

    // 全局变量自动成为window的属性
    console.log(window.globalVar); // "我是全局变量"
    console.log(window.letVar); // undefined
    console.log(window.constVar); // undefined

  • 在函数内

    function test() {
    if (true) {
    var x = 10; // 函数作用域
    let y = 20;
    const z = 30; // let/const - 块级作用域
    }
    console.log(x); // 10 - 在函数内可访问
    console.log(y); // ReferenceError: y is not defined
    console.log(z); // ReferenceError: z is not defined
    }

二、变量提升

变量提升就是JavaScript 在编译阶段就把所有变量声明记录进作用域,但赋值操作仍留在原地的一种机制。

声明"提前",赋值"不动"。

复制代码
// var a = 5;提到了前面
console.log(a); // undefined (不会报错)
var a = 5;

// let/const  编译时已知道有个变量 b,但进入 TDZ(暂时性死区),
// 在 let/const b 语句执行完之前都不能读/写。
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;

三、重新赋值

varlet 可以重新赋值,const 不可以重新赋值,但可以改属性

复制代码
var name = "Alice";
name = "Bob"; // ✅

let age = 25;
age = 26; // ✅

const PI = 3.14; //const 变量必须在声明时赋值
PI = 3.14159; // TypeError: Assignment to constant variable

const person = { name: "Alice" };
person = { name: "Bob" }; // ❌ 不能重新赋值
person.name = "Bob"; // ✅ 可以修改属性

const numbers = [1, 2, 3];
numbers = [5, 6, 7]; // ❌ 不能重新赋值
numbers.push(4); // ✅ 可以修改数组内容

// 冻结对象(浅冻结)
const obj = { name: 'Alice', info: { age: 18 } };
Object.freeze(obj);     // 第一层冻结
obj.name = 'Bob';       // 静默失败(严格模式会抛错)
obj.info.age = 20;      // ✅  freeze 只冻结浅层

四、重复声明

var可以重复声明,letconst不能

复制代码
var count = 1;
var count = 2; // ✅ 不会报错

let total = 10;
let total = 20; // ❌ SyntaxError: Identifier 'total' has already been declared

const MAX = 100;
const MAX = 200; // ❌ SyntaxError: Identifier 'MAX' has already been declared

var count = 1;
var count = 2;
console.log(count);
// 同一块作用域里多次 var 声明会被合并。等价于============ >>
var count;   // 提升后只声明一次
count = 1;   // 第一次赋值
count = 2;   // 第二次赋值
console.log(count); // 2

五、总结

  • 如果值不需要改变 用 const

    const API_URL = "https://api.example.com";
    const container = document.getElementById('container');

  • 需要重新赋值时使用 let

    let counter = 0;
    counter = 1; // 需要改变值

    for (let i = 0; i < 10; i++) {
    // 循环变量需要改变
    }

  • 容易引起错误的 var

    for (var i = 0; i < 5; i++) {
    console.log(i); // 输出 0、1、2、3、4。同步执行
    }

    for (var i = 0; i < 5; i++) { // var 是函数作用域,所有回调都引用同一个 i
    setTimeout(function() { // 循环会立即执行完毕,i 的值从 0 增加到 5
    console.log(i); // setTimeout 的回调是异步的,会在 100ms 后执行
    }, 100); // 当回调函数执行时,循环早已结束,此时的 i 已经是 5
    } // 所以输出 5个5。

    for (let i = 0; i < 5; i++) { // let 是块作用域,每次循环迭代都会创建一个新的 i 变量
    setTimeout(function() { // 这就形成了 5 个独立的闭包
    console.log(i); // 输出 0、1、2、3、4
    }, 100);
    }

    // var 通过立即执行函数来创建闭包,实现同样的效果
    for (var i=0; i<5; i++){
    function(j){ // t=0ms: 循环开始,创建5个定时器
    setTimeout(function(){ // t=0ms: 循环结束
    console.log(j); // t=100ms: 5个定时器同时触发,打印 0 1 2 3 4
    }, 100);
    }(i)
    }

六、跨js文件的变量

index.html 中有一个按钮

复制代码
<button onclick="dayin()">点击</button>

<!-- type="module" 是使用 import 的关键 -->
<script type="module" src="script.js"></script>

script.js 从 test.js 导入变量

复制代码
import { url } from './test.js'

// type="module",这个函数默认不会添加到全局 window 对象
// 需要通过 window.dayin = dayin 显式暴露给全局作用域
window.dayin = dayin;

function dayin() {
	alert(url);
}

test.js中的变量需要导出

复制代码
// export 导出 url 变量,使其他模块可以导入使用
export var url = "yang";
相关推荐
canonical_entropy2 小时前
下一代低代码渲染框架 nop-chaos-flux 的设计原则
前端·低代码·前端框架
东方小月2 小时前
5分钟搞懂Harness Engineering(驾驭工程):从提示词到AI Agent的进化之路
前端·后端·架构
我叫黑大帅2 小时前
为什么需要 @types/react?解决“无法找到模块 react 的声明文件”报错
前端·javascript·面试
之歆2 小时前
DAY_21JavaScript 深度解析:数组(Array)与函数(Function)(一)
前端·javascript
XinZong3 小时前
【AI社交】基于OpenClaw自研轻量化AI社交平台实战
前端
Le_ee3 小时前
ctfweb:php/php短标签/.haccess+图片马/XXE
开发语言·前端·php
爱上好庆祝4 小时前
学习js的第七天(wed APIs的开始)
前端·javascript·css·学习·html·css3
KaMeidebaby4 小时前
卡梅德生物技术快报|冻干工艺开发:注射用心肌肽全流程参数优化与工程化方案
前端·其他·百度·新浪微博
ooseabiscuit4 小时前
Laravel6.x核心优化与特性全解析
android·开发语言·javascript
哆啦A梦15885 小时前
20, Springboot3+vue3实现前台轮播图和详情页的设计
javascript·数据库·spring boot·mybatis·vue3