js是单线程的,内部要处理的任务分同步任务、异步任务。
成都创新互联公司主营昌吉网站建设的网络公司,主营网站建设方案,App定制开发,昌吉h5小程序设计搭建,昌吉网站营销推广欢迎昌吉等地区企业咨询
异步任务分微任务、宏任务
执行顺序:【又称 事件循环机制 】
先执行同步任务,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中。当所有同步任务执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。
微任务和宏任务有哪些:
示例:
setTimeout(function(){
console.log(1);
});
new Promise(function(resolve){
console.log(2);
resolve();
}).then(function(){
console.log(3);
}).then(function(){
console.log(4)
});
console.log(5);
// 2 5 3 4 1
遇到setTimout,异步宏任务,放入宏任务队列中。
遇到new Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出2。
Promise.then,异步微任务,将其放入微任务队列中。
遇到同步任务console.log(5);输出5;主线程中同步任务执行完。
从微任务队列中取出任务到主线程中,输出3、 4,微任务队列为空。
从宏任务队列中取出任务到主线程中,输出1,宏任务队列为空。
相同点:
不同点:
注意:
async和defer属性都仅适用于外部脚本,如果script标签没有src属性,尽管写了async、defer属性也会被忽略。
深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。
js中基本数据类型存放在栈中,引用数据类型存放在堆中。
浅拷贝是在堆中先创建一个新对象,拷贝原始对象的属性值。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址。
深拷贝是在堆中先创建一个新对象,采用递归方法实现深度克隆原理,将一个对象从内存中完整的拷贝一份出来。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,在堆中创建一个新对象再完整拷贝原对象。
区别:
实现:
双重for循环 + splice。
for(var i=0;i
filter + indexOf,返回item第一次出现的位置等于当前的index的元素 【常用】。
let newArr = arr.filter((item, index) => arr.indexOf(item) === index);
filter + Object.hasOwnProperty,利用对象的键名不可重复的特点
let obj = {}
arr.filter(item => obj.hasOwnProperty(typeof item + item) ? false : obj[typeof item])
new Set + 扩展运算符 或 Array.from 【常用】。
let newArr = [...new Set(arr)];
let newArr = Array.from(new Set(arr));
ObjA.call(ObjB, argument) --- ObjB调用ObjA中的方法,并把argument作为参数传入。
作用:改变this的指向。
区别:
调用方式不同:
参数不同:
三者第一个参数都是调用的对象。
原型:
每个构造函数都有一个prototype属性,即 显式原型属性,它指向构造函数的原型对象。
每个实例对象都有一个__proto__属性,即 隐式原型属性,它指向构造函数的原型对象。
通过显式原型属性向原型对象上设置值,通过隐式原型属性向原型对象上读取值,即 实例对象的隐式原型属性值等于其构造函数的显式原型属性值。
原型链:
每个构造函数的原型对象,默认是一个空的Object构造函数的实例对象,也都有一个__proto__属性。
实例对象和原型对象的__proto__属性连接起来的一条链,即 原型链,它的尽头是Object构造函数的原型对象的__proto__属性。
当在实例对象上读取值时,先在实例对象本身上找,当找不到,再通过__proto__属性,在其构造函数的原型对象上找,
如果还找不到,就继续沿着__proto__属性向上找,直到Object构造函数的原型对象的__proto__属性为止,此时值为null。
定义在一个函数体内,且访问了外部函数变量 的函数,即 闭包函数(闭包)。
优点:
缺点:会导致内存泄露,所以要谨慎使用。
应用场景:
回调和闭包的区别:【是否定义在函数体内】。
例:
function handle(msg, time) {
setInterval(function callback() {
console.log(msg);
}, time)
}
handle("哈哈哈哈", 5000)
对于setInterval函数来说,callback函数是回调函数。
对于handle函数来说,callback函数是闭包函数。
普通函数:普通函数中this是动态的,在调用函数时确定,一般谁调用指向谁。
调用方式 this指向。
普通函数调用 window。
构造函数调用 实例对象。
对象方法调用 该方法所属对象。
事件绑定方法 绑定事件的对象。
定时器函数 window。
立即执行函数 window。
箭头函数:
箭头函数没有自己的this、arguments。
箭头函数的this是静态的,在定义函数时确定,一般和箭头函数所在父作用域的this指向一致。
作用:
都是可以限制函数的执行频次,避免函数触发频率过高导致响应速度跟不上触发频率,因而出现延迟、假死或卡顿的现象。
都使用定时器实现。
防抖(debounce):【多次重新计时】。
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
典型的案例:输入框搜索,输入结束后n秒才进行搜索请求,n秒内又输入内容,则重新计时。
节流(throttle):【多次只一次生效】。
规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效。
典型的案例:鼠标不断点击按钮触发事件,规定在n秒内多次点击只生效一次。
原因:const指针指向的地址是不可以改变的,但地址指向的内容是可以改变的。
Promise对象:
描述:
三种状态:
九种方法:
对象上有resolve、reject、all、allSettled、race、any方法:
原型上有then、catch、finally方法:
async与await:
出现目的:
async:
await:
必须放在async定义的函数内部去使用。
作用:
异步变同步的解决,经历了四个阶段:
描述:
回调里面嵌入回调,导致层次很深,代码维护起来特别复杂,产生回调地狱问题。
示例代码:
getData(){
//获取分类列表id
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
let id=res.data[0].id
// 根据分类id获取该分类下的所有文章
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res2=>{
//获取到一篇文章的id,根据文章id找到该文章下的评论
let id=res2.data[0].id;
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/comment.php",
data:{
aid:id
},
success:res3=>{
//找到该文章下所有的评论
console.log(res3)
}
})
}
})
}
})
}
描述:
示例代码:
//在onload初始化后调用相应的函数
onLoad() {
//调用导航函数,并拿到函数的返回值
this.getNav(res=>{
let id=res.data[0].id;
//拿到分类id作为参数
this.getArticle(id,res2=>{
//拿到文章id作为参数
let id=res2.data[0].id;
this.getComment(id,res3=>{
//最终获取到第一个分类下,第一篇文章下,所有评论
console.log(res3)
})
})
});
}
methods: {
//先获取导航分类接口,将结果进行返回,到调用函数的地方获取
getNav(callback){
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
callback(res)
}
})
},
//获取文章数据,将文章列表进行返回
getArticle(id,callback){
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res=>{
callback(res)
}
})
},
//获取文章下的所有评论
getComment(id,callback){
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/comment.php",
data:{
aid:id
},
success:res=>{
callback(res)
}
})
}
}
示例代码:
//promise链式调用
this.getNav()
.then(res=>{
let id=res.data[0].id;
return this.getArticle(id);
})
.then(res=>{
let id=res.data[0].id;
return this.getComment(id)
})
.then(res=>{
console.log(res)
})
methods: {
//先获取导航分类接口,将结果进行返回,到调用函数的地方获取
getNav(callback){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
//获取文章数据,将文章列表进行返回
getArticle(id){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
//获取文章下的所有评论
getComment(id){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/comment.php",
data:{
aid:id
},
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
}
}
描述:
await / async 这两个命令是成对出现的,如果使用await没有在函数中使用async命令,那就会报错,如果直接使用async没有使用await不会报错,只是返回的函数是个promise
示例代码:
async onLoad() {
let id,res;
res=await this.getNav();
id=res.data[0].id;
res=await this.getArticle(id);
id=res.data[0].id;
res=await this.getComment(id);
console.log(res)
}
methods: {
//先获取导航分类接口,将结果进行返回,到调用函数的地方获取
getNav(callback){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
//获取文章数据,将文章列表进行返回
getArticle(id){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
//获取文章下的所有评论
getComment(id){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/comment.php",
data:{
aid:id
},
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
}
}
示例代码:
// 1
const xhr = new XMLHttpRequest();
// 2
xhr.open('POST', "http://localhost:xxx");
// 3
xhr.send("a=100&b=200");
// 4
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
// 5
if(xhr.status >= 200 && xhr.status < 300){
result.innerHTML = xhr.response;
}
}
}
作用:
一个模块就是实现某个特定功能的文件,在文件中定义的变量、函数、类都是私有的,对其他文件不可见。
为了解决引入多个js文件时,出现 命名冲突、污染作用域 等问题。
AMD:
浏览器端模块解决方案。
AMD即是“异步模块定义”。
在AMD规范中,我们使用define定义模块,使用require加载模块。
提前执行:它采用异步方式加载模块,一边加载一边执行。
依赖前置:依赖必须在定义时引入。
CMD:
浏览器端模块解决方案。
CMD即是“通用模块定义”。
在CMD规范中,我们使用define定义模块,使用require加载模块。
延迟执行:它采用异步方式加载模块,先加载完毕再按需执行。
依赖就近:依赖可以在代码的任意一行引入。
CommonJS:
服务器端模块解决方案。
在CommonJS规范中,我们使用module.exports导出模块,使用require加载模块。
立即执行:它采用同步方式加载模块,先加载后执行,执行完毕会被缓存。
依赖就近:依赖可以在代码的任意一行引入。
ESModule:
浏览器端 和 服务器端 通用的模块解决方案。
在ESModule规范中,我们使用export导出模块,使用import加载模块。
延迟执行:它采用异步方式加载模块,先加载完毕再按需执行。
依赖就近:依赖可以在代码的任意一行引入。
查:
增:
删:
改:
属性操作:
内容操作:
对象字面量(花括号)。
工厂模式(对象字面量 + return新对象)。
Object构造函数(new Object)。
构造函数模式(new function + 属性、方法都在构造函数上)。
原型模式(new function + 属性、方法都在原型上)。
组合模式(属性在构造函数上 + 方法在原型上)。
类(底层就是对 组合模式 进行了封装)。
原型链继承(子类原型指向父类实例)。
构造函数继承(借助 call)。
组合继承(原型链继承 + 构造函数继承)。
原型式继承(借助 Object.create)。
寄生式继承(原型式继承 + 添加子类方法)。
寄生组合继承(寄生式继承 + 组合继承)
extends(底层就是对 寄生组合继承 进行了封装)
在 代码执行前 产生。
产生变量提升、函数提升的原因。
定义:
执行上下文栈:
存放执行上下文对象的栈。
按照上下文对象创建的次序进栈,然后从栈顶依次执行出栈。
二十八、说一下什么是作用域、作用域链?
在代码编写时产生。
定义:
作用域链:
在某一作用域内找某一变量时,先在自身作用域内的执行上下文对象中找,找不到再去父作用域内的执行上下文对象中找,依次向上找,直到全局作用域内的执行上下文对象为止。这个过程称为作用域链。
分享标题:JS面试题:公司真实JS面试题整理
分享地址:http://www.36103.cn/qtweb/news47/29047.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联