#说明

一般来说,我们使用变量前都会先声明变量:let const var function … ; 但是JS中变量也可以不声明,直接使用,这是什么意思呢?他们之间有何区别呢?

查阅借鉴的资料:MDN的var 描述部分;慕课网的变量可以不声明直接使用?; CSDN的js 变量声明 (var使用与不使用的区别;思否的 JS函数中直接使用变量,不用VAR?Javascript变量和属性的区别;博客园的js 变量与属性的区别

除此笔记外大家可以看我其他笔记 :全栈笔记数据结构与算法编程_前端开发学习笔记编程_后台服务端学习笔记JavaNodejsJavaScript笔记编程工具使用笔记ES6及后续版本学习笔记Vue笔记整合React笔记微信小程序学习笔记Chrome开发使用及学习笔记 以及许多其他笔记就不一一例举了

Ⅰ - 变量的声明分显式声明和隐式声明

  • 显示声明 是程序中的一条说明语句,它列出一批变量名并指明这些变量的类型。
  1. // 显示声明 变量name,但不知其类型,也不知其占用空间大小
  2. var name ;
  • 隐式声明 指通过某种默认协定的方法将变量名与类型绑定。所有隐式声明的变量默认都是全局变量,无论函数内外
  1. // 赋值语句其实隐式的声明了变量name,类型为string
  2. name = '努力学习的汪';//隐式声明(为全局变量的一个属性) --> 注意:是属性

隐式声明带来了些许的方便,但却被认为有损于程序的可读性,因为它可能会带来隐藏的错误,Bug。

Ⅱ - 结合实例说明

1、当我们使用访问一个没有声明的变量时,JS会报错

  1. console.log(1,userName); //报错,因为没有声明

2、当我们给一个没有声明的变量赋值时,JS不会报错

  • 相反它会认为我们是要隐式声明一个 全局 变量,这一点一定要注意。
  1. userName = 'hongjilin'
  2. console.log(1,userName); //打印hongjilin
  3. console.log('window',window.userName) //打印window上的userName
  4. function person(){
  5. userName = '努力学习的汪';
  6. console.log(2,userName); //打印 努力学习的汪
  7. }
  8. person();
  9. console.log(3,userName); //打印 努力学习的汪
  10. console.log('window',window.userName) //打印window上的userName

可以明显看到,实际上变量是挂载在全局对象window上,以属性的形式存在

JS中声明变量与不声明变量直接使用的区别 - 图1

3、当我们给声明过的变量赋值

与上方代码基本一致,只有第一行代码改为声明变量

  1. let userName = 'hongjilin' //##只有这一行声明改变
  2. console.log(1,userName); //打印hongjilin
  3. console.log('window',window.userName) //打印window上的userName
  4. function person(){
  5. userName = '努力学习的汪';
  6. console.log(2,userName); //打印 努力学习的汪
  7. }
  8. person();
  9. console.log(3,userName); //打印 努力学习的汪
  10. console.log('window',window.userName) //打印window上的userName

可以明显看到,实际上声明后的变量是局部存在的,在window上是找不到这个属性的JS中声明变量与不声明变量直接使用的区别 - 图2

Ⅲ - 总结

在当前域中声明变量. 如果在方法中声明,则为局部变量(local variable);如果是在全局域中声明,则为全局变量。

  1. 而事实上是对属性赋值操作。
  • 首先,它会尝试在当前作用域链: 如在方法中声明, (先找方法当前的作用域)中解析 userName;
  • 如果在任何当前作用域链中找到name,则会执行对name属性赋值;
  • 如果没有找到name,它才会层层往上找,最终在全局对象(即当前作用域链的最顶层对象,如window对象)中创造name属性并赋值。
  1. 注意: 它并不是声明了一个全局变量,而是创建了一个全局对象的属性
  • 即便如此,可能你还是很难明白“变量声明”跟“创建对象属性”在这里的区别,别急! 继续往下看
  • 事实上,Javascript的变量声明、创建属性以及每个Javascript中的每个属性都有一定的标志说明它们的属性
  • 如只读(ReadOnly)不可枚举(DontEnum)不可删除(DontDelete)等等。
  1. 由于变量声明自带不可删除属性,比较 var userName = ‘努力学习的汪’userName = ‘努力学习的汪’
  • 前者是变量声明,带不可删除属性,因此无法被删除 —> delete userName; 无效
  • 后者为全局变量的一个属性,因此可以从全局变量中删除 —> delete userName; 有效