JavaScript进阶

语法知识

数组

类数组

什么是类数组
JavaScript中的类数组主要有以下几种

  1. 函数里面的参数对象 arguments
  2. 用 getElementsByTagName/ClassName/Name 获得的 HTMLCollection;
  3. 用 querySelector 获得的 NodeList
    类数组与普通的数组的关系是什么
  4. 类数组能否使用数组的方法?
  5. 类数组有哪些方式可以转换成数组?

编程技巧

函数式编程

为什么要学习函数式编程

函数式编程是非常古老的一个概念,早于第一台计算机的诞生。
函数式编程是随着React的流行受到越来越多的关注
Vue3也开始拥抱函数式编程
函数式编程可以抛弃this
打包过程中可以更好地利用tree shaking过滤无用代码
方便测试,方便并行处理
有很多库可以帮助我们进行函数式开发:lodash, underscope, ramda

什么是函数式编程

函数式编程是一种编程范式,和面向对象编程是并列关系(编程范式:思想+ 实现的方式)
面向对象编程:对现实世界中的事物的抽象,抽象出对象以及对象与对象之间的关系
函数式编程:把现实世界事物之间的联系抽象到程序世界

函数式编程的特性(纯函数,柯里化,函数组合)

函数式编程的使用场景

函数式编程Lodash

函数式编程总结

函数式编程是一种编程范式,和面向对象编程是并列关系(编程范式:思想+ 实现的方式)
面向对象编程:对现实世界中的事物的抽象,抽象出对象以及对象与对象之间的关系
函数式编程:把现实世界事物之间的联系抽象到程序世界

函数式编程的核心思想
纯函数
在程序设计中,若一个函数符合以下要求,则它可能被认为是纯函数

  • 此函数在相同的输入值是,需产生相同的输出,函数的输出,或改为输出值以外

ES6

语言与平台之间的关系

  1. 前端程序员平时写的代码哪些属于语言层面哪些属于平台
    ECMAScript 与JavaScript
    ECMAScript的发展过程
    ECMAScript 2015的新特性
    And more

ECMAScript 概述

JavaScript是ECMAScript的扩展,ECMAScript 只是提供了最基本的语法
浏览器JavaScript = ECMAScript + BOM + DOM
node JavaScript= ECMAScript + fs + net + etc.
JavaScript语言本身指的就是ECMAScript
2015年开始ES保持每年一本版本的迭代

ES2015 迭代时间过长,变化过大,2015年后 每隔一年 发布一个版本

ES2015(ES6)
相比ES5.1的变化比较大
自此,标准命名规则发生变化
行业内有人习惯于用ES6来代指ES2015极其以后的版本
ES2015 长达26章建议读一下标准规范 https://262.ecma-international.org/6.0/

  1. 解决原有语法上的一些问题或者不足(let, const)
  2. 对原有语法的增强
  3. 全新的对象,全新的方法,全新的功能
  4. 全新的数据类型和数据结构
    初始化环境
yarn add nodemon --dev

stormweb@alex MINGW64 ~/Desktop/ecma
$ yarn nodemon demo00.js 
yarn run v1.22.18
warning ..\..\package.json: No license field
$ C:\Users\stormweb\Desktop\ecma\node_modules\.bin\nodemon demo00.js
[nodemon] 2.0.19
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node demo00.js`
开始工作2333
[nodemon] clean exit - waiting for changes before restart

在ES2015之前,ES只有两种作用域 函数作用域+全局作用域
ES2015中新增了块级作用域

if(true){
    var foo = 'sqxy'
}
console.log(foo)
if(true){
    let foo = 'sqxy'
}
console.log(foo)

for(var i= 0;i< 3;i++){
    for(var i = 0;i< 3;i++){
        console.log(i)
} 
}
for(let i= 0;i< 3;i++){
    for(let i = 0;i< 3;i++){
        console.log(i)
} 
console.log("内层循环结束",i)
}
var elements = [{},{}, {}]
for (var i= 0; i< elements.length;i++){
    elements[i].onclick = function(){
        console.log(i)
    }
}
elements[2].onclick()

闭包:借助函数作用域摆脱全局作用域产生的影响

var elements = [{},{}, {}]
for (var i= 0; i< elements.length;i++){
    elements[i].onclick = (function(i){
        return function(){
        console.log(i)
    }
    })(i)
}
elements[0].onclick()
var elements = [{},{}, {}]
for (let  i= 0; i< elements.length;i++){
    elements[i].onclick = function(){
        console.log(i)
    }
}
elements[2].onclick()

for: 两层嵌套的作用域

for (let  i = 0 ; i<3; i++){
    let i = 'foo'
    console.log(i)
}

let 声明的变量不会出现变量提升(官方的bug叫做特性),如果只是升级var会造成一些老的代码不能使用
const 只读常量/衡量,在let 基础上增加了只读特性

const obj = {}
obj.name = "sqxy"

最佳实践: 不用var,主要使用const, 对于一些需要修改的变量使用let
数组解构

// 数组解构
const arr = [100,200,300]
// const foo = arr[0]
// const bar  = arr[1]
// const baz= arr[2]
// console.log(foo,bar,baz)
const [foo, bar, baz] = arr
const [foo],,baz]
const [foo,...rest]= arr
console.log(foo,bar,baz)
//  const [foo, bar, baz,rest] = arr //  rest=underfined 

对象解构
根据属性名提取

const obj ={name:'sqxy', age:18}
const {name} = obj
const name = 'tom'
const {name:objNam = 'jack'} = obj
console.log(objName)

截流和防抖

防抖 debounce

把多次函数调用合成一次,可以用于防止快速按键,快速拖动窗口大小,导致事件处理函数内的
复杂操作被多次执行降低体验

// 参考lodash 的 debounce
// 自己实现一个debounce函数
function debounce (fn, delay) {
	let timer = null
	return function (...args) {
		clearTimeout(timer)
		timer = setTimeout(() => {
			fn.apply(this, args)
			timer = null
}, delay)
}
function add(n1,n2){
console.log(n1+n2)
let fn = debounce(add,300)
fn(1,2)
fn(1,2)
fn(1,2)
}

节流 throttle

在一定时间内让指定函数只执行一次,可以用于快速滚动的过程中,检测滚动位置距离底部多远。(要在滚动过程中检测位置是否到达底部,而 debounce 是在事件结束之后才会执行)


function add(n1, n2) {
    console.log(n1 + n2)
}
const fn = throttle(add, 3000)
fn(1, 2)
fn(1, 2)
fn(1, 2)
fn(1, 2)
function throttle(fn, delay) {
    let timer = null
    let pre = null
    return function (...args) {
        let now = Date.now()
        if (pre) {
            if (now - pre >= delay) {
                fn.apply(this, args)
                pre = now
            } else {
                if (timer) return
                timer = setTimeout(() => {
                    fn.apply(this, args)
                    pre = now
                    timer = null
                }, delay)
            }
        } else {
            fn.apply(this, args)
            pre = now
        }
    }
}

lodash 导出单独防抖和节流函数
打开终端,切换到项目中 lodash 的源码目录
输入以下命令

npm i -g lodash-cli
lodash include=debounce,throttle
posted @ 2022-05-25 10:49  李老师家的狗  阅读(73)  评论(0)    收藏  举报