
JS知识点--平时视频或做题时发现的知识漏洞(持续更新)
发布日期:2021-05-07 09:21:34
浏览次数:19
分类:精选文章
本文共 4377 字,大约阅读时间需要 14 分钟。
1.如果编写了非有效的js时,例如把return写成retrun,会抛出ReferenceError
2.使用JSON.parse()方法,可以将JSON字符串解析为JavaScript值
3.对于一个var name
如果只声明变量而未初始化,则会打印undefined。而如果用let/const
关键字声明变量且未初始化,则它被引用时会抛出ReferenceError,此情况被称为“暂时性死区”
4.在ES2020中,通过#号可以给class添加私有变量,即在class外部无法获取该值,如果尝试输出,则会抛出SyntaxError
5.SyntaxError:Javascript引擎发现了不符合语法规范的代码
ReferenceError:当对变量/项的引用被破坏或不存在时,将引发此错误.6.在使用typeof判断null的数据类型时,会显示为object类型,这是存在的一个小问题,特殊记一下。此外typeof判断引用类型时,只能分辨出object和function两种类型
7.三种数据类型检测方法比较:
- instanceof可以准确判断复杂引用数据类型,但是不能正确判断基础数据类型
- typeof可以判断基础数据类型(null除外),但是引用数据类型中,除了function类型外,其他的也无法判断
- Object.prototype.toString(),或者Object.prototype.toString.call(xxx),最终返回[Object 数据类型],注意数据类型的首字母大写,如[Object Number]
8.数据类型转换:
a.强制类型转换 6种- Number():对于布尔型true和false分别被转化成1和0; 数字则返回自身;null返回0;undefined返回NaN; 对于字符串,如果字符串中只包含数字则将其转换为十进制;如果字符串中包含有效的浮点格式将其转换为浮点数值;如果是空字符串将其转换成0;如果不是以上格式的字符串则返回NaN symbol型则抛出错误
- parseInt()
- parseFloat()
- toString()
- String()
- Boolean():除了undefined,null,false,’’,NaN,0转换出来的是false,其余都是true
b.隐式类型转换 5种
- 逻辑运算符&&、||、!
- 运算符+、-、*、/ ‘+’号操作符不仅可以用作数字相加,也可以用于字符串拼接 如果其中有一个是字符串,另外一个是undefined、null或布尔型,则调用toString()方法进行字符串拼接 如果其中有一个是数字,另外一个是undefined、null、布尔型或数字,则会将其转化成数字进行加法运算 如果其中一个是字符串,一个是数字,则会按照字符串规则进行拼接 如果**‘+’两边都为字符串**,则将得到经过加法运算后的字符串
- 关系运算符>、<、>=、<=
- 相等运算符==: 如果类型相同,无需进行类型转换; 如果其中一个操作值为null或者undefined,那么另外一个操作值必须为null或者undefined才会返回true,否则都返回false; 如果其中一个是symbol类型,那么返回false; 两个操作值都为string和number类型,那么就会把字符串类型转换为number; 如果一个操作值为boolean,那么转换为number 如果一个操作值为object,且另一方为string、number、或者symbol,就会把object转换成原始类型再进行判断
- if/while条件
9.object转换规则
- 如果部署了
[symbol.toPrimitive]()
方法,优先调用再返回 - 调用valueOf(),如果转换为基础类型则返回
- 调用toString(),如果转换为基础类型则返回
- 如果都没有返回基础类型,会报错
10.JS中实现浅拷贝的方法:4种
浅拷贝即只能拷贝一层对象,如果出现对象的嵌套,则无能为力
- object.assign:object.assign是ES6中object的一个方法,该方法可以用于JS对象的合并等多个用途,其中一个用途就是可以浅拷贝。语法为
object.assign(target,...sources)
示例代码:
let target = { }let source = { a:{ b:2}}object.assign(target,source) // 拷贝的是引用数据类型,即拷贝的是地址console.log(target) // {a:b:10}source.a.b = 10console.log(source) // {a:b:10}console.log(target) // {a:b:10}
- 扩展运算符方法:利用JS扩展运算符,在构造对象的同时完成浅拷贝的方法。语法为
let cloneObj = {...obj}
示例代码:
let obj = { a:1,b:{ c:1}}let obj2 = { ...obj}obj.a = 2console.log(obj)// {a:2,b:{c:1}}console.log(obj2)// {a:1,b:{c:1}}obj.b.c = 2console.log(obj)// {a:2,b:{c:2}}console.log(obj2)// {a:1,b:{c:2}}
- concat拷贝数组:只能用于数组的拷贝
示例代码:
let arr = [1,2,3]let newArr = arr.concat()newArr[1] = 100console.log(arr)// [1,2,3]console.log(newArr)// [1,100,3]
- slice拷贝数组:仅针对数组对象,语法为
arr.slice(begin,end)
,返回一个新的数组对象,不会更改原数组
11.手工实现一个浅拷贝
- 对基础类型做一个最基本的浅拷贝
- 对引用类型开辟一个新的存储,并且拷贝一层对象属性
代码示例:
const shallowClone = (target) => { if(typeof target === 'object' && target !== null){ const cloneTarget = Array.isArray(target)?[]:{ } for(let prop in target){ if(target.hasOwnProperty(prop)){ cloneTarget[prop] = target[prop] } } return cloneTarget } else{ return target }}
12.JS中实现深拷贝的方法:
深拷贝的原理为:将一个对象从内存中完整的拷贝出来一份给目标对象,并从堆内存中开辟一个全新的空间存放新对象,且新对象的修改并不会改变原对象,二者实现真正的分离
- 乞丐版(JSON.stringify):是目前开发过程中最简单的深拷贝方法。
示例代码:
let obj = { a:1,b:[1,2,3]}let str = JSON.stringify(obj)let obj2 = JSON.parse(str)console.log(obj2) // {a:1,b:[1,2,3]}obj.a = 2obj.b.push(4)console.log(obj) // {a:2,b:[1,2,3,4]}console.log(obj2) // {a:1,b:[1,2,3]}
JSON方法中存在的缺陷:
1.拷贝的对象的值中如果有函数、undefined、symbol 这几种类型,经过 JSON.stringify 序列化之后的字符串中这个键值对会消失; 2.拷贝 Date 引用类型会变成字符串; 3.无法拷贝不可枚举的属性; 4.无法拷贝对象的原型链; 5.拷贝 RegExp 引用类型会变成空对象; 6.对象中含有 NaN、Infinity 以及 -Infinity,JSON 序列化的结果会变成 null; 7.无法拷贝对象的循环应用,即对象成环 (obj[key] = obj)。- 改进版,通过递归实现
const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj !== null)const deepClone = function (obj, hash = new WeakMap()) { if (obj.constructor === Date) return new Date(obj) // 日期对象直接返回一个新的日期对象 if (obj.constructor === RegExp) return new RegExp(obj) //正则对象直接返回一个新的正则对象 //如果循环引用了就用 weakMap 来解决 if (hash.has(obj)) return hash.get(obj) let allDesc = Object.getOwnPropertyDescriptors(obj) //遍历传入参数所有键的特性 let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc) //继承原型链 hash.set(obj, cloneObj) for (let key of Reflect.ownKeys(obj)) { cloneObj[key] = (isComplexDataType(obj[key]) && typeof obj[key] !== 'function') ? deepClone(obj[key], hash) : obj[key] } return cloneObj}
13.继承:继承可以使子类别具有父类的各种属性和方法
当前一共有6种继承方法:- 原型链继承:缺点为共享问题。它们的内存空间是共享的,当一个发生变化的时候,另外一个也随之进行了变化。
- 构造函数继承(借助call):优化了原型链继承的共享问题,但是其只能继承父类的实例属性和方法,不能继承原型属性或者方法。
- 组合继承(前两组结合):这里涉及多次构造,增加性能开销
发表评论
最新留言
感谢大佬
[***.8.128.20]2025年03月20日 21时23分08秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
一个系统部署多个tomcat实例
2019-03-05
HP服务器设置iLO
2019-03-05
Redhat 平台下LVM管理说明
2019-03-05
oracle数据库迁移
2019-03-05
《Dotnet9》系列-开源C# Winform控件库强力推荐
2019-03-05
从头实现一个WPF条形图
2019-03-05
.NET CORE(C#) WPF 重新设计Instagram
2019-03-05
.NET CORE(C#) WPF 方便的实现用户控件切换(祝大家新年快乐)
2019-03-05
C# WPF开源控件库:MahApps.Metro
2019-03-05
使用QT实现一个简单的登陆对话框(纯代码实现C++)
2019-03-05
QT :warning LNK4042: 对象被多次指定;已忽略多余的指定
2019-03-05
GLFW 源码 下载-编译-使用/GLAD配置
2019-03-05
针对单个网站的渗透思路
2019-03-05
Typescript 学习笔记六:接口
2019-03-05
拥抱HTML5
2019-03-05
Scala字符串与容器
2019-03-05
关于JTAG,你知道的和不知道的都在这里
2019-03-05
【CTF】CTFHub 技能树 文件头检查 writeup
2019-03-05
web服务器-并发服务器2
2019-03-05