-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8.6 前端面试题目收集(yh) #203
Comments
第一期,7.27面试,问的多的: |
第二期:8.6面试 |
对于基础我觉得稍微差一点的,会问如下两个入门级的问题: 另:json对象的某个值,能不能是undefined |
什么是跨域?跨域请求资源的方法有哪些?1、什么是跨域? 缺点: |
javascript面向对象中继承实现? 面向对象的基本特征有:封闭、继承、多态。
|
如何理解闭包?1、定义和用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。 4、变量的作用域 |
闭包的概念, 我面试之前准备了题目,但是面试的时候并没有问,我怕面试的时候自己hold不住 最近新参考了别处的资料,新建了文档: |
sessionStorage 、localStorage 和 cookie 之间的区别共同点:用于浏览器端存储的缓存数据 10、Web Storage与Cookie相比存在的优势: |
null,undefined 的区别?null 表示一个对象是“没有值”的值,也就是值为“空”; undefined不是一个有效的JSON,而null是; Javascript将未赋值的变量默认值设为undefined; typeof undefined typeof null 注意: |
== 和 ===(1) "=="叫做相等运算符,"==="叫做严格运算符。 对于明确数据类型的用===更为可靠,JavaScript是一门弱类型语言,表达式运算赋值等操作都会导致类型转换。而一些隐式转换会带来一些意想不到的后果。 |
严格运算符 === 的运算规则严格运算符===的运算规则如下, |
相等运算符 "== "的运算规则相等运算符"=="在比较相同类型的数据时,与严格运算符"==="完全一样。 【注:以上内容来自网络,但是有部分可能是错的,比如null===undefined的值】 |
假如你写了这样的代码: function fix(n) {
if (n == 0) { return n + 1; }
return n + 2;
} 如果输入n为字符串值"0"的话,恭喜你,你的程序爆炸啦! 你将会得到字符串"01"作为返回值,而不是你想要的数字1。所以一句话概括:没有类型限制,类型转换的后果将是不可预料的。 那么这种不严格比较确实就一无是处吗? if (typeof str === "string" && str == false) {
console.log("The string is full of white spaces!");
} 因为 ''==false 和' '==false值都是true |
叶欣的 一个题目: 变量声明的提升 |
我们在看一段Code: var v='Hello World';
(function(){
alert(v);
})() 经过运行之后,我们发现,还是和我们预期的一样,弹出了“Hello World”。 好了,有意思的来了。接着在看一段下面的代码: var v='Hello World';
(function(){
alert(v);
var v='I love you';
})() 如果这个是一个面试题,面试官问你这个结果是多少?你怎么回答? 我们先看结果吧! 结果是 undefined?和你上面自己想的一样吗? 好吧,我就不故弄玄虚了。其实,这里面隐藏了一个陷阱-----JavaScript中的变量提升(Hoisting); |
现在我来解释下提升是什么意思?顾名思义,就是把下面的东西提到上面。在JS中,就是把定义在后面的东东(变量或函数)提升到前面中定义。 变量提升变量提升,很简单,就是把变量提升提到函数的top的地方。我么需要说明的是,变量提升 只是提升变量的声明,并不会把赋值也提升上来。 比如: 我们定义三个变量: (function(){
var a='One';
var b='Two';
var c='Three';
})() 实际上它是这样子的: (function(){
var a,b,c;
a='One';
b='Two';
c='Three';
})() 这个时候就把变量提升了呀。 好,我们现在回到第一段code里面。为什么会报错呢?其实,根据我么根据上面变量提升原件以及js的作用域(块级作用域)的分析,得知 上面代码真正变成如下: var v='Hello World';
(function(){
var v;
alert(v);
v='I love you';
})() 所以,才会提示说“undefined”。 从这里,我们也学习到,我们在写js code 的时候,我么需要把变量放在函数级作用域的顶端,比如我在上面所举的例子:var a,b,c;。以防止出现意外。 |
函数提升函数提升是把整个函数都提到前面去。 在我们写js code 的时候,我们有2中写法,一种是函数表达式,另外一种是函数声明方式。我们需要重点注意的是,只有函数声明形式才能被提升。 函数声明方式提升【成功】function myTest(){
foo();
function foo(){
console.log("我来自 foo");
}
}
myTest(); 函数表达式方式提升【失败】function myTest(){
foo();
var foo =function foo(){
console.log("我来自 foo");
}
}
myTest(); 运行结果如下: |
新看到的一个偏难的题目: ["1", "2", "3"].map(parseInt) 答案是多少?parseInt() 函数能解析一个字符串,并返回一个整数,需要两个参数 (val, radix), function parseInt(str, radix) { 因为二进制里面,没有数字3,导致出现超范围的radix赋值和不合法的进制解析,才会返回NaN 详细解析:http://blog.csdn.net/justjavac/article/details/19473199 |
这个题目,我自己的理解和测试 // 我先写这么一个自己的函数,用内置的arguments看看map调用的时候的参数情况
var parseInt2 = function(i) { console.log(arguments); return i};
[1,2,3].map(parseInt2)
// map 传了 3 个 (element, index, array),
// 对于map的第一次执行arguments为1, 0, [1,2,3]这样;
//第二次执行是2, 1, [1,2,3];
//第三次执行是3, 2, [1,2,3]
//所以,对于parseInt测试执行,发现:
parseInt(1,0)
1
parseInt(2,1)
NaN
parseInt(3,2)
NaN 所以,["1", "2", "3"].map(parseInt) ,结果是[1, NaN, NaN]也就不奇怪了 |
ES6问let/var,问箭头函数(处理this的问题) 要点: 关于箭头函数,另外的解释见: |
另外可以参考这份题目: 前端开发面试题本文由我收集总结了一些前端面试题,初学者阅后也要用心钻研其中的原理,重要知识需要系统学习、透彻学习,形成自己的知识链。万不可投机取巧,临时抱佛脚只求面试侥幸混过关是错误的!也是不可能的!不可能的!不可能的! 面试有几点需注意:(来源寒冬winter 老师,github:@wintercn) 面试题目: 根据你的等级和职位的变化,入门级到专家级,广度和深度都会有所增加。 题目类型: 理论知识、算法、项目细节、技术视野、开放性题、工作案例。 细节追问: 可以确保问到你开始不懂或面试官开始不懂为止,这样可以大大延展题目的区分度和深度,知道你的实际能力。因为这种知识关联是长时期的学习,临时抱佛脚绝对是记不住的。 回答问题再棒,面试官(可能是你面试职位的直接领导),会考虑我要不要这个人做我的同事?所以态度很重要、除了能做事,还要会做人。(感觉更像是相亲( •̣̣̣̣̣̥́௰•̣̣̣̣̣̥̀ )) 资深的前端开发能把absolute和relative弄混,这样的人不要也罢,因为团队需要的是:你这个人具有可以依靠的才能(靠谱)。 前端开发所需掌握知识点概要: HTML&CSS: 其他: |
js:防抖动与节流2017年03月15日 20:15:46 因此针对这类事件要进行防抖动或者节流处理 防抖动它的做法是限制下次函数调用之前必须等待的时间间隔。正确实现 debouncing 的方法是将若干个函数调用合成 一次,并在给定时间过去之后仅被调用一次。 // 将会包装事件的 debounce 函数
function debounce(fn, delay) {
// 维护一个 timer
let timer = null;
return function() {
// 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
}
}
// 当用户滚动时被调用的函数
function foo() {
console.log('You are scrolling!');
}
// 在 debounce 中包装我们的函数,过 2 秒触发一次
let elem = document.getElementById('container');
elem.addEventListener('scroll', debounce(foo, 2000)); 首先,我们为scroll事件绑定处理函数,这时debounce函数会立即调用, 每一次事件被触发,都会清除当前的 timer 然后重新设置超时调用。 只有当高频事件停止,最后一次事件触发的超时调用才能在delay时间后执行 function debouce(func,delay,immediate){
var timer = null;
return function(){
var context = this;
var args = arguments;
if(timer) clearTimeout(time);
if(immediate){
//根据距离上次触发操作的时间是否到达delay来决定是否要现在执行函数
var doNow = !timer;
//每一次都重新设置timer,就是要保证每一次执行的至少delay秒后才可以执行
timer = setTimeout(function(){
timer = null;
},delay);
//立即执行
if(doNow){
func.apply(context,args);
}
}else{
timer = setTimeout(function(){
func.apply(context,args);
},delay);
}
}
} 节流节流是另一种处理类似问题的解决方法。 它和防抖动最大的区别就是,节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流阀技术来实现。 主要有两种实现方法: 时间戳 var throttle = function(func,delay){
var prev = Date.now();
return function(){
var context = this;
var args = arguments;
var now = Date.now();
if(now-prev>=delay){
func.apply(context,args);
prev = Date.now();
}
}
} 当高频事件触发时,第一次应该会立即执行(给事件绑定函数与真正触发事件的间隔如果大于delay的话),而后再怎么频繁触发事件,也都是会每delay秒才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了。 定时器实现: var throttle = fucntion(func,delay){
var timer = null;
return funtion(){
var context = this;
var args = arguments;
if(!timer){
timer = setTimeout(function(){
func.apply(context,args);
timer = null;
},delay);
}
}
} 当第一次触发事件时,肯定不会立即执行函数,而是在delay秒后才执行。 可以综合使用时间戳与定时器,完成一个事件触发时立即执行,触发完毕还能执行一次的节流函数: var throttle = function(func,delay){
var timer = null;
var startTime = Date.now();
return function(){
var curTime = Date.now();
var remaining = delay-(curTime-startTime);
var context = this;
var args = arguments;
clearTimeout(timer);
if(remaining<=0){
func.apply(context,args);
startTime = Date.now();
}else{
timer = setTimeout(func,remaining);
}
}
} 需要在每个delay时间中一定会执行一次函数,因此在节流函数内部使用开始时间、当前时间与delay来计算remaining,当remaining<=0时表示该执行函数了,如果还没到时间的话就设定在remaining时间后再触发。当然在remaining这段时间中如果又一次发生事件,那么会取消当前的计时器,并重新计算一个remaining来判断当前状态。 总结防止一个事件频繁触发回调函数的方式: 防抖动:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。 节流:使得一定时间内只触发一次函数。 |
web前端开发,如何提高页面性能优化?内容方面:
|
这边有个参考的帖子; |
你有用过哪些前端性能优化的方法? |
浏览器是如何渲染页面的?渲染的流程如下: |
一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?(流程说的越详细越好)
|
前端面试题之手写事件模型及事件代理/委托 在前端面试,js是重头戏,也是体现面试者的重要方面。jq库类在前端影响深远,以至于很多入门者直接用jq代替原生js来开发项目,效率是提升了,但是往往面试官为了考察面试者的基础,几乎不可能问你jq里面的某个功能怎么用,而是问你怎么用原生js去实现某个方法或者考察你是否读个jq的源码,是否懂得里面真正的原理。 本文来整理一下关于事件的常被考察的知识点 Q:描述下js里面的事件流 A:DOM2级事件模型中规定了事件流的三个阶段:捕获阶段、目标阶段、冒泡阶段,低版本IE(IE8及以下版本)不支持捕获阶段 捕获事件流:Netscape提出的事件流,即事件由页面元素接收,逐级向下,传播到最具体的元素。 冒泡事件流:IE提出的事件流,即事件由最具体的元素接收,逐级向上,传播到页面。 关于js事件,这里有一篇非常详细的介绍,可以看下:http://www.cnblogs.com/hyaaon/p/4630128.html Q:IE和W3C不同绑定事件解绑事件的方法有什么区别,参数分别是什么,以及事件对象e有什么区别 A: 绑定事件: W3C:target.addEventListener(event, listener, useCapture); event —— 事件类型;listener —— 事件触发时执行的函数;useCapture —— 指定事件是否在捕获或冒泡阶段执行,为true时事件句柄在捕获阶段执行,为false(默认false)时,事件句柄在冒泡阶段执行。 btn.addEventListener('click',function(){
//do something...
},false) 对应的事件移除: IE:target.attachEvent(type, listener); type - 字符串,事件名称,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等。 listener —— 实现了 EventListener 接口或者是 JavaScript 中的函数。 btn.attachEvent('onclick',function(){
//do something...
}) 对应的事件移除: detachEvent(event,function); Q:事件的委托(代理 Delegated Events)的原理以及优缺点 A:委托(代理)事件是那些被绑定到父级元素的事件,但是只有当满足一定匹配条件时才会被挪。这是靠事件的冒泡机制来实现的, 优点是: (1)可以大量节省内存占用,减少事件注册,比如在table上代理所有td的click事件就非常棒 (2)可以实现当新增子对象时无需再次对其绑定事件,对于动态内容部分尤为合适 缺点是: 事件代理的应用常用应该仅限于上述需求下,如果把所有事件都用代理就可能会出现事件误判,即本不应用触发事件的被绑上了事件。 例子: var toolbar = document.querySelector(".toolbar");
toolbar.addEventListener("click", function(e) {
var button = e.target;
if(!button.classList.contains("active"))
button.classList.add("active");
else
button.classList.remove("active");
}); A:其实就是考核对事件对象e的了解程度,以及在IE下对应的属性名。单击button元素会冒泡到UL.toolbar元素,使用了e.target来定位到当前点击的button。 Q:手写原生js实现事件代理,并要求兼容浏览器 / ============ 简单的事件委托
function delegateEvent(interfaceEle, selector, type, fn) {
if(interfaceEle.addEventListener){
interfaceEle.addEventListener(type, eventfn);
}else{
interfaceEle.attachEvent("on"+type, eventfn);
}
function eventfn(e){
var e = e || window.event;
var target = e.target || e.srcElement;
if (matchSelector(target, selector)) {
if(fn) {
fn.call(target, e);
}
}
}
}
/**
* only support #id, tagName, .className
* and it's simple single, no combination
*/
function matchSelector(ele, selector) {
// if use id
if (selector.charAt(0) === "#") {
return ele.id === selector.slice(1);
}
// if use class
if (selector.charAt(0) === ".") {
return (" " + ele.className + " ").indexOf(" " + selector.slice(1) + " ") != -1;
}
// if use tagName
return ele.tagName.toLowerCase() === selector.toLowerCase();
}
//调用
var odiv = document.getElementById("oDiv");
delegateEvent(odiv,"a","click",function(){
alert("1");
})
A:大致实现思路就是创建一个类或是匿名函数,在bind和trigger函数外层作用域创建一个字典对象,用于存储注册的事件及响应函数列表,bind时,如果字典没有则创建一个,key是事件名称,value是数组,里面放着当前注册的响应函数,如果字段中有,那么就直接push到数组即可。trigger时调出来依次触发事件响应函数即可。Q:实现事件模型 Q:事件如何派发也就是事件广播(dispatchEvent) A:一般我们在元素上绑定事件后,是靠用户在这些元素上的鼠标行为来捕获或者触发事件的,或者自带的浏览器行为事件,比如click,mouseover,load等等,有些时候我们需要自定义事件或者在特定的情况下需要触发这些事件。这个时候我们可以使用IE下fireEvent方法,高级浏览器(chrome,firefox等)有dispatchEvent方法。 ie下的例子: //document上绑定自定义事件ondataavailable
document.attachEvent('ondataavailable', function (event) {
alert(event.eventType);
});
var obj=document.getElementById("obj");
//obj元素上绑定click事件
obj.attachEvent('onclick', function (event) {
alert(event.eventType);
});
//调用document对象的createEventObject方法得到一个event的对象实例。
var event = document.createEventObject();
event.eventType = 'message';
//触发document上绑定的自定义事件ondataavailable
document.fireEvent('ondataavailable', event);
//触发obj元素上绑定click事件
document.getElementById("test").onclick = function () {
obj.fireEvent('onclick', event);
}; 高级浏览器(chrome,firefox等)的例子: //document上绑定自定义事件ondataavailable
document.addEventListener('ondataavailable', function (event) {
alert(event.eventType);
}, false);
var obj = document.getElementById("obj");
//obj元素上绑定click事件
obj.addEventListener('click', function (event) {
alert(event.eventType);
}, false);
//调用document对象的 createEvent 方法得到一个event的对象实例。
var event = document.createEvent('HTMLEvents');
// initEvent接受3个参数:
// 事件类型,是否冒泡,是否阻止浏览器的默认行为
event.initEvent("ondataavailable", true, true);
event.eventType = 'message';
//触发document上绑定的自定义事件ondataavailable
document.dispatchEvent(event);
var event1 = document.createEvent('HTMLEvents');
event1.initEvent("click", true, true);
event1.eventType = 'message';
//触发obj元素上绑定click事件
document.getElementById("test").onclick = function () {
obj.dispatchEvent(event1);
}; |
老哥,为什么close了啊? |
前端面试题目收集
The text was updated successfully, but these errors were encountered: