「JS硬气功👊」JavaScript变量声明&&变量类型攻略🔪🔪

Hi!这里是JustHappy ,既然点开了这个JS硬气功,那就一起愉快的学习吧!我想大家都有在面试中碰到过JS变量类型之类相关的问题吧,今天我们来练一练这一块的,希望可以帮助大家和我自己在面试中把嘴皮子磨硬🪨🪨🪨

变量声明 && 变量类型 🐶🐮

var、let、const

letconst是ES6(ECMAScript 2015)引入的,旨在提供更好的作用域控制和变量声明的安全性。在现代JavaScript开发中,推荐使用letconst来代替var,以编写更清晰、更易于维护的代码。

为什么大家都不继续使用var?

var声明的变量会被提升到它们所在的作用域的顶部 (这怎么形容呢?就相当于在你代码的第一行前面声明了变量),但是它们的赋值不会提升

这是啥意思呢?我们来看看下面这几小段代码,大家也可以在自己的设备上跑一下

  • 我们尝试单独输出一个未被声明的变量
arduino 复制代码
console.log(myVal)
  • 显而易见,这行代码是会报错的

  • 但是如果我们在这行代码的下面使用var去声明这个变量,再在下面输出就会有以下情况

ini 复制代码
console.log(myVar); // 输出:undefined,而不是报错,因为变量声明被提升,但赋值没有提升
var myVar = 5;
console.log(myVar); // 输出:5
  • 我们都知道代码是顺序执行的,按道理说第一个console.log(myVal)应该会报错,但是却输出了undefined,这说明了该变量在这一行处于一个"被声明但是为被赋值的状态",而以上现象就是因为var变量的声明 被提升、但赋值并没有被提升

  • 这会导致什么问题呢?

    • 这可能导致在变量赋值之前就引用了未声明的变量,导致程序出现错误。

let和const

我们在使用let和const的时候是不存在变量提升这一问题,这是因为let和const声明变量会经历所谓的"暂时性死区"(Temporal Dead Zone,TDZ)

  • 下面两段代码也证明了这一点
ini 复制代码
console.log(letVal); // 抛出 ReferenceError: bar is not defined
let letVal = 'aaa';
ini 复制代码
console.log(constVal); // 抛出 ReferenceError: qux is not defined
const constVal = 'bbb';

你真的了解变量类型吗?

值类型 or 引用类型(即简单类型 和 复杂类型)

值类型 又或者说是 简单类型 吧,在JavaScript中有

我们先来看以下两段代码

ini 复制代码
// 值类型特征演示
let a = 10;
let b = a;
b = 20;
console.log(a); // 10

// 引用类型特征演示
let c = { name: "Jack" };
let d = c;
d.name = "Tom";
console.log(c.name); // Tom

很直观的可以看到值类型演示中原来的值没有被改变,但是在引用类型中却被改变了

所以这是为什么呢?

不只是JavaScript,几乎是所有的编程语言都有这个特性,这和数据在内存中的存储有关

在JavaScript中,值类型和引用类型在内存中的存储方式有显著的区别,这主要体现在它们存储的位置和访问方式上:

值类型(简单类型)
  1. 存储位置:值类型的数据直接存储在栈(stack)内存中。

  2. 存储方式:当值类型的数据被创建时,它们会直接被复制到栈中。例如,当你声明一个变量并赋予一个值时,这个值就会被存储在栈中。

引用类型(复杂类型)
  1. 存储位置:引用类型的数据存储在堆(heap)内存中。

  2. 存储方式:引用类型的变量实际上存储的是指向堆中数据的指针(引用)。当引用类型的数据被创建时,它们会被存储在堆中,而变量则保存了指向这些数据的引用。

那么对于一引用数据类型(复杂类型),我们用一个新的变量拷贝完再修改的话,如何使得原本的数据不被修改呢。于是乎我们来聊聊深拷贝浅拷贝

深拷贝和浅拷贝

由上我们知道,只有引用类型(复杂数据类型)需要进行深拷贝,所以在此之前我们需要掌握如何判断一个数据是否是引用类型,所以我们来看看typeof()

