知识点整理
-
作用域
含义:某个变量合法的使用范围
作用域分为:- 全局作用域
- 函数作用域
- 块级作用域(ES6新增)
自由变量:一个变量在当前作用域没有定义,但被使用了
向上级作用域,一层一层依次寻找,直到找到为止,如果到了全局作用域都没有找到,则报错xx is not defined -
闭包
含义:作用域应用的特殊情况,有2种表现:函数作为参数被传递
function create(){
let a = 100
return function(){
console.log(a)
}
}
let fn = create()
let a = 200
fn()//100
函数作为返回值被返回
function print(fn){
let a = 200
fn()
}
let a = 100
function fn(){
console.log(a)
}
print(fn)//100
所有自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方
-
this
this取什么样的值,是在函数执行的时候确定的,不是在定义的时候
五种场景:
- 作为普通函数
- 使用call apply bind
- 作为对象方法被调用
- 在class方法中被调用
- 箭头函数
function fn1() {
console.log(this)
}
fn1()//window
fn1.call({x:100})//{x:100}
const fn2 = fn1.bind({x:200})
fn2()//{x:200}
const zhangsan = {
name:'张三',
sayHi(){
console.log(this)//当前对象
},
wait(){
setTimeout(function(){
//setTimeout执行不依赖当前作用域
console.log(this)// this===window
})
}
}
const zhangsan = {
name:'张三',
sayHi(){
console.log(this)//当前对象
},
wait(){
setTimeout(()=>{
//箭头函数的作用域永远取上级作用域
console.log(this)// 当前对象
})
}
}
class People{
constructor(name){
this.name = name
this.age=20
}
sayHi(){
console.log(this)
}
}
//this,指向实例化对象
const zhangsan = new People('张三')
zhangsan.sayHi()//zhangsan 对象
常见的有关作用域和闭包的题目:
1、this的不同应用场景如何取值
2、手写bind函数
3、实际开发过程中闭包的应用场景,举例说明
4、创建10个a标签,点击的时候弹出来的序号
2.手写bind函数
Function.prototype.myApplyPlus = function (thisArg, args) {
// 判断this的指向
if (typeof this !== 'function') {
throw new Error('type error')
}
// 处理外部传递过来的this,如果this为null时,指向全局的window对象
const newThis = thisArg || window
// 创建一个唯一的key
const fn = Symbol()
// 接收临时this
newThis[fn] = this
// 传入参数,调用新属性,注意this是谁调用取谁,这种就是第一个参数调用
const res = newThis[fn](...args)
// 删除属性,防止污染
delete newThis[fn]
// 返回
return res
}
看懂上面的写法即可理解底下的代码
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1)//[1,2,3,4,5,6]
3、实际开发过程中闭包的应用场景,举例说明
//隐藏数据,提供api
function createAche(){
var data = {}
return {
set:(key,val)=>{
data[key] = val
},
get:(key)=>{
return data[key]
}
}
}
4.创建10个a标签,点击的时候弹出来的序号
let a,i
for(i=0;i<10;i++){
a = document.createElement('a')
a.innerHTML = i+'<br>'
a.addEventListener('click',function(e){
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
经验证 弹出来的都是10
改为
let a
for(let i=0;i<10;i++){
a = document.createElement('a')
a.innerHTML = i+'<br>'
a.addEventListener('click',function(e){
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
经验证 弹出来的都是对应数字