前端基础JavaScript基础作用域和对象课程前言Cou...
前端基础JavaScript基础作用域和对象
课程前言Course Introduction同学们,本课程聚焦 JavaScript 核心基础 —— 作用域与对象。将解析作用域机制,区分全局与局部作用域,揭示变量提升、作用域链的运行逻辑;深入对象体系,讲解字面量、构造函数等创建方式,助你构建 JS 变量与数据组织的底层认知,为复杂业务逻辑编写筑牢基础。让我们开始今天的课程吧!一作用域
CodingFuture
在 JavaScript(ES6 之前)中,作用域决定了变量的可见性和生命周期,就像给变量划定了 “活动范围”。它分为两种类型:全局作用域和局部作用域(函数作用域)。1.1全局作用域:代码的 “全局舞台”
全局作用域就像是一个 “全局舞台”,包含整个 script 标签或独立 JS 文件中的所有代码。在这个 “舞台” 上声明的变量(用 var)都是全局变量,它们在代码的任何位置都能被访问到,直到浏览器关闭才会被销毁。比如:var globalNum = 10; // 全局变量function globalFunc(){ console.log(globalNum); // 可以访问全局变量}globalFunc(); // 输出:10这里需要注意一个特殊情况:在函数内部如果不使用 var 声明变量,这个变量也会成为全局变量(虽然能实现功能,但非常不建议这么做,容易导致变量污染)。例如:function badPractice(){ nonVarVar = "我是意外的全局变量"; // 没有用var声明}badPractice();console.log(nonVarVar); // 输出:我是意外的全局变量1.2局部作用域:函数的 “专属空间”
局部作用域是函数的 “专属空间”,在函数内部声明的变量(用 var)只能在这个函数内部使用,函数执行结束后,这些变量就会被销毁,因此更节省内存。函数的形参也是局部变量,只能在函数内使用。比如:function localVarDemo(){ var localVar = "我是局部变量"; // 局部变量 console.log(localVar); // 输出:我是局部变量}localVarDemo();console.log(localVar); // 报错,无法访问局部变量1.3全局变量与局部变量的对比
特性全局变量局部变量作用范围整个程序(浏览器关闭才销毁)仅限函数内部(函数执行完销毁)声明方式全局作用域用 var,或函数内不声明函数内用 var 或形参内厝占用长期占用,可能导致内存泄漏短期占用,更高效命名冲突风险高(容易与其他变量重名)低(仅限函数内)二作用域链
CodingFuture
当函数嵌套时,内部函数可以访问外部函数的变量,这种层层嵌套形成的变量查找机制就是 “作用域链”。它遵循 “就近原则”,就像在一条链条上从内到外依次查找变量,直到找到为止,如果到全局作用域还没找到就会报错。2.1案例分析
作用域链的查找过程:var globalA = 1; // 全局作用域function outer(){ var outerB = 2; // outer函数作用域 function inner(){ var innerC = 3; // inner函数作用域 console.log(globalA); // 查找顺序:inner → outer → 全局,找到1 console.log(outerB); // 查找顺序:inner → outer,找到2 console.log(innerC); // 直接在inner作用域找到3 } inner();}outer();作用域链层级:0 级链:全局作用域(globalA=1)1 级链:outer 函数作用域(outerB=2)2 级链:inner 函数作用域(innerC=3)三预解析
CodingFuture
JavaScript 引擎在执行代码时分为两步:预解析和代码执行。预解析会提前处理变量和函数的声明,就像在正式演出前先把舞台道具准备好。3.1变量预解析(变量提升)
变量声明会被提升到当前作用域的顶部,但赋值不会提升。这意味着即使变量在使用后才声明,声明会被 “提前”,但变量初始值是undefined。console.log(num); // 输出:undefined(变量提升后声明但未赋值)var num = 10; // 实际执行时相当于:var num; console.log(num); num = 10;3.2 函数预解析(函数提升)
函数声明会被整体提升到作用域顶部,因此可以在声明前调用函数。fn(); // 输出:我是提前声明的函数function fn(){ console.log("我是提前声明的函数");}注意:函数表达式(变量赋值形式)不会提升,因为它本质上是变量声明,遵循变量提升规则(初始值为undefined)。fn(); // 报错:fn不是函数(变量提升后fn是undefined)var fn = function() { console.log("我是函数表达式");};3.3预解析案例解析
var num = 10;function fn(){ console.log(num); // 输出:undefined(函数内变量提升,优先使用局部变量声明) var num = 20; console.log(num); // 输出:20(赋值后)}fn();预解析后代码结构:var num; // 全局变量声明提升function fn(){ var num; // 函数内变量声明提升 console.log(num); // undefined num = 20; console.log(num); // 20}num = 10; // 全局变量赋值fn();四对象
CodingFuture
数据与功能的 “封装容器”对象是 JavaScript 中最核心的数据类型之一,它将相关的属性(数据)和方法(功能)封装在一起,就像一个 “容器”,让数据结构更清晰。4.1对象的基本概念
属性:对象的特征(如 “姓名”“年龄”),用 “键值对” 表示,键是属性名(字符串),值可以是任意类型(包括函数)。方法:对象的行为(如 “说话”“跑步”),本质是对象中的函数。示例:用对象描述一个人var person = { name: "张三", // 属性 age: 23, sayHello: function() { // 方法 console.log("你好,我是" + this.name); // this指向当前对象 }};4.2创建对象的三种方式
对象字面量(*简洁)直接用{}定义对象,键值对之间用逗号分隔。var star = { name: "pink", age: 18, sayHi: function() { alert("大家好啊~"); }};// 访问属性:对象.属性名 或 对象["属性名"]console.log(star.name); // 输出:pinkconsole.log(star["age"]); // 输出:18// 调用方法:对象.方法名()star.sayHi(); // 弹出提示框new Object ()(构造函数方式)通过内置构造函数创建空对象,再动态添加属性和方法。var andy = new Object(); // 创建空对象andy.name = "pink"; // 添加属性andy.age = 18;andy.sayHi = function() { // 添加方法 alert("大家好啊~");};自定义构造函数(批量创建相似对象)当需要创建多个类似对象时,用构造函数封装公共属性和方法,通过new关键字实例化对象。// 定义构造函数(首字母大写约定)function Person(name, age, height){this.name = name; // this指向新创建的对象this.age = age;this.height = height;this.introduce = function() { // 方法 console.log("我是" + this.name + ",年龄" + this.age + ",身高" + this.height); };}// 创建对象实例var zs = new Person("张三", 23, 181);var ls = new Person("李四", 24, 182);zs.introduce(); // 输出:我是张三,年龄23,身高181new 关键字的作用:创建一个空对象;将this指向这个空对象;执行构造函数中的代码(给空对象添加属性和方法);隐式返回这个对象(无需手动写 return)。4.3遍历对象
使用for...in可以遍历对象的所有属性(包括方法,因为方法也是属性值为函数的键值对)。var obj = { name: "zs", age: 18, sex: "男", sayHi: function() { console.log(this.name + "hello"); }};for (var key in obj) { console.log(key + ":" + obj[key]); // 输出属性名和属性值 // 结果: // name:zs // age:18 // sex:男 // sayHi:function() { ... }(函数代码)}注意:遍历出的属性包括对象自身的属性和继承的属性(如toString),如果需要过滤继承属性,可以用hasOwnProperty方法:for (var key in obj) { if (obj.hasOwnProperty(key)) { // 只处理自身属性 console.log(key + ":" + obj[key]); }}五总结与建议
CodingFuture
5.1作用域与预解析的核心要点
作用域链:内部函数访问外部变量时,从内到外逐层查找,遵循 “就近原则”。预解析陷阱:变量提升只提升声明,不提升赋值,初始值为undefined;函数声明整体提升,函数表达式按变量提升处理(初始值undefined);避免在函数内不声明直接赋值变量(防止意外全局变量)。5.2对象的*佳实践
优先使用对象字面量:简洁直观,适合快速创建单个对象;构造函数用于批量创建:当需要多个相似对象时,用构造函数封装公共逻辑;合理使用 this:在对象方法和构造函数中,this指向当前对象,避免混淆;遍历对象时过滤继承属性:使用hasOwnProperty确保只操作自身属性。
结言陈词Closing statement通过本课程,你已掌握作用域链的就近查找规则、预解析机制对代码执行的影响,能熟练运用三种方式创建对象并实现属性遍历。理解变量生命周期与对象数据建模思维,可有效避免命名冲突、提升代码可读性。建议结合实际项目练习,在函数嵌套与对象封装中深化理解。下期课程预告:JavaScript基础-内置对象码上未来为同学们安排统一答疑扫码添加微信领取详细课程大纲
微信号:CodingFuture2020
The CodingFuture&The Future is Already Here<<< END >>>
资深职业咨询规划师