学习课程名称:BAT大牛带你横扫初级前端JavaScript面试(第二版)
章节名称:作用域和闭包(新版)
讲师姓名:双越
课程内容:
- 作用域和自由变量
- 闭包
- this
- 原型中的this
作用域是什么?
代表着某个变量合法的使用范围
作用域分类:
全局作用域
函数作用域
块级作用域
自由变量:一个变量在当前作用域没有定义,但是被使用了
向上级作用域,一层一层一次寻找,直至找到为止
如果到全局作用域都没找到,则报错 xx is not defined
闭包的核心重点:函数定义的地方和函数执行的地方不一样。
闭包的两种情况:
- 函数作为参数被传递
- 函数作为返回值被返回
所有自由变量的查找,都会向上级作用域查找,不是在执行的地方!!!
闭包在实际开发中,有如下应用场景:
隐藏数据(不让外边去改变)
如何做一个简单的 缓存工具
function createCache() {
const data = {}; // 闭包中的数据,被隐藏,不被外界访问
return {
set: function (key, val) {
data[key] = val;
},
get: function (key) {
return data[key];
},
};
}
const demo = createCache();
demo.set("a", 100);
console.log(demo.get("a"));
this 有如下应用场景,比较复杂(场景比较多)
- 作为普通函数 window
- 使用call apply bind 改变this的指向
- 作为对象的方法被调用 this即当前对象
- 在class 方法中被调用 this即创建的实例
- 箭头函数 取上级作用域的this
this这里有句话,一定要记住:“this在各个场景中,取什么样的值,是在函数执行的时候确认的,不是在函数定义的时候确认的”
手写bind
Function.prototype.bind = function () {
// 将参数拆解为数组 列表转换为数组
const args = Array.prototype.slice.call(arguments);
// 获取this (数组第一项)
const t = args.shift();
// fn1.bind(...) 中的 fn1
const self = this;
// 返回一个函数
return function () {
return self.apply(t, args);
};
};
// bind 示例验证
function fn1(a, b, c) {
console.log("this", this);
console.log(a, b, c);
return "this is fn1";
}
const fn4 = fn1.bind1({ x: 100 }, 10, 20, 30);
const res1 = fn3();
console.log(res1);
//this, {x:100}
// 10,20,30
//this is fn1