对js的基础语法总结
一、const、let、var 区别
变量提升在下方会有代码演示
let | var | const | |
---|---|---|---|
变量提升/预解析 | ❌ | ✔ | ❌ |
重复定义 | ❌ | ✔ | ❌ |
作用域 | 块级作用域 | 函数作用域 | 块级作用域 |
常量是否可变 | ✔ | ✔ | ❌ |
对象/数组是否可变 | ✔ | ✔ | ✔ |
需要初始化 | ❌ | ❌ | ✔ |
二、防抖与节流
1、防抖
例子:如同公交车,上来个人等2s保证安全在发车,如果等的期间还有人来,则重新等到安全
实现:
- 利用setTimeout作为定时器
- 当在定时器未消失时,再次触发 则会将定时器【清除】+【重做】=》重新计时间
- 由于setTimeout内部函数是做完后执行,因此要想立即执行 添加了callNow作为临时参数
function debounce(func,wait){
let timeout;
return function(){
if(timeout) clearTimeout(timeout) //若存在,则清空定时器
let callNow = !timeout;
timeout = setTimeout(()=>{ //增加定时器
timeout=null; //时间到了,清除定时器
},wait)
if(callNow) func.apply(this)
}
}
2、节流
例子:如同拿工资,你一次把工资取完,只有在公司打钱的那一天,卡里才能拿得到钱。你急着要钱,不好意思么有,你时间到了不去拿钱,之后去拿还能拿。
实现:
- 一样利用setTimeout作为定时器
- 当在定时器未消失时,不做操作
- 当在定时器不存在时,生成定时器,时间到了去执行,也可像防抖那样利用临时变量去实现立即调用
function throttle(func,wait){
let timeout;
return function(){
if(!timeout){
timeout = setTimeout(()=>{ //增加定时器
timeout=null; //时间到了,清除定时器
func.apply(this)
},wait)
}
}
}
三、变量提升+作用域
1、来一个开胃菜
//看一下下面输出什么
var length = 100
function f1(){
console.log(this.length)
}
var obj = {
x:10,
f2: function (f1){
f1();
arguments[0]();
}
}
obj.f2(f1,1)
//考点:预解析+作用域+arguments
懵了吧 我开始也是!!
(1) 先介绍arguments ->是函数内置参数
先!把下面代码放在浏览器运行一下
function a(){
console.log(arguments)
}
a(1,2,3,4,'s','d')
- 即使你不接受形参 一样会将你的实参存在arguments中
- arguments是一个对象
{"0": 1,"1": 2,"2": 3, "3": 4,"4": "s", "5": "d"}
- 【注意】:arguments有作用域是它本身
(2) 逐层分析调用者&作用域
- 通过调用者确定作用域【注意arguments作用域是arguments本身】
- 无调用者 =》作用域是window
- 通过作用域确定this指向
function f1(){
console.log(this.length)
}
var obj = {
x:10,
f2: function (f1){
f1(); //无调用者 =》作用域window
arguments[0](); //无调用者 =》作用域arguments
}
}
obj.f2(f1,1) //调用者obj =》作用域obj
(3) 分析函数执行顺序
- 主函数
obj.f2(f1,1)
这没跑了 就是调用obj的f2 - 从而执行
//函数一 f1() //函数二 arguments[0]();
- 此时这俩的作用域都是obj 因为通过上面的obj调用的
- 首先是第一个f1()=》
console.log(this.length)
此时无调用者因此作用域指向window,获取到的length也就是全局中的100 - 第二个函数arguments[0]()=》f1() 此时无调用者,但是arguments有自己作用域因此作用域指向arguments,所以调用获取到的length是arguments的长度
因此最后答案是100 ,2 可放在浏览器上试试哦