01 JS基础 var、let、const 的区别
var 开胃小菜 面试题1 以下代码会输出什么
console.log(v1) var v1 = 1;
¨K18K
- 题解 输出两个undefined undefined
为什么在输出语句之后 声明变量或者函数 还会undefined 因为遭遇到了变量提升,JS编译器会在代码运行之前为当前作用域 先声明变量再使用 上述等同于以下代码
```
var v1
console.log(v1)
v1 = 1
1 // 函数
2 function fn() {
3 var v2
4 if (false) {
5 v2 = '2'
6 }
7 console.log(v2)
8 }
9 fn();
¨K10K
¨K8K
¨K20K
全局污染
栗子2 假设我们引入了一个外部的js jq.js
var v = 'jq'
- 在我们自己的代码中引用 会输出test 我们并不能输出jq.js里面的那个jq字符串 如果jq.js是一个插件的话会导致程序的不稳定
1 <script src="./jq.js"></script>
2 <script>
3 var v = 'test'
4 console.log(v);
5 </script>
解决方案1 在ES6之前 将外部的js封装到立即执行函数里面 改造jq.js
1 (function () {
2 var $ = (window.$ = {});
3 var name = '一只空指针';
4 $.getName = function () {
5 return name;
6 }
7 }.bind(window)())
解决方案2 在ES6之后 使用let块级作用域 看起来是不是简洁了很多 改造jq.js
1 {
2 let $ = (window.$ = {});
3 let name = '一只空指针';
4 $.getName = function () {
5 return name;
6 }
7 }
然后使用$来调用 会正常输出 "一只空指针" 啊哈 这看起来像不像 jq的用法
1 <script src="./jq.js"></script>
2 <script>
3 console.log($.getName());
4 </script>
const 常量
- 1 同一个作用域内 不能重复声明,基础数据类型 声明后不能改变
- 2 引用类型里面的数据是可以改变的,基础类型的数据是存在栈里面的,引用类型在栈内保存的是对象的内存地址,真正的数据是存在堆空间的,所以我们可以改变基于堆空间的数据,也就是可以改变对象的属性 (如果不希望对象的值被改变可以使用 Object.freeze() 将对象冻结 )
- 小栗子3
1 // 声明一个引用类型的常量
2 const XZR = {
3 name: '一只空指针',
4 age: 22
5 }
6 // 输出 {name: "一只空指针", age: 22}
7 console.log(XZR)
8 // 改变 age 称为23
9 XZR.age = 23
10 // 输出 {name: "一只空指针", age: 23}
11 console.log(XZR)
12 // 将对象进行冻结 然后尝试改变值
13 Object.freeze(XZR)
14 XZR.age = 24
15 // 依然 输出 {name: "一只空指针", age: 23}
16 console.log(XZR)
刚才讲到了 基础类型和引用类型
- 顺便引出一个很经典的面试题 null 和 undefined的区别 其实在很多语言中是只有null 没有undefined的 可能JS作者有他自己的想法吧 变量初始化的时候 null标识引用类型 undefined标识基本类型。