uploadhub的技术博客 uploadhub的技术博客
首页
  • 学习笔记

    • 《HTML5和CSS3篇》
    • 《JavaScript基础篇》
    • 《JavaScript高级篇》
    • 《Ajax篇》
    • 《JavaScript模块化篇》
    • 《Node.js篇》
    • 《MongoDB篇》
    • 《Promise篇》
    • 《Git篇》
  • 《Vue2+Vue3篇》
  • 《React篇》
  • 一面-基础
  • 二三面-进阶
关于我
  • 分类
  • 标签
  • 归档

uploadhub

首页
  • 学习笔记

    • 《HTML5和CSS3篇》
    • 《JavaScript基础篇》
    • 《JavaScript高级篇》
    • 《Ajax篇》
    • 《JavaScript模块化篇》
    • 《Node.js篇》
    • 《MongoDB篇》
    • 《Promise篇》
    • 《Git篇》
  • 《Vue2+Vue3篇》
  • 《React篇》
  • 一面-基础
  • 二三面-进阶
关于我
  • 分类
  • 标签
  • 归档
  • JS基础知识(一)-变量类型和计算
  • JS基础知识(二)- 原型和原型链
  • JS基础知识(三)- 作用域、闭包
    • 1.几道面试题(以点带面)
    • 2.涉及知识点
      • 2.1 执行上下文(Execution-context)
      • 2.2 this
      • 2.3 作用域(action-scope)
      • 2.4 闭包(closure)
    • 3.对前文问题的解答
      • 3.1 创建10个 <a> 标签,点击的时候弹出对应的序号
      • 3.2 实际开发中闭包的应用
  • JS基础知识(四)- 异步和单线程
  • JS基础知识(五)- 异步进阶
  • JS-Web-API(一)- DOM & BOM
  • JS-Web-API(二)- 事件
  • JS-Web-API(三)- Ajax
  • JS-Web-API(四)- 存储
  • HTTP协议及缓存机制
  • 开发环境
  • 运行环境
  • 一面-基础
uploadhub
2022-05-28
目录

JS基础知识(三)- 作用域、闭包

# 1.几道面试题(以点带面)

  1. 说一下对变量提升的理解

  2. 说明this几种不同的使用场景

  3. 创建10个 <a> 标签,点击的时候弹出对应的序号

  4. 如何理解作用域

  5. 实际开发中闭包的应用

# 2.涉及知识点

  1. 执行上下文
  2. this
  3. 作用域
  4. 作用域链
  5. 闭包

# 2.1 执行上下文(Execution-context)

执行上下文

  1. 范围:一段 <script> 或者一个函数
  2. 全局:变量定义、函数声明 【针对一段<script>里面】
  3. 函数:变量定义、函数声明、this、arguments

注意:要留意“函数声明” 和 “函数表达式” 的区别

console.log(a);  // undefined
var a = 100;

fn('zhansan'); // zhangsan, 20
function fn(name) {
	age = 20;
	console.log(name, age); 
	var age;
}
1
2
3
4
5
6
7
8
9

# 2.2 this

this 要在执行时才能确认值,定义时无法确认

特殊情况:箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而非使用时所在的作用域指向的对象

this的使用场景

  1. 作为构造函数执行
  2. 作为对象属性执行
  3. 作为普通函数执行 【this指向window】
  4. call、 apply、 bind
var a = {
	name: 'A',
	fn: function() {
		console.log(this.name);
	}
}

a.fn();  // A, this === a
a.fn.call({name: 'B'});  // B, this === {name: 'B'}
var fn1 = a.fn;
fn1(); // 空, this === window
1
2
3
4
5
6
7
8
9
10
11

# 2.3 作用域(action-scope)

作用域

  1. 全局作用域
  2. 函数作用域
  3. 块级作用域(ES6新增)

自由变量:一个变量在当前作用域没有定义,但被使用了

var a = 100;
function fn() {
	var b = 200;
	// 当前作用域没有定义的变量,即“自由变量”
	console.log(a);
	console.log(b);
}
fn();//输出100 200
var a = 100;
function F1() {
	var b = 200;
	function F2() {
		var c = 300;
		console.log(a);  // a是自由变量
		console.log(b);  // b是自由变量
		console.log(c);
	}
	F2();
}
F1();//输出100 200 300
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2.4 闭包(closure)

闭包的使用场景

  1. 函数作为返回值
  2. 函数作为参数传递

函数作为返回值

function F1() {
	var a = 100;
	// 返回一个函数(函数作为返回值)
	return function() {
		console.log(a); // 自由变量,去定义它时的父作用域寻找
	}
}
// f1 得到一个函数
var f1 = F1();
var a = 200;
f1(); // 100
1
2
3
4
5
6
7
8
9
10
11

函数作为参数传递

function print(fn) {
    let b = 200
    fn()
}

let b = 100
function fnb() {
    console.log(b)
}

print(fnb) // 100
1
2
3
4
5
6
7
8
9
10
11

所有的自由变量【闭包】的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!!!

# 3.对前文问题的解答

# 3.1 创建10个 <a> 标签,点击的时候弹出对应的序号

for(var i = 0; i < 10; i++) {
	a = document.createElement('a');
	a.innerHTML = i + 1 + "<br>";
	document.body.appendChild(a);
}

window.onload = function() {
	var oA = document.getElementsByTagName('a');
	for(var i = 0; i < oA.length; i++) {
		oA[i].onclick = function(num) {
			return function() {
				alert(num);
			}
		}(i);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 3.2 实际开发中闭包的应用

// 闭包隐藏数据,只提供 API

function createCache() {
    // 闭包中的数据,被隐藏,不被外界访问
    const data = {}
    return {
        set: function(key,val) {
             data[key] = val
        },
        get: function(key) {
            return data[key]
        }
    }
}

const c = createCache()
c.set('a', 100)
console.log(c.get('a'))
// 封装变量,收敛权限。
function isFirstLoad() {
	var _list = [];
	return function(id) {
		if (_list.indexOf(id) >= 0) {
			return false;
		} else {
			_list.push(id);
			return true;
		}
	}
}
var firstLoad = isFirstLoad();
console.log(firstLoad(10)); // true
console.log(firstLoad(10)); // false
console.log(firstLoad(20)); // true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#面试#JavaScript
JS基础知识(二)- 原型和原型链
JS基础知识(四)- 异步和单线程

← JS基础知识(二)- 原型和原型链 JS基础知识(四)- 异步和单线程→

最近更新
01
HTTP协议及缓存机制
05-28
02
开发环境
05-28
03
JS基础知识(一)-变量类型和计算
05-28
更多文章>
Theme by Vdoing | Copyright © 2021-2023 uploadhub | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式