引用数据类型判断
1.instanceof()
判断一个实例是否属于某种类型,例如:
[1,2,3] instanceof Array ----- true
new Date(‘2019/01/05’) instanceof Date -------true
实现原理:
是只要 右边变量的 prototype 在 左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,表示左边变量并非是右边变量的实例。
2.constructor
当一个函数F被定义时,JS引擎会为F添加prototype原型,然后在prototype上添加一个constructor属性,指向F的引用。
注意:
1.null和undefined是无效的对象,因此是不会有constructor存在的,这两种类型的数据可以通过第三种方法来判断。
2.JS对象的constructor是不稳定的,这个主要体现在自定义对象上,当开发者重写prototype后,原有的constructor会丢失,constructor会默认为Object。
3.Object.prototype.toString
toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,即 toString运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx是具体的数据类型。
必须通过Object.prototype.toString.call来获取
大部分的对象都实现了自身的toString方法,这样就可能会导致Object的toString被终止查找,因此要用call来强制执行Object的toString方法。
NULL和Undefined的区别
共同点:都是原始类型,保存在栈中
不同点:
(1)undefined——表示变量声明过但并未赋过值。
它是所有未赋值变量默认值。
例如:var a; //a自动被赋值为undefined
(2)null——表示一个变量不再指向任何对象地址,将来可能指向一个对象。
当使用完一个比较大的对象时,需要对其进行释放内存时,设置为null
例如:var emps = [‘ss’,‘nn’];
emps = null; //释放指向数组的引用
const对象是否可以被改变
对象属性值可以被改变,对象的指向不可以
有效Number判断
ES6新增 Number.isNaN()检测数值是否是 NAN, Number.isFinite() 检测数值是否有限,取代全局的 isNaN() isFinite()。
ES5的 isFinite() , isNaN() 方法都会先将非数值类型的参数转化为Number类型再做判断,其实是不合理的,最造成 isNaN(‘NaN’) === true 的奇怪行为,'NaN’是一个字符串,但是isNaN却说这就是NaN。
深浅拷贝
区别
(1)深拷贝:拷贝的时候会生成一份新的数据,修改拷贝以后的数据不会原数据。
(2)浅拷贝:拷贝的时候只是拷贝了一份引用,修改拷贝以后的数据会影响原来的数据。
方式
(1)直接赋值给一个变量
(2)Object.assign() 浅拷贝
将源对象的所有可枚举属性,复制到目标对象(target)
(3)Array.prototype.slice(start,end) 深拷贝
返回从 start 开始(包括 )到 end 结束(不包括)为止的新数组
(4)Array.prototype.concat() 深拷贝
连接两个或多个数组,返回新数组
(5)JSON.parse(JSON.stringify()) 深拷贝
(6)Loadsh库中的API,如:.clone()、.cloneDeep()
(7)JSON.parse(JSON.stringify()) 深拷贝,不可以拷贝函数
(8)扩展运算符 浅拷贝
let obj2 = {…obj1}
若obj1内有对象属性时,对象是浅拷贝,需要:
let obj2 = {…obj1,obj3:…obj1.obj3}
如果所解构的原对象是一维数组或对象,其本质就是对基本数据类型进行等号赋值,那它就是深拷贝;
如果是多维数组或对象,其本质就是对引用类型数据进项等号赋值,那它就是浅拷贝;
最终的结论就是:解构赋值是浅拷贝(因为它确实不能对多维数组或对象达到深拷贝的作用);
遍历对象
1.Object.keys(obj)
返回一个数组,包括对象自身的所有可枚举属性(不含继承的、Symbol属性)。
2.for()遍历
3.Object.getOwnPropertyNames(obj)方法
获取到对象中的属性名,存到一个数组中,返回数组对象,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性).
4.Reflect.ownKeys(obj) 方法
返回一个数组,包含对象自身的所有属性
判断对象是否为空
1.将json对象转化为json字符串,再判断该字符串是否为"{}"
var data = {};
var b = (JSON.stringify(data) == “{}”);
2.for in 循环判断
3.Object.getOwnPropertyNames()方法
返回数组对象,判断数组的length来判断此对象是否为空
4.Object.keys()方法
ES6的新方法, 返回值也是对象中属性名组成的数组
ES6新增数组方法
foreach()
遍历数组,无返回值,不改变原数组,仅仅只是遍历
map()
对数组进行一次映射,返回新数组,数组元素个数不变,但是按照一定的条件转换,数组元素发生了变化。
filter()
对数组进行一次过滤,返回新数组,数组元素个数可能发生了改变,但是数组元素不会发生改变。
some()
遍历数组,有一项返回true,则停止遍历,结果返回true。不改变原数组。
every()
遍历数组每一项,每一项返回true,最终结果为true.有一项返回false,停止遍历,结果返回为false。不改变原数组。
reduce()
从数组的第二项开始遍历,让数组的前后两项进行某种计算,然后返回其值,并继续计算,不改变原数组,返回计算的最终结果
总结:
some、every返回true、false。
map、filter返回一个新数组。
reduce让数组的前后两项进行某种计算,返回最终操作的结果。
forEach 无返回值。
字符串方法
检索字符串
indexOf() 方法返回字符串中指定文本首次出现的索引(位置),不存在返回 -1
lastIndexOf() 方法返回指定文本在字符串中最后一次出现的索引,不存在返回 -1
ps:两种方法都接受作为检索起始位置的第二个参数。
search() 方法搜索特定值的字符串,并返回匹配的位置
indexOf() 与 search()区别在于:
search() 方法无法设置第二个开始位置参数。
indexOf() 方法无法设置更强大的搜索值(正则表达式)。
提取部分字符串
slice() 提取字符串的某个部分并在新字符串中返回被提取的部分。
该方法设置两个参数:起始索引(开始位置),终止索引(结束位置)。
参数为负,则从字符串的结尾开始计数。
省略第二个参数,则该方法将裁剪字符串的剩余部分
substring() 类似于 slice()。
无法接受负的索引。
substr() 类似于 slice()。
第二个参数规定被提取部分的长度,不能为负
替换字符串内容
replace() 用另一个值替换在字符串中指定的值,返回的是新字符串
concat() 连接两个或多个字符串,可用于代替加运算符
trim() 删除字符串两端的空白符
把字符串转换为数组
split()
省略分隔符,被返回的数组将包含 index [0] 中的整个字符串。
分隔符是 “”,被返回的数组将是间隔单个字符的数组
提取字符串字符
charAt() 返回字符串中指定下标的字符串
charCodeAt() 返回字符串中指定索引的字符 unicode 编码
翻转字符串
方法一:
先将字符串转化为数组,待处理完后再将结果转化回字符串:
split()方法将一个字符串拆成字符并返回一个数组
reverse()方法使数组反转
join()方法将数组中的所有元素边接成一个字符串
var a=“foo”;
var b=a.split("")//转化为字符串数组
.reverse()//进行反转
.join("")//数组中的字符拼接回字符串
方法二:
把字符串中的字符倒序存入数组,再将数组转化为字符串:
var newString = [];
for(var i = a.length-1,j = 0; i >= 0; i --,j ++){
newString[j] = a[i];
};
newString.join();