前端JS面试题-基础-作用域和闭包
时间:2021-07-11
本文章向大家介绍前端JS面试题-基础-作用域和闭包,主要包括前端JS面试题-基础-作用域和闭包使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
写在前面:本文内容主要根据慕课网双越老师的付费课程“一天时间迅速准备前端面试 快速构建初级前端知识体系 ”进行编写,主要是为了自己在面试前总结学习,欢迎留言指教。
本文包括如下内容:
每一部分包括题目和知识点两部分。
作用域和闭包
题目
- this的不同应用场景,如何取值
- 手写bind函数
- 实际开发中闭包的应用场景,举例说明
- 场景题
1. this的不同应用场景,如何取值
有5种应用场景,如下:
- 作为普通函数——返回window
- 使用 call apply bind——传入什么绑定什么
- 作为对象方法被调用——返回对象本身
- 在class方法中调用——当前实例本身
- 箭头函数——上级作用域
2. 手写bind函数
bind() 方法会创建一个新函数,当这个新函数被调用时,它的 this 值是传递给 bind() 的第一个参数, 它的参数是 bind() 的其他参数和其原本的参数。
//模拟 bind
Function.prototype.bind1 = 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)
}
}
// 使用
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)
console.log(fn2())
// 结果
this {x: 100}
10 20 30
this is fn1
3. 实际开发中闭包的应用场景,举例说明
- 函数作为返回值,以cache缓存为例:
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'))
- 函数作为参数被传递,以setTimeout定时器为例:
function fn() {
alert()
}
const func = fn()
// 第一个参数是一个函数,或者是一段执行的js代码,第二参数是第一个参数执行的时间间隔。
setTimeout(func, 1000)
被面试官问到什么是闭包,最好的回答就是把两个 demo 写一遍,然后说出闭包的使用场景【cache缓存 setTimeout定时器 异步操作 等】。不用说什么概念。
4. 场景题
这个代码打印出来的序号都是 10,应该在for里定义let i,这样需要都是递增的。
知识点
1. 作用域
- 全局作用域
- 函数作用域
- 块级作用域(ES6新增)【大括号内是一个块级作用域】
2. 自由变量【当前作用域未定义的变量】
- 一个变量在当前作用域没有定义,但被使用了
- 向上级作用域,一层一层一次寻找,直至找到为止
- 如果到全局作用域都没找到,则报错 xx is not defined
所有的自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!!!
3. 闭包
作用域引用的特殊情况,有两种表现:
- 函数作为参数被传递
- 函数作为返回值被返回
4. this
有5种应用场景,如下:
- 作为普通函数——返回window
- 使用 call apply bind——传入什么绑定什么
- 作为对象方法被调用——返回对象本身
- 在class方法中调用——当前实例本身
- 箭头函数——上级作用域
// 普通函数:返回window
function fn1() {
console.log(this)
}
fn1() //window
// call apply bind:传入什么绑定什么
fn1.call({x: 100}) //{x: 100}
const fn2 = fn1.bind({x:200})
fn2() //{x:200}
// 作为对象方法被调用:返回对象本身
const zhangsan = {
name: '张三',
sayhi(){
console.log(this)
}
}
zhangsan.sayhi() //{name: "张三", sayhi: ƒ}
// 在class方法中调用:返回实例本身
class People{
constructor(name){
this.name = name
}
sayhi(){
console.log(this)
}
}
const zhangsan = new People('张三')
zhangsan.sayhi() //People {name: "张三"}
// 箭头函数:上级作用域
const zhangsan = {
name: '张三',
wait(){
setTimeout(()=>{
console.log(this)
})
},
waitAgain(){
setTimeout(function () {
console.log(this)
})
}
// 两个函数进行对比
}
zhangsan.wait() //{name: "张三", wait: ƒ, waitAgain: ƒ}
zhangsan.waitAgain() //window
this取什么值,是在函数执行的时候确认的,不是在函数定义的时候确认的
原文地址:https://www.cnblogs.com/wumengcheng/p/14998066.html
- HDU 3595 GG and MM(Every-SG)
- CSS布局(四) float详解
- php http_build_query 拼接数组 可以用这个函数
- 神器Pytorch(1)
- PHP中的Array2String & String2Array
- CSS布局(五) 网页布局方式
- CSS布局(六) 对齐方式
- css渲染(一) 字体
- css渲染(二) 文本
- BZOJ 2463: [中山市选2009]谁能赢呢?(智商)
- excel导入与导出
- 【LeetCode 204】关关的刷题日记40 Number of Boomerangs
- 洛谷P1339 [USACO09OCT]热浪Heat Wave(最短路)
- excel导出类
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【小白学金融】—— 用 STATA 计算 CAR 值
- 3行核心CSS代码的rate评分组件,秀到你怀疑人生
- 用 Rust 和 N-API 开发高性能 NodeJS 扩展
- 教你 Linux 免密登录配置
- Linux阅码场 - Linux内核月报(2020年08月)
- 事务的本质和死锁的原理
- 深度神经网络conda环境下载
- 隧道构建:端口转发的原理和实现
- SAP Spartacus注入自定义的CurrentProductService
- Redis系列(十一)redis命令全集
- Jinkens+gitlab针对k8s集群实现CI/CD
- Vue 踩过的坑
- Java TCP/UDP/HttpClient简例
- 让你设计实现一个签到功能,到底用MySQL还是Redis?
- 如何防止MySQL重复插入数据,这篇文章会告诉你