局部作用域分为函数作用域和块作用域。
<script>
标签 和 .js 文件 的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。
全局作用域中声明的变量,任何其它作用域都可以被访问
注意:
JS环境中分配的内存, 一般有如下生命周期:
1. 内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
2. 内存使用:即读写内存,也就是使用变量、函数等
3. 内存回收:使用完毕,由垃圾回收自动回收不再使用的内存
4. 说明:
所谓垃圾回收, 核心思想就是如何判断内存是否已经不再会被使用了, 如果是, 就视为垃圾, 释放掉
两种常见的浏览器垃圾回收算法: 引用计数法 和 标记清除法
const person = {
age: 18,
name: 'pink老师'
}
const p = person
person = 1
p = null
缺点:嵌套引用
如果两个对象相互引用,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄露。
function fn() {
let o1 = {}
let o2 = {}
o1.a = o2
o2.a = o1
return '引用计数无法回收'
}
fn()
因为他们的引用次数永远不会是0。这样的相互引用如果说很大量的存在就会导致大量的内存泄露
变量提升是 JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问(仅存在于var声明变量)
ES6 引入了块级作用域,用let 或者 const声明变量,让代码写法更加规范和人性化
函数提升与变量提升比较类似,是指函数在声明之前即可被调用。
arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参
剩余参数允许我们将一个不定数量的参数表示为一个数组
- 语法一
在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this。
注意
在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window,因此
DOM事件回调函数为了简便,还是不太推荐使用箭头函数
解构赋值是一种快速为变量赋值的简洁语法,本质上仍然是为变量赋值。
数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法。
在 JavaScript 中最主要的数据类型有 6 种:
其实字符串、数值、布尔、等基本类型也都有专门的构造函数,这些我们称为包装类型。
JS中几乎所有的数据都可以基于构成函数创建。
推荐使用字面量方式声明对象,而不是 Object 构造函数
三个常用静态方法(静态方法就是只有构造函数Object可以调用的)
新方法
作用:Object.keys 静态方法获取对象中所有属性(键)
作用:Object.values 静态方法获取对象中所有属性值
作用:Object. assign 静态方法常用于对象拷贝
展开运算符(…),将一个数组进行展开
典型运用场景: 求数组最大值(最小值)、合并数组等
立即执行函数
数组解构
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次
调用就可以了。
面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作。
封装的本质是将具有关联的代码组合在一起,其优势是能够保证代码复用且易于维护,函数是最典型也是最基础的代码封装形式,面向对象思想中的封装仍以函数为基础,但提供了更高级的封装形式。
实际上每一个构造函数都有一个名为 prototype
的属性,译成中文是原型的意思,prototype
的是对象类据类型,称为构造函数的原型对象,每个原型对象都具有 constructor
属性代表了该原型对象对应的构造函数。
原型对象里面的this指向还是实例对象
每个原型对象里面都有个constructor 属性(constructor 构造函数)
对象都会有一个属性 proto 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype
原型对象的属性和方法,就是因为对象有 proto 原型的存在。
注意:
继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承
的特性。
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对
象的链状结构关系称为原型链
① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)
③ 如果还没有就查找原型对象的原型(Object的原型对象)
④ 依此类推一直找到 Object 为止(null)
⑤ __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行
this
的值,即【谁调用 this
的值指向谁】this
值为 window
,严格模式下没有调用者时 this
的值为 undefined
。this
与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在 this
!箭头函数中访问的 this
不过是箭头函数所在作用域的 this
变量。this
的值】,事件回调函数使用箭头函数时,this
为全局的 window
,因此DOM事件回调函数不推荐使用箭头函数this
的原因,基于原型的面向对象也不推荐采用箭头函数call
方法调用函数,同时指定函数中 this
的值
call
方法能够在调用函数的同时指定 this
的值call
方法调用函数时,第1个参数为 this
指定的值call
方法的其余参数会依次自动传入函数做为函数的参数apply
方法能够在调用函数的同时指定 this
的值apply
方法调用函数时,第1个参数为 this
指定的值apply
方法第2个参数为数组,数组的单元值依次自动传入函数做为函数的参数bind
方法并不会调用函数,而是创建一个指定了 this
值的新函数,bind
方法创建新的函数,与原函数的唯一的变化是改变了 this
的值。//定时器
document.onmousemove = debounce (function(){
console.log("函数节流");
})
// 函数防抖
function debounce (cd,time=300){
var t = null;
return function(){
if(t) return;
t = setTimeout(() => {
cd.call(this);
t = null;
}, time);
}
}
案例
const box = document.querySelector('.box')
let i = 1 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
// 防抖函数
function debounce(fn, t) {
let timeId
return function () {
// 如果有定时器就清除
if (timeId) clearTimeout(timeId)
// 开启定时器 200
timeId = setTimeout(function () {
fn()
}, t)
}
}
// box.addEventListener('mousemove', mouseMove)
box.addEventListener('mousemove', debounce(mouseMove, 200))
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数
开发使用场景 –
方法:利用时间戳 实现原理:提前设定变量,准备存储事件结束后的时间戳,在事件开启之后,立即保存时间戳,并判断当前时间戳和事件结束后的时间戳的差值,决定是否需要执行本次事件。事件执行完毕之后,保存事件结束时的时间戳,以供下次开启事件时计算差值。
//时间相减
document.onmousemove = throttle(function(){
console.log("函数节流")
})
function throttle(cb, wait=300){
let last = 0;
return function(){
var now = new Date().getTime();;
if (now - last > wait) {
cb.call(this);
last = new Date().getTime();;
}
}
}
案例,滑动加1
const box = document.querySelector('.box')
let i = 1 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
// console.log(mouseMove)
// 节流函数 throttle
function throttle(fn, t) {
// 起始时间
let startTime = 0
return function () {
// 得到当前的时间
let now = Date.now()
// 判断如果大于等于 500 采取调用函数
if (now - startTime >= t) {
// 调用函数
fn()
// 起始的时间 = 现在的时间 写在调用函数的下面
startTime = now
}
}
}
box.addEventListener('mousemove', throttle(mouseMove, 500))
例页面打开,可以记录上一次的视频播放位置
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务