JavaScript 的基本类型有哪些?引用类型有哪些?null 和undefined 的区别?
基本数据类型:Number、String、Boolean、null、undefined,Symbol (ES6),BigInt (ES10)
引用数据类型:Function、Object、Array
如何判断JavaScript的数据类型?
1、typeof
typeof 对于简单数据类型(undefined、null、boolean、number 、string )可以判断的出来,但是对于复杂数据类型就不起作用(Array),因为对于复杂数据类型的判断结果也是object,跟null的判断返回结果相同,因此这个时候判断不出来是复杂数据类型还是null简单数据类型,返回值为该值的数据类型(undefined、null(object)、boolean、number 、string )
var arr = new Array();
console.log(typeof 1);//number
console.log(typeof 'xiaoming');//string
console.log(typeof true);//boolean
console.log(typeof undefined);//undefined
console.log(typeof null);//object
console.log(typeof arr);//object
2、instanceof
instanceof可以判断对象是不是另一个对象实例,主要作用是来判断复杂数据类型的,返回值为布尔值;
console.log([] instanceof Array);//true
console.log({} instanceof Object);//true
console.log(function(){} instanceof Function);//true
3、**Object.prototype.toString.call()
Object.prototype.toString.call()能够准确的判断所有的数据类型;
var a = Object.prototype.toString;
console.log(a.call("xiaoming"));//String
console.log(a.call(1));//Number
console.log(a.call(true));//Boolean
console.log(a.call(null));//Null
console.log(a.call(undefined));//Undefined
console.log(a.call([]));//Array
console.log(a.call(function () { }));//Function
console.log(a.call({}));//Object
4、constructor
constructor也能够判断多种数据类型,这里跟instanceof一样,null和undefined除外
console.log(("xiaoming").constructor === String);//true
console.log((1).constructor === Number);//true
console.log((true).constructor === Boolean);//true
//console.log((null).constructor === Null);
//console.log((undefined).constructor === Undefined);
console.log(([]).constructor === Array);//true
console.log((function () { }).constructor === Function);//true
console.log(({}).constructor === Object);//true
5、Array.isArray
可以判断一个数据类型是否为数组
let arr = [1,2,3]
console.log(Array.isArray(arr)) // true
console.log(Array.isArray({}) // false
3、简述创建函数的几种方式?
函数声明
function fn(){}
函数表达式
let fn = function(){}
构造函数(函数对象方式)
let fn = new function(num:1)
fn.num
4、Javascript 创建对象的几种方式?
1、 字面量创建
var per1 = {
name: '张三',
age: '18',
eat: function () { console.log('吃东西') }
}
2、new Object方式创建
var per2 = new Object()
per2.name = '李四';
per2.age = '18';
per2.read = function () { console.log('读书') }
3、通过工厂模式创建
function person(name,age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.play = function () {
console.log('玩游戏')
}
return obj
}
var per3 = person('王五','20')
4、通过构造函数创建,实列对象也指向原型对象,所以可以找到对象原型上的属性
function animal(name, age) {
this.name = name;
this.age = age;
this.food = function () {
console.log('骨头')
}
}
var ani1 = new animal('泰迪',3) // ani1称为实例化对象
console.log(ani1.__proto__ === animal.prototype) // true 两者都是指向构造函数的原型
console.log(ani1.__proto__.constructor === animal.prototype.constructor) // true 两者都指向的是构造函数
console.log(ani1 instanceof animal) // true 以此来判断对象是不是这种数据类型
javascript中宿主对象和原生对象的区别是什么
- 所有的BOM和DOM对象都是宿主对象,js原生的基本数据类型,引用数据类型等都属于原生对象。
Array数组常用方法
length属性动态获取数组长度
join() 将一个数组转成字符串。返回一个字符串。
reverse() 将数组中各元素颠倒顺序
delete 运算符只能删除数组元素的值,而所占空间还在,总长度没变(arr.length)。
shift() 删除数组中第一个元素,返回删除的那个值,并将长度减1。
pop() 删除数组中最后一个元素,返回删除的那个值,并将长度减1。
unpop() 删除数组中第一个元素
unshift() 往数组前面添加一个或多个数组元素,长度要改变。arrObj.unshift(“a”,“b,“c”)
concat( ) 连接数组
slice( ) 返回数组的一部分
sort( ) 对数组元素进行排序
splice( ) 插入、删除或替换数组的元素
toLocaleString( ) 把数组转换成局部字符串
toString( ) 将数组转换成一个字符串
遍历数组常用方法
1. forEach()
- 数组里的元素个数有几个,该方法里的回调就会执行几次
- 第一个参数是数组里的当前元素,第二个参数为数组里当前元素的索引值,第三个参数则是它自己
- 没有返回值,本质上等同于 for 循环,对每一项执行 function 函数。即map是返回一个新数组,原数组不变,forEach 是改变原数组。
- 不支持 continue,用 return false 或 return true 代替。
- 不支持 break,用 try catch/every/some 代替
private forEach() {
type itemType = {
cityId: number,
cityName: string
}
const arr = [
{ cityId: 195, cityName: '深圳'},
{ cityId: 196, cityName: '北京'},
{ cityId: 197, cityName: '上海'}
]
arr.forEach((item: itemType, index: number, arr: any) => {
console.log(`index:${index},item:${JSON.stringify(item)},arr:${JSON.stringify(arr)}`)
})
}
2.map()
- map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
- map() 方法按照原始数组元素顺序依次处理元素。
- 使用比较广泛,但其性能还不如 forEach
- 不会改变原始数组。
let arr = [1, 2, 3, 4, 5, 6]
let newArr = arr.map((item: any) => {
return item * item
})
console.log(newArr)
3.some()
遍历数组,只要有一个以上的元素满足条件就返回 true,否则返回 false ,退出循环
private some(id: number) {
const arr = [
{ cityId: 195, cityName: '深圳'},
{ cityId: 196, cityName: '北京'},
{ cityId: 198, cityName: '上海'}
]
let result = arr.some((item: any) => {
return item.cityId === id
})
console.log(`传入:${id},结果:${result}`)
}
4. every()
遍历数组,每一个元素都满足条件 则返回 true,否则返回 false
private every() {
const arr = [1,2,3,4,5]
let result = arr.every((item: any) => {
return item > 0
})
console.log(`结果:${result}`) // true
}
// ====================================================
private every() {
const arr = [1,2,3,4,5]
let result = arr.every((item: any) => {
return item > 10
})
console.log(`结果:${result}`) // false
}
5. filter()
会筛选后返回一个新的数组,如果不用箭头函数写的话需要写return
var arr = [
{ id: 1, text: 'aa', done: true },
{ id: 2, text: 'bb', done: false } ]
var arr2 = arr.filter(item => item.done)
console.log(arr2) // { id: 1, text: 'aa',done:true}
6. find()
遍历数组,返回符合条件的第一个元素,如果没有符合条件的元素则返回 undefined
let arr = [1,2,2,3,3,3,3,4,4,5,6]
let num = arr.find((item) => {
return item === 3
})
console.log(num) // 3
// ===========
let arr = [1,2,2,3,3,3,3,4,4,5,6]
let num = arr.findIndex((item) => {
return item === 10
})
console.log(num) // -1
7. findIndex()
遍历数组,返回符合条件的第一个元素的索引,如果没有符合条件的元素则返回 -1
let arr = [1,2,2,3,3,3,3,4,4,5,6]
let num = arr.findIndex((item:any) => {
return item === 2
})
console.log(num) // 1
// ===================
let arr = [1,2,2,3,3,3,3,4,4,5,6]
let num = arr.findIndex((item:any) => {
return item === 10
})
console.log(num) // -1
8. for…of…(ES6)
可以在遍历数组的时候将数组中对象的数据结构出来
const arr = [
{ cityId: 195, cityName: '深圳'},
{ cityId: 196, cityName: '北京'},
{ cityId: 197, cityName: '上海'}
]
for( {cityId}of arr) {
console.log(cityId) // 195 196 197
}
9.for
const arr = [
{ cityId: 195, cityName: '深圳'},
{ cityId: 196, cityName: '北京'},
{ cityId: 197, cityName: '上海'}
]
for(let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
10. reduce
arr.reduce(function(prev,cur,index,arr){ ... }, init);
arr :原数组;
prev :上一次调用回调时的返回值,或者初始值 init;
cur : 当前正在处理的数组元素;
index :当前正在处理的数组元素的索引,若提供 init 值,则索引为0,否则索引为1;
init :初始值
其实常用的参数只有两个:prev 和 cur。
var arr = [1,2,3,4];
var sum = arr.reduce((prev,cur)=>{
return prev + cur;
}) // 10
<!-- 设定初始值求和 -->
var sum = arr.reduce((prev,cur)=>{
return prev + cur;
},10) // 20
方法对于100万的循环时间
for最快,但可读性比较差
forEach比较快,能够控制内容
for....of比较慢,香
for...in比较慢,不方便
遍历对象的常用方法
1.for…in…
- for...in 语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)
- for in得到对对象的key或数组,字符串的下标
const arr = [
{ cityId: 195, cityName: '深圳'},
{ cityId: 196, cityName: '北京'},
{ cityId: 197, cityName: '上海'}
]
const obj = { cityId: 195, cityName: '深圳'}
for(const key in arr) {
console.log(`数组key-${key}`)
}
for(const key in obj) {
console.log(`对象key-${obj[key]}`)
}
字符串常用方法
Length 获取字符串的长度。如:var len = strObj.length
toLowerCase() 将字符串中的字母转成全小写。如:strObj.toLowerCase()
toUpperCase() 将字符串中的字母转成全大写。如:strObj.toUpperCase()
charAt(index) 返回指定下标位置的一个字符。如果没有找到,则返回空字符串
substr() 在原始字符串,返回一个子字符串
substring() 在原始字符串,返回一个子字符串
split() 将一个字符串转成数组
charCodeAt( ) 返回字符串中的第n 个字符的代码
concat( ) 连接字符串
fromCharCode( ) 从字符编码创建—个字符串
indexOf( ) 返回一个子字符串在原始字符串中的索引值(查找顺序从左往右查找)。如果没
有找到,则返回-1
lastIndexOf( ) 从后向前检索一个字符串
localeCompare( ) 用本地特定的顺序来比较两个字符串
match( ) 找到一个或多个正则表达式的匹配
replace( ) 替换一个与正则表达式匹配的子串
search( ) 检索与正则表达式相匹配的子串
slice( ) 抽取一个子串
toLocaleLowerCase( ) 把字符串转换小写
toLocaleUpperCase( ) 将字符串转换成大写
toLowerCase( ) 将字符串转换成小写
toString( ) 返回字符串
toUpperCase( ) 将字符串转换成大写
valueOf( )
深拷贝浅拷贝
- 浅拷贝就是通过直接赋值的方法就可以完成,如果是复杂数据类型直接赋值的赋值的地址的指针,如果改变地址里面的内容两个复杂数据里都会改变,所以如果不希望出现这种问题就要用到深拷贝
- 深拷贝的话可以使用JSON.parse( JSON.stringify() )序列化和反序列来实现,也可以通过递归的方式手写深拷贝,遍历要拷贝的数据,在里面做判断根据不同复杂数据,进行处理递归处理,如果没有就浅拷贝,也可以使用lodash函数库来完成数据的深拷贝
解决异步问题的方法
- 可以使用promise函数,回调函数,发布订阅者,es6新增的解决异步编程的方法Generator,还可以使用await/async搭配promise函数使用解决异步编程问题
promise函数
- Javascript执行环境是单线程的,也就是说JS环境中负责解释和执行的线程只有一个,一次只能完成一项任务,这个任务执行完后才能执行下一个,因此Javascript中存在大量的异步操作和回调函数。 Promise函数是异步编程的一个解决方案,相对传统的解决方案,他更合理和强大。 Promise的本意是“承诺”、“许诺”的意思。 承诺在未来会执行某个操作的函数,就是Promise函数。
- Promise有三种状态,分别是:**Pending **(进行中), ** Resolved (已完成), Rejected ** (已失败)。Promise从Pending状态开始,如果成功就转到成功态,并执行resolve回调函数;如果失败就转到失败状态并执行reject回调函数。
- Promis函数有resolve和reject两个参数方法,如果是resolve就进.then并且可以一直.then执行下去,如果失败的话就是reject就进.catch
- Promis函数的方法有,.all .race .allsettled .finally .any
闭包
- 闭包的几个特性:函数嵌套函数时发生,一个函数可以访问另一个函数内部的变量,参数和变量不回被垃圾回收机制回收
- 闭包的好处,可以防止命名冲突,可以提升作用域链的范围,在内存中维持一个变量可以做缓存
- 闭包的坏处,会造成内存泄露,解决方法是使用完一个变量后我们手动赋值为null将变量清空
原型链
- 查找机制是先查找自身的原型对象(prototype),如果没有就通过隐式原型(proto)查找上一级原型对象,查到最顶级的话就是object的原型对象,如果还没有,就是null
- .call() .apply() .bind()可以改变this指向
es6新增的语法
- let const var
- 箭头函数没有this,不能new
- Set 和 Map 主要的应用场景在于 数据重组 和 数据储存。
- Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结构
call apply bind 作用和区别
- 都可以改变this指向,第一个参数都是this要指向的内容,apply是数组的形式,apply和call都是立即执行,bind不是
数组去重的方法
- es6新增的set方法 includes()如果判断不包含的情况,然后用新的数组再添加,indexof也可以判断,filter也可以