网站首页 > 技术文章 正文
前言
今天是元宵节,猿宵节。一个作为程序员通宵加班的节日,就应该来篇文章祝个兴。承接之前俩篇文章的内容。今天仍是JavaScript的面试内容。
接招吧~
zhen
1. 闭包
闭包属于一种特殊的作用域,称为 静态作用域。它的定义可以理解为: 父函数被销毁 的情况下,返回出的子函数的[[scope]]中仍然保留着父级的单变量对象和作用域链,因此可以继续访问到父级的变量对象,这样的函数称为闭包。
- 闭包会产生一个很经典的问题:
- 多个子函数的[[scope]]都是同时指向父级,是完全共享的。因此当父级的变量对象被修改时,所有子函数都受到影响。
- 解决:
- 变量可以通过 函数参数的形式 传入,避免使用默认的[[scope]]向上查找
- 使用setTimeout包裹,通过第三个参数传入
- 使用 块级作用域,让变量成为自己上下文的属性,避免共享
2. script 引入方式:
- html 静态<script>引入
- js 动态插入<script>
- <script defer>: 异步加载,元素解析完成后执行
- <script async>: 异步加载,但执行时会阻塞元素渲染
3. 对象的拷贝
- 浅拷贝: 以赋值的形式拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响
- Object.assign
- 展开运算符(...)
- 深拷贝: 完全拷贝一个新对象,修改时原对象不再受到任何影响
- JSON.parse(JSON.stringify(obj)): 性能最快
- 具有循环引用的对象时,报错
- 当值为函数、undefined、或symbol时,无法拷贝
- 递归进行逐一赋值
4. new运算符的执行过程
- 新生成一个对象
- 链接到原型: obj.__proto__ = Con.prototype
- 绑定this: apply
- 返回新对象(如果构造函数有自己 retrun 时,则返回该值)
5. instanceof原理
能在实例的 原型对象链 中找到该构造函数的prototype属性所指向的 原型对象,就返回true。即:
// __proto__: 代表原型对象链 instance.[__proto__...] === instance.constructor.prototype // return true 复制代码
6. 代码的复用
当你发现任何代码开始写第二遍时,就要开始考虑如何复用。一般有以下的方式:
- 函数封装
- 继承
- 复制extend
- 混入mixin
- 借用apply/call
7. 继承
在 JS 中,继承通常指的便是 原型链继承,也就是通过指定原型,并可以通过原型链继承原型上的属性或者方法。
- 最优化: 圣杯模式
var inherit = (function(c,p){ var F = function(){}; return function(c,p){ F.prototype = p.prototype; c.prototype = new F(); c.uber = p.prototype; c.prototype.constructor = c; } })(); 复制代码
- 使用 ES6 的语法糖 class / extends
8. 类型转换
大家都知道 JS 中在使用运算符号或者对比符时,会自带隐式转换,规则如下:
- -、*、/、% :一律转换成数值后计算
- +:
- 数字 + 字符串 = 字符串, 运算顺序是从左到右
- 数字 + 对象, 优先调用对象的valueOf -> toString
- 数字 + boolean/null -> 数字
- 数字 + undefined -> NaN
- [1].toString() === '1'
- {}.toString() === '[object object]'
- NaN !== NaN 、+undefined 为 NaN
9. 类型判断
判断 Target 的类型,单单用 typeof 并无法完全满足,这其实并不是 bug,本质原因是 JS 的万物皆对象的理论。因此要真正完美判断时,我们需要区分对待:
- 基本类型(null): 使用 String(null)
- 基本类型(string / number / boolean / undefined) + function: 直接使用 typeof即可
- 其余引用类型(Array / Date / RegExp Error): 调用toString后根据[object XXX]进行判断
很稳的判断封装:
let class2type = {} 'Array Date RegExp Object Error'.split(' ').forEach(e => class2type[ '[object ' + e + ']' ] = e.toLowerCase()) function type(obj) { if (obj == null) return String(obj) return typeof obj === 'object' ? class2type[ Object.prototype.toString.call(obj) ] || 'object' : typeof obj }
尾声
无论怎么样,在这个元宵佳节,还是祝各位开开心心,一年没bug~
猜你喜欢
- 2025-06-13 大型前端应用如何做系统融合?(系统前端怎么做)
- 2024-10-04 小厂一面:30分钟速通,拿下一血(前端)
- 2024-10-04 【中大厂前端面试百问】这不迷死你?
- 2024-10-04 写给准备跳槽的Web前端工程师(第二章)
- 2024-10-04 网络安全、Web安全、渗透测试之笔经面经总结
- 2024-10-04 写给准备跳槽的Web前端工程师(第三章)
- 2024-10-04 燃数科技前端25-40K*14薪一面超简单,下周二面啦
- 2024-10-04 前端面试总结 前端面试题目100及最佳答案
- 2024-10-04 前端社招一点面试记录 社招前端面试自我介绍
- 2024-10-04 Java大佬分享:字节跳动面经分享,从JVM到线程池
你 发表评论:
欢迎- 523℃Oracle分析函数之Lag和Lead()使用
- 520℃几个Oracle空值处理函数 oracle处理null值的函数
- 517℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 504℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 501℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 493℃【数据统计分析】详解Oracle分组函数之CUBE
- 472℃Oracle有哪些常见的函数? oracle中常用的函数
- 471℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (61)
- 前端数组 (73)
- 前端排序 (47)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)