有关typeof()

typeof()可以直接返回简单数据类型的确切类型 ,而对复杂数据类型来说,则返回object ,对于函数则返回function,以下是返回结果示例

javascript 复制代码
// 对于简单数据类型
console.log(typeof 10); // number
console.log(typeof "Jack"); // string
console.log(typeof true); // boolean
console.log(typeof Symbol()); // symbol
console.log(typeof undefined); // undefined
//对于复杂数据类型
console.log(typeof {}); // object
console.log(typeof []); // object

//对于函数
console.log(typeof function () {}); // function

但是typeof()有个历史遗留问题,当判断null 的时候也会返回object

javascript 复制代码
console.log(typeof null); // object
所以我们来实现一个深拷贝吧!!!

实现深拷贝有多种方式,我们这里就写一种最重要的,最能体现编程思想的递归深拷贝

ini 复制代码
const deepClone = (obj) => {
  if (typeof obj !== "object" || obj === null) return obj;
  // 初始化反回结果
  let result;
  // 判断是数组还是对象
  if (Array.isArray(obj)) {
    result = [];
  } else {
    result = {};
  }
  for (let key in obj) {
    // 保证key不是原型链上的属性
    if (obj.hasOwnProperty(key)) {
      result[key] = deepClone(obj[key]);
    }
  }
  return result;
};

以下是测试这段代码的示例

css 复制代码
let e = {
  name: "Jack",
  sex: "male",
  address: {
    city: "Beijing",
  },
  age: 18,
};
let f = deepClone(e);

f.address.city = "Shanghai";
console.log(e); // { name: 'Jack', sex: 'male', address: { city: 'Beijing' }, age: 18 }
console.log(f); // { name: 'Jack', sex: 'male', address: { city: 'Shanghai' }, age: 18 }

有点烦人的变量类型转换

先看看以下几个示例吧

ini 复制代码
// 有关 "==" 号的类型转换

// 如果比较的两个值类型不同,js会尝试将它们转换为相同的类型。
console.log(3 == "3"); // true
console.log(true == 1); // true
console.log(false == 0); // true
console.log("" == 0); // true
console.log("" == false); // true
console.log(null == undefined); // true

// 但是NaN 不等于任何值,包括它自己
console.log(NaN == NaN); // false
console.log(NaN !== NaN); // true
console.log(NaN === NaN); // false

怎么样,是不是有些懵逼!😭

其实这只需要咱记住就好啦

那就有疑问了!我们该如何判断一个值是否是NaN 呢?该如何合乎逻辑的比较两个NaN呢?

我们可以使用 isNaN() 函数判断是否为NaN

javascript 复制代码
console.log(isNaN(NaN)); // true

使用 object.is() 函数判断两个值是否严格相等

javascript 复制代码
console.log(Object.is(NaN, NaN)); // true

如果有什么不足之处,大家尽管在评论区留言哦

相关推荐
浩星6 分钟前
vue3+uniapp中使用高德地图实现撒点效果
前端·vue.js·uni-app
JamSlade12 分钟前
React 个人笔记 Hooks编程
前端·javascript·笔记·react.js
就叫飞六吧13 分钟前
html文件cdn一键下载并替换
前端·python·html
Allen Bright18 分钟前
【HTML-3】HTML 中的水平线与换行:基础元素详解
前端·html
纸包鱼最好吃20 分钟前
javaweb-html
前端·html
程序二次开发22 分钟前
html,js获取扫码设备的输入内容
前端·javascript·html
鲁Q同志1 小时前
vue项目启动报错(node版本与Webpack)
前端·vue.js·webpack
Allen Bright1 小时前
【HTML-5】HTML 实体:完整指南与最佳实践
前端·html
Elastic 中国社区官方博客1 小时前
在 JavaScript 中正确使用 Elasticsearch,第二部分
大数据·javascript·数据库·elasticsearch·搜索引擎·全文检索
Favour722 小时前
根据当前日期计算并选取上一个月和上一个季度的日期范围,用于日期控件的快捷选取功能
前端·vue.js·elementui