javascript篇
一、数据类型
JavaScript 有几种类型
- 基本数据类型:undefined、null、boolean、number、string、symbol(es6的新数据类型)
- 引用数据类型:object、array、function(统称为object)
数据类型检测
typeof
对于基本数据类型来说,除了 null
都可以显示正确的类型,typeof 对于对象来说,除了函数都会显示 objec
typeof 5 // 'number'
typeof '5' // 'string'
typeof undefined // 'undefined'
typeof false// 'boolean'
typeof Symbol() // 'symbol'
console.log(typeof null) //object
console.log(typeof NaN) //number
typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'
instanceof
通过原型链来判断数据类型的
p1 = new Person()
p1 instanceof Person // true
Object.prototype.toString.call()可以检测所有的数据类型,算是一个比较完美的方法了。
var obj={}
var arr=[]
console.log(Object.prototype.toString.call(obj)) //[object Object]
console.log(Object.prototype.toString.call(arr)) //[object Array]
深浅拷贝
浅拷贝
Object.assign() //es6的方法
Object.assign会合并对象生成一个新对象。如果对象的属性是普通类型改变之后新对象不会改变,如果是引用类型改变后新对象也会改变,所以Object.assign实际上还是浅拷贝。
var obj={aa:1,b:{item:'45'}};
var newObj=Object.assign({},obj);
obj.aa=2;
obj.b.item='kk';
console.log(newObj.aa); //1
console.log(newObj.b.item); //kk
深拷贝
JSON.parse(JSON.stringify(obj))
利用JSON.stringify(obj)将对象先转为json字符串,再JSON.parse()转回为json对象可以实现深拷贝,这也是比较常用的一种方法。
用js实现一个深拷贝
其实深拷贝可以拆分成 2 步,浅拷贝 + 递归,浅拷贝时判断属性值是否是对象,如果是对象就进行递归操作,两个一结合就实现了深拷贝。
function cloneDeep(source) {
if (!isObject(source)) return source; // 非对象返回自身
var target = Array.isArray(source) ? [] : {};
for (var key in source) {
if (source.hasOwnProperty(i)) {
if (isObject(source[key])) {
target[key] = cloneDeep(source[key]); // 注意这里
} else {
target[key] = source[key];
}
}
}
return target;
}
function isObject(obj) {
return typeof obj === 'object' && obj != null;
}
二、作用域
变量声明提升
- 在 JavaScript 中,函数声明(function aa(){})与变量声明(var)经常被 JavaScript 引擎隐式地提升到当前作用域的顶部。
- 函数声明的优先级高于变量,如果变量名跟函数名相同且未赋值,则函数声明会覆盖变量声明
- 声明语句中的赋值部分并不会被提升,只有变量的名称被提升
作用域链
因为函数的嵌套形成作用域的层级关系。当函数执行时,从当前作用域开始搜,没有找到的变量,会向上层作用域查找,直至全局函数,这就是作用域链。
- 在 JavaScript 中,作用域为 function(){}内的区域,称为函数作用域。
- 全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节
闭包
闭包的原理就是作用域链,比函数F内部有一个函数G,函数 G可以访问到函数F中的变量,那么函数G就是闭包。
function F() {
let a = 1
window.G = function () {
console.log(a)
}
}
F()
G() // 1