作用域和闭包
纲要
产出
学会作用域和闭包
学会
this
的所有用法
主要内容
什么是作用域?什么是自由变量?
什么是闭包?闭包会用在哪里?
this
有几种赋值情况?
关键字
作用域
闭包
this
1.作用域
let a = 0;
function fn1() {
let b = 100;
function fn2() {
console.log("a:" + a + ",b:" + b);
}
}
全局作用域
函数作用域
块级作用域(ES6新增)
// ES6块级作用域
if(true) {
let x = 100;
}
console.log(x); // 此处报错
2.自由变量
一个变量在当前作用域没有定义,但被使用了;
向上级作用域一层一层依次寻找,直至找到为止;
如果到全局作用域都没找到,则报错
xx is not defined
;
3.闭包
作用域应用的特殊情况,有两种表现:
函数作为参数被传递;
函数作为返回值被返回;
// 函数作为返回值
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
闭包:自由变量的查找是在函数定义的地方,向上级作用域查找,而不是在执行的地方!
4. this
作为普通函数 [返回window]
使用
call
apply
bind
[传入什么,绑定什么]作为对象方法被使用 [返回对象本身]
在
class
方法中调用 [返回实例对象本身]箭头函数 [找它上一级作用域的this的值]
注:this
取值,是在函数执行的时候确认的;
例:
function fn1() {
console.log(this);
}
// 返回window
fn1(); // window
// 传入什么,绑定什么
fn1.call({x:100}); // {x:100}
const fn2 = fn1.bind({x:200});
fn2(); // {x:200}
注:bind
会返回新的函数
const zhangsan = {
name: '张三',
sayHi() {
// this 即当前对象
console.log(this);
},
wait() {
setTimeout(function() {
// this === window
console.log(this);
})
}
}
vs
const zhangsan = {
name: '张三',
sayHi() {
// this 即当前对象
console.log(this);
},
waitAgain() {
setTimeout(() => {
// this 即当前对象
console.log(this);
})
}
}
class People {
constructor(name) {
this.name = name;
this.age = 20;
}
sayHi() {
console.log(this);
}
}
const zhangsan = new People("张三");
zhangsan.sayHi(); // zhangsan对象
面试题
手写bind函数
Function.prototype.bind1 = function() {
// 将参数解析为数组
const args = Array.prototype.call(arguments);
// 获取 this (数组第一项)
const t = args.shift();
//
const self = this;
// 返回函数
return function() {
return self.apply(t, args);
}
}
function fn1(a, b, c) {
console.log('this', this);
console.log(a, b, c);
return 'this is fn1';
}
const fn2 = fn1.bind1({x:100}, 10, 20, 30);
const res = fn2();
console.log(res);
// 执行结果如下
// this {x:100}
// 10, 20, 30
// this is fn1
实际开发中闭包的作用
隐藏数据
如:做一个简单的cache工具
// 闭包隐藏数据,只提供API
function createCache() {
const data = {};
return {
set: function(key, val) {
data[key] = val;
},
get: function(key) {
return data[key];
}
}
}