本文正在参加「金石计划 . 瓜分6万现金大奖」
JS的数据类型
基本数据类型
1.Number
2. String
3. Boolean
4. Null
5. Undefined
6. Symbol
7. BigInt
引用数据类型
1. Object(对象)
2. Array(数组)
3. Function(函数)
4. Date等(内置对象)
更多细节可查看,JS中令人疑惑的数据类型及其判断方法
JS中的最大值
相信刷过一些算法的伙伴们都知道,在javascript这门语言中存在最大值,所以后来在ES6中才出现了BigInt的数据类型,言归正传,那在JS中最大值为 2^53,最小值为-2^53,但是这两个值,不太安全,所以我们一般将2^53 - 1作为 最大安全值 (Number.MAX_SAFE_INTEGER),-2^53 + 1作为 最小安全值 (Number.MAX_SAFE_INTEGER)
深浅拷贝
通常情况下我们所谓的拷贝,是对于对象的拷贝,基本数据类型的拷贝没有意义,所以我们浅谈一下深浅拷贝到底在理论上是怎么实现的?
浅拷贝: 只拷贝一层,相当于拷贝的是原对象的引用地址,拷贝对象改变,则是引用地址中,也就是原对象的引用地址中的内容发生改变,所以原对象也发生改变。
深拷贝: 深拷贝相当于层层拷贝,是拿着原对象引用地址中的内容,在堆中重新开辟的了一个空间,存放与原对象引用地址中一样的内容,是两个独立的对象,拷贝得到新对象不会影响原对象。
闭包
相信前端学习的小伙伴都不陌生了吧,那当面试官提问我们什么是闭包的时候,我们应该怎么回答的相对专业一些呢?
闭包: 当js执行引擎中,一个函数执行完毕后该函数的执行上下文就应该被浏览器的垃圾回收机制回收掉,但是当一个函数内部的函数被返回出来执行,那么内部函数对外部函数存在引用,引用的这些变量的集合称之为闭包。这些集合不会随外部函数的执行上下文的回收而消失。
相关的一些细节可看看笔者之前写过的浅谈javascript闭包这篇文章。
变量提升
要了解变量提升,首先我们要知道js的预编译过程,可以看JS入门级理解(从作用域到作用域链),笔者曾在这篇文章中有较为详细的描述。
让我们看几个例子来体会一下变量声明的过程
1.js
console.log(name); // undefined 在预编译阶段声明了name变量在作用域顶端但没有赋值
var name = '寒月十九'
if (false) {
var age = 20
}
console.log(age); // undefined 虽然if的逻辑没有走进去,但是在预编译时同样会声明age这个变量,没有赋值逻辑
-----------------------
2.js
console.log(fun); // ƒ fun() {} 函数声明提升,值为函数体
function fun() {}
if (null) {
function fun2() {} // 相当于 var fun2 = function() {},判断逻辑没有走进去,只声明了变量没有赋值
}
console.log(fun2); // undefined
-----------------------
3.js
console.log(fun); // ƒ fun() {} 变量fun先提升到作用域顶端,然后函数声明也提升将fun赋值为函数体
var fun = '寒月十九'
function fun() {}
console.log(fun); // '寒月十九' 虽然被赋值为函数体,从上往下执行时又被赋值为字符串
isNaN 和 Number.isNaN 的区别?
isNaN() 能判断 NaN和能成功转成数字的值,不能成功转成数字的值为false 存在隐式类型转化
Number.isNaN()只能判断 NaN
for in 如何不遍历到原型上的属性?
所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。这个方法可以用来检测一个对象是否含有特定的自身属性;和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
代码实现:
function Person(name) {
this.name = name
}
Person.prototype.age = 20
const person = new Person('寒月十九')
for (const key in person) {
person.hasOwnProperty(key) && console.log(key);
}