写一份面试答卷
过年后,脑子里一团浆糊。。。转转看到了这篇文章 里边的一些问题在之前我也有遇到过,在正式的工作中也用到了一些,闲来重新面试一次。
1.JS是如何实现继承的?
什么是继承?通俗讲就是孩子继承父亲:父亲有的东西,就会交给孩子。JS实现继承,看开发环境 ,有时只要有一个父类,子类extends父类就好;或是要使用prototype一步步继承,像是javascript之原型;或是借用apply,call实现‘偷偷’继承。看过想过却没有用过。不是因为我懒,绝不是。
2.object的prototype是什么?(接上一个问题)
一个空对象。这个对象自带了一些属性和方法,而且几乎所有的JS对象的顶层都是它。最后一点很危险,所以不要为了省事或是别的原因修改这个‘空对象’。
3.JS如何实现数据以及功能的封装。(即类是如何实现的)
我现在一般使用三种方法:工厂模式,对象定义属性和方法,class。
4.如果一个标签里面包含了10000个image,如何有效地对这10000个image实现事件绑定,比如说click事件。(考察事件冒泡机制)
每个image都添加上事件,让我想到了以前写过的图片延迟加载的功能:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> img { opacity: 1; transition: opacity 0.3s; } img[data-original] { opacity: 0; } </style> </head> <body> <img data-original="./img/img1" alt="" src="../img/img1.jpg" /> <img data-original="./img/img2" alt="" src="../img/img2.jpg" /> <img data-original="./img/img3" alt="" src="../img/img3.jpg" /> <img data-original="./img/img4" alt="" src="../img/img4.jpg" /> <img data-original="./img/img5" alt="" src="../img/img5.jpg" /> <img data-original="./img/img6" alt="" src="../img/img6.jpg" /> <img data-original="./img/img7" alt="" src="../img/img7.jpg" /> <img data-original="./img/img8" alt="" src="../img/img8.jpg" /> <img data-original="./img/img9" alt="" src="../img/img9.jpg" /> <script> Array.prototype.forEach.call(document.querySelectorAll('img[data-original]'), function (img) { img.setAttribute('src', img.getAttribute('data-original')); img.onload = function () { img.removeAttribute('data-original'); }; }); </script> </body> </html>
至于说了是冒泡的问题 window.event ? window.event.cancelBubble = true : e.stopPropagation();即可
5.假设现在有对象A、B,A对象绑定了S事件,如何对B对象也绑定S事件?
A对象绑定了S事件,是引用了S事件,如果想给B对象也绑定S事件,那就让B对象引用S事件即可;而所谓的引用,就是《指向》同一堆内存地址。
引用是多对一的关系,谨慎修改。
var S = function () { alert("s") }; var A = {},B = {}; A.s = S; B.s = S; console.log(A); console.log(A.s === S); console.log(B); console.log(B.s === S);
6.如何实现跨域请求?你知道的有多少种方法?各有什么优缺点?
在我实际工作中,我并没有很多使用前端解决跨域问题的经验---大多由后台技术人员解决。当然,这并不说明我就一点都不了解这方面的问题。之前学习nodejs时,我在本地起了一个nodejs服务器(127.0.0.1),使用webstrom(http://localhost:63342)打开页面,这就形成了跨域。然后,在响应头上设置response.setHeader('Access-Control-Allow-Origin', "http://localhost:63342")。方法有
-
CORS跨域资源共享(IE8+)
-
通过jsonp跨域(只能实现GET请求)
-
通过修改document.domain来跨子域(只适用于不同子域的框架间的交互)
-
使用window.name来进行跨域
-
使用HTML5的window.postMessage方法跨域(IE8+)
方法虽多,但是都有功能和兼容限制,我只在刚开始工作的时候看过上一位FE留下的代码里有使用到document.domain,至于其他的就真真只是看看罢了。
7.当使用隐藏框架实现跨域请求时,如果框架页跟当前页不属于同个父域,是否可以实现跨域?
这个问题,至少现在不想回答。
8.如何实现私有变量?说出一种方法即可。
给它一个私有的空间,例如var a = {"a1":2},在外部访问a1就要用a.a1的方式访问;或是在对象内写个类似getter的函数var a={"a1":2,getA1:function(){return this.a1}},在外部访问a1就要用a.getA1的方式访问;或是闭包。
9.函数闭包使用得多吗?什么情况下需要使用函数闭包?
不多。近期有个小功能需要避免操作频繁一直请求,用了个类似lodash的debounce的函数,
function debounce(fn, delay) { var timer; return function () { clearTimeout(timer); timer = setTimeout(function () { fn(); }, delay) } }
debounce返回一个包含外部声明变量的函数,形成闭包。这个返回的函数和变量(timer)在同一个scope中,返回的函数可以访问到变量,可以操作变量,但是每次执行返回的函数又不会重置变量,而是直接读取变量。debounce调用时第一件事就是清除掉上一次的setTimeout(这样也就清除了上一次触发的事件),然后将本次的事件重新赋值给timer,delay就是一个时间点,超过这个时间没有别的触发,就执行fn。
10.当某个事件发生时,如果获得事件发生的对象。(ff和ie不同)var target = event.srcElement ? event.srcElement: event.target;
11.当绑定事件时,this指针指向的是?this浅看
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
status常见404(not found),403(forbidden),500(server error)