javaScript基础知识储备

本文深入解析JavaScript的核心ECMAScript,涵盖变量命名、数据类型(包括基本与引用)、数组操作、类型判断、EventLoop与异步编程、Promise执行顺序、浅拷贝与深拷贝,以及常见错误处理。同时讨论了DOM和BOM在Web开发中的作用,以及编程范式和技巧如隐式转换和异步控制。

javaScript知识储备

组成

  • ECMAScript(核心)

提供语法、变量等,遵循ECMA-262标准

  • DOM(文档对象模型)

提供操作HTML标签的API,遵循W3C规范

  • BOM(浏览器对象模型

提供操作浏览器的API,window是BOM顶级对象,暂无规范

定义

  1. 解释型脚本语言

代码一边编译一边执行,区别于编译型语言(代码编译完毕才能执行)

  1. 弱语言类型

指某一个变量被定义类型,该变量可以根据环境变化自动进行转换,即具有隐式类型转换

  1. 单线程

通过轮转时间片模拟实现多线程,本质还是单线程

变量

命名规范

✅ 字母、下划线、数字、$符号

✅ 语义化、结构化

✅ 驼峰式

❌ 数字开头

❌ 关键字、保留字

数据类型

基本数据类型
  1. null

表示一个值被定义了,定义为“空值”

  1. undefined

表示根本不存在定义

  1. Boolean

布尔值

  1. Number

数值

  1. String

字符串

  1. Symbol

符号,ES6新增,表示独一无二的值

  1. BigInt

大数值,ES11新增,表示任意大的整数

const bigInt = 9007199254740991n
BigInt(9007199254740991)    // 9007199254740991n
// 注意:当使用 BigInt 时,带小数的运算会被取整。BigInt 和 Number 不是严格相等的,但是宽松相等的。
引用数据类型
  1. Object

对象

  1. Array

数组

数组扩展内容

扁平化-多维数组转换一维数组

/**
* flat()
* @param {number} n 维度
* @return {array} 一维数组
**/
[1,2,[3,4]].flat(2) // [1,2,3,4]
[1,2,[3,4]].toString().split(';')   // ['1','2','3','4']

合并

/**
* concat()  连接多个数组时效率低,返回新数组,不建议
* map() 使用较为复杂,不建议
* push.apply()  使用较为复杂,不建议
* for in    使用较为复杂,不建议
* ...   扩展运算符,返回新数组,建议
**/
const a1 = [1,2]
const a2 = [3,4]
a1.concat(a2)   // [1,2,3,4]
[...a1,...a2]   // [1,2,3,4]

去重

/**
* new Set() 利用新数据结构成员的值都是唯一的特性,建议
* 对象法:判断对象中是否存在key值,不建议
* 双循环对比:使用较为复杂,不建议
**/
[...new Set([1,1,2,3])] // [1,2,3]
// 注意:new Set()返回的是伪数组,可配合...或Array.from()转换成数组

排序

/**
* sort() 对于undefined 和 null 对象会有问题,但胜在简单易用
* 冒泡排序法
* 选择排序法
**/
[1,3,2,4].sort((a,b) => a-b)    // [1,2,3,4]
// 注意:a-b 升序,b-a 降序

求和

/**
* reduce()
* @param {function} funtion 累加器函数
* @param {number} initialValue 初始值,可选
**/
[1,2,3,4].reduce((pre,cur) => { pre + cur }, 0) // 10
  1. Function

函数

数据类型判断方式
  1. typeof
/**
* @param {any} object 某个实例对象
* @return {string} type
**/
typeof(0)   // 'number'
typeof(null)    // 'object'
typeof(undefined)    // 'undefined'

缺点:无法判断null、object、array,返回值都是object

  1. instanceof
/**
* @param {any} object 某个实例对象
* @param {prototype} constructor 某个构造函数
* @return {boolean} true/false
**/
[] instanceof Object    // true
[] instanceof Array    // true

缺点:无法判断array,可搭配用Array.isArray()判断数组类型

  1. Object.prototype.toString.call()
/**
* @param {any} object 某个实例对象
* @return {string} type
**/
Object.prototype.toString.call(1)   // [object Number]
Object.prototype.toString.apply(undefined)   // [object Undefined]

缺点:返回结果不能直接使用,需额外处理,搭配.slice(8,-1)即可

类型转换
  1. 显式转换

String()、Number()、parseInt()、toString()…

String(112)   // {string} '112'
Number('112')   // {number} 112
  1. 隐式转换

+、-、*、/、== …

+'1' === 1  // true
1 == true   // true
true/5  // 0.2

附加内容:探讨 == 与 === 两者的异同点

/**
*   相同点:两者均可达到判断数据是否相等的效果
*   不同点:==仅判断数据是否相等,不会判断类型,存在隐式类型转换,===则会判断数据与类型是否都相等
**/
'1' == 1    // true
'1' === 1   // false

Event Loop

Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理

Task Queue

Task Queue即事件循环中的任务队列,任务队列中包含MacroTask、MicroTask两种任务。

MacroTask

macro task即宏任务:setTimeOut()、setInterval()…

MicroTask

micro task即微任务:Promise()、nextTick()…

运行机制

mainProcess -> [one] macroTask -> [all] microTask -> [one] macroTask …

简单解释:每一次事件循环中,主进程先执行一个macroTask宏任务,macroTask宏任务执行完毕后,主进程便查询并执行microTask微任务,直至队列内microTask执行完毕,之后再执行一个macroTask,以此循环。

管中窥豹,microTask执行优先级是较高于macroTask的。

问题解疑

  1. Promise的执行顺序问题

new Promise()是同步函数,会立即执行,而Promise.then()/.catch()才是异步任务。

  1. async/await语法糖执行问题

async函数是同步函数,语法糖会返回一个Promise对象,当函数执行时遇到await语法糖时,先立即执行await语句,执行完成并阻塞线程(跳出函数),等到then/catch返回再接着执行函数体内后续语句。

  1. setTimeOut不能精准定时执行问题

这就涉及到setTimeOut函数执行需满足的两个条件之一:主进程必须是空闲状态,这就意味着即便定时器时间到了但由于主线程未空闲,因此就不会执行回调。

  1. 浅拷贝与浅拷贝的实现与区别

简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化?如果B也跟着变了,说明这是浅拷贝(授人以鱼),如果B没变,那就是深拷贝(授人以渔)

/**
*   浅拷贝:Object.assign()、直接赋值
*   深拷贝:JSON.parse(JSON.stringify())    // 无法拷贝函数和undefined
**/
let object = { name: 'zzz' }   // 源对象
//  浅拷贝
let easyCopyObj_1 = object
let easyCopyObj_2 = Object.assign(object)
// 深拷贝
let deepCapyObj = JSON.parse(JSON.stringify(object))
// 改变源对象
old_obj.name = 'zzr'
// 对比结果
console.log(easyCopyObj_1) // { name: 'zzr' }
console.log(easyCopyObj_2) // { name: 'zzr' }
console.log(deepCapyObj) // { name: 'zzz' }
  1. 常见代码错误类型
  • syntaxError

顾名思义,典型的语法错误

  • ReferenceError

引用错误,当一个不存在的变量被引用时发生的错误

let a = 1 + b   // ReferenceError:b is not defined
  • typeError

数据类型未正确使用

let fun = {}
fun()   // typeError:fun is not a function
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值