JavaScript 基础篇:细说 js 中的变量和作用域

细说 JS 中的变量和作用域

本文源自 JavaScript 学习 0402 课时

一、变量的类别

  1. var 声明全局变量,允许提升,会在 window创建一个 新属性
// 初始化,未给 test1 赋值
var test1;
console.log(test1); //打印:undefined

// 赋值
var test1 = "赋值的RQ桑(test1)";
console.log(test1); //打印:赋值的RQ桑(test1)

// 用 var 更新,也可以用 js 的专有名词 “提升”
var test1 = "用var更新的RQ桑(test1)";
console.log(test1); //打印:用var更新的RQ桑(test1)

// 直接更新
test1 = "直接更新的RQ桑(test1)";
console.log(test1); //打印:直接更新的RQ桑(test1)

// var 声明的变量 会 在 window 上创建一个新属性。
console.log(window.test1); //打印:直接更新的RQ桑(test1)

注意!!

  • 直接 声明一个值,事实上是对属性赋值操作,可以参考如下代码。
//使用直接赋值方式声明的是全局变量(全局对象属性)
test4 = "RQ桑(test4)";
console.log(test4); //打印:RQ桑(test4)

// 事实上是对属性赋值操作,可以在全局找到这个属性
console.log(window.test4); //打印:RQ桑(test4)

console.log(window); //在window下面找到刚才声明的 `test1` 和 `test4`;

//test4 在函数内部仍然是一个全局属性,可以全局访问

·


  1. let 声明全局变量,不允许提升,不会在window上创建一个新属性
// 初始化, 先不赋值
let test2;
console.log(test2); //  打印: undefined

// 赋值,提升是被禁止的
// let test2 = 'RQ桑(test2)';  // 语法错误,不 OK

// 变量允许更新
test2 = "更新后的RQ桑(test2)";
console.log(test2); //打印:更新后的RQ桑(test2)

// let 声明的变量 不会 在 window 上创建一个新属性。
console.log(window.test2); //undefined
  1. const 声明一个常量不允许提升,不会在 window 上创建一个新属性,声明时必须赋值,不允许更改。
// const test2;  //这种写法是不 ok 的,会报错
[!!报错信息:Identifier 'test2' has already been declared]

// 赋值
const test3 = "RQ桑(test3)";
console.log(test3); //打印:RQ桑(test3)

// const 声明的变量 不会 在 window 上创建一个新属性。
console.log(window.test3); //undefined

下面两种写法都会直接报错

// 不能用 const 提升
const test3 = "用const修改过的RQ桑(test3)";

// const 常量 不允许 更新RQ桑
test3 = "更新后的RQ桑(test3)";

!! 注意,使用 let 直接用 test(n) = '更新值' 是修改操作,不会在 window 上创建新属性。

  1. var、let、const 三者的区别

不同点

  1. var 定义的变量,会在 window 上创建一个新属性。letconst 不会。

  2. const 声明 常量 前必须先赋值,且不支持修改。

  3. let 声明的变量可以提升,但 let 声明的变量不能提升,但两者都支持更新。

相同点

  1. 三者都是全局变量(常量),作用于全局、是默认的、不可删除。

二、函数的作用域

1. 函数中声明的变量为私有变量。

function demo1() {
  //在函数内部可以访问到外部的全局变量

  let test5 = "京东商城";

  var test6 = "小米商城";

  // 使用直接赋值方式声明的是全局变量(全局对象属性)。
  test7 = "天猫商城"; // 隐式声明(为全局变量的一个属性)

  return `网络购物平台:${test5}${test6}${test7}`;
}
console.log(demo1()); //打印:网络购物平台:京东商城、 小米商城、天猫商城
console.log(test5); //无法访问私有成员
console.log(test6); //无法访问私有成员
console.log(test7); //打印:天猫商城(全局成员)

2. 函数的作用域链

// 内部的变量 --> 到它的上一级作用域中去查找变量

let test8 = "全局的test8";
let test9 = "全局的test9";

function demo2() {
  // 当函数体内返回对象在局部找不到时,会触发作用域链
  // 这时函数内部可以访问到外部的全局变量

  let test8 = "函数内的test8";

  return `我是:${test8} \n 我是:${test9}`;
}
console.log(test8); // 全局的test8
console.log(test9); //全局的test9

console.log(demo2()); //test9找不到,所以找到他的`上一级`
// 我是:函数内的test8  我是:全局的test9

三、块作用域

这里先通过阅读技术博客:[Js 块级作用域],了解为什么要有作用域?

1. let 和 const 支持块作用域

{
  let a = 1;
  const B = "hello";
}

console.log(a); //外部访问不到
console.log(B); //外部访问不到

2. var:不支持块作用域

{
  var m = 1;
}
console.log(m); //打印1

3. 块作用域的作用

在使用 for 循环或者 if 等条件判断语句时,可防止内部变量被污染,示例如下

let colors = ["red", "green", "js"];

for (let i = 0; i < colors.length; i++) {
  console.log("%c%s", "color:violet", colors[i]); // 输出(样式为粉色) red green js
}
console.log(i); //报错:ReferenceError: i is not defined
let colors = ["red", "green", "js"];

for (var i = 0; i < colors.length; i++) {
  console.log("%c%s", "color:violet", colors[i]); // 输出(样式为粉色) red green js
}
console.log(i); //输出 3

文章到此就结束啦,记得留下你们的小赞喔,你们的鼓励就是对我最大的支持!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小趴菜RQS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值