当前位置: 首页 > Web前端 > HTML5

前端面试常考知识点---js

时间:2023-04-05 18:08:11 HTML5

1.同步异步详解~文章总结:函数setTimeout(fn,ms)是在指定时间后将要执行的任务添加到EventQueue中,并且因为是单线程任务要一个一个执行,如果之前的任务耗时太长,只能等待,导致真正的延迟时间比ms长很多。setInterval每隔指定的时间就会把注册的函数放入EventQueue中,如果之前的任务耗时太长,那么还需要等待setInterval,避免代码无间隔的跑几次,当且仅当没有这个timer的时候timer代码在实例化的时候会加入到队列中,但这可能会导致:一些interval会被跳过,多个timer的代码执行时间可能比预期的要短。setTimeout(function(){//dosomethingsetTimeout(arguments.callee,interval);},interval)实现了上面的递归调用,这样做的好处是:在前面的定时器代码执行完成之前,不会插入入队列新的计时代码,确保不会有任何遗漏的区间。此外,它保证在下一次定时器代码执行之前至少等待指定的时间间隔。讲道理,我也没搞清楚,异步宏任务(macro-task)中宏任务和微任务如何递归:包括整体代码脚本,setTimeout,setIntervalmicro-task(微任务):Promise,process.nextTick把事件放入宏任务和微任务。这是一个循环,然后执行完微任务,开始下一个循环。2.闭包理解闭包解决scope的问题还是很奇怪,这样函数中的变量就可以在函数a执行完并被外部访问返回后,闭包使得Javascript的垃圾回收机制GC不回收a占用的资源,因为a的内部函数b的执行需要依赖a中的变量,造成内存浪费。编程3.如何判断一个变量的类型?是Array类型吗?是Number类型吗?四种方法typeof对于除null之外的基本类型都能返回正确的结果。对于引用类型,除了函数,返回所有对象类型。对于null,返回对象类型。对于函数返回函数类型。instanceof在原型链上查找//假设instanceof算子左边是L,右边是RLinstanceofR//instanceof运行时,判断原型上是否存在R.prototypeL.__proto__.__proto__L链.....===R.prototype?//如果存在则返回true,否则返回false注意:instanceof会递归寻找L的原型链,即L.__proto__.__proto__.__proto__.__proto__...直到找到或找到最顶层的instanceof检测左边的__proto__原型链上,右边是否有原型prototype,constructornull和undefined都是无效对象,所以不会有constructor。这两类数据需要通过其他方法来判断。函数的构造函数不稳定,主要体现在自定义对象上。当开发者重写原型时,原来的构造函数引用会丢失,构造函数会默认为ObjecttoStringtoString(),也就是Object的原型方法。调用该方法,默认返回当前对象的[[Class]]。这是格式为[objectXxx]的内部属性,其中Xxx是对象的类型。对于Object对象,直接调用toString()会返回[objectObject]。对于其他对象,需要调用/apply返回正确的类型信息。Object.prototype.toString.call(Symbol());//[对象符号]Object.prototype.toString.call(undefined);//[对象未定义]Object.prototype.toString.call(newError());//[objectError]5.跨域CORSjsonp前四个方法需要后端配合,后端会设置回调函数名,返回数据等,documnet.domain只能将document.domain设置为自己或者更高级别的父域,和主域必须相同。例如:a.b.example.com中的一个文档的document.domain可以设置为a.b.example.com、b.example.com、example.com中的任意一个,但是不能设置为c.a.b.example.com,因为这是当前域的子域不能设置为baidu.com,因为主域已经不同了。即只有子域才能获取父域。如果想获取同级其他页面的数据,需要嵌入一个iframe,在页面http://www.example.com/a上将两个页面的document.domain设置为父域在.html中设置document.domain:http://example.com/b.html页面中也设置了document.domain,这也是必须的。虽然这个文档的域是e??xample.com,但是还是要显示出来的。document.domain的值:window.name在一个窗口(window)的生命周期中,该窗口加载的所有页面共享一个window.name,每个页面对window.name都有读写权限。window.name在窗口加载的所有页面中都是持久的,并且不会在加载新页面时重置。注意window.name的值只能是字符串形式。这个字符串的最大大小可以允许2M左右甚至更大的容量,这取决于不同的浏览器,但一般来说足够了。如www.baidu.com/a.html在不同域的www.baidu.com/data.html页面中获取了valuedata.htmla.htmlwindow.postMessage,调用postMessage方法的window对象引用该window对象接收消息,该方法第一个参数message为要发送的消息,类型只能是字符串;第二个参数targetOrigin用于限制接收消息的窗口对象的域。如果不想限制域,可以使用通配符*。需要接收消息的窗口对象可以通过监听自身的消息事件获取传入的消息,消息内容保存在事件对象的data属性中。CORS分为简单请求和非简单请求。需要后台设置:Access-Control…………6.实现一个双向数据绑定点从我的视图到输入框等模型的输入框,监听输入的内容是否输入框已更改,oninput事件//视图到模型varinput=document.getElementById("a"),title=document.getElementById("title");//title是区域的文本显示idinput.oninput=function(e){title.innerHTML=this.value;};modelviewusegetandsetofdefineProperty//modelviewObject.defineProperty(input,'val',{//这里必须定义一个新的属性名,不能使用value,否则会报错。get:function(){returnthis.value;},设置:函数(val){this.value=val;title.innerHTML=val;}});7.事件委托事件委托目标和currentTarget假设事件绑定在ul上,ul有一个子元素lie.currentTarget,它总是指向添加监听事件的对象。如果是ul,e.target指向触发事件监听的对象,就是li。注意:要将事件绑定到ul,请使用e。target.nodeName.toLowerCase==='li'判断节点是否嵌套li时,可以使用循环查找parentNodevarev=ev||window.event是兼容事件的写法vartarget=ev.target||ev。srcElement是事件源的兼容写法8.async/awaitpromise实例promise的问题promise一旦执行,promise不能中途取消的错误,外部无法捕获,只能在内部预判。如何执行promise并监控它很难有带有async关键字的函数,这使得你的函数的返回值必须是一个promise对象;await等待右边“表达式”的结果(遇到await会释放线程,但是await后面跟着那个函数的不会阻塞)