前端面试每日3+2(第4天)
当你发现自己的才华撑不起你的野心时,就请安静下来学习吧!
鲁迅说过:
答案仅供参考...
# 1、对web的标准以及w3c的理解和认识?
解析:
答案:
WEB标准:
- 为什么:浏览器开发商和web程序员在开发新应用程序时遵守指定的标准有利于web更好的发展。
- 作用:开发人员按照web标准制作网页,更简单;使用web标准,能够确保所有浏览器正确显示您的网站;遵循web标准更有力于搜索引擎访问和收录,更有利于转换格式,有利于访问程序代码
- 是什么:单来说可以分为结构,表现和行为。三者的分离!
- 结构主要是html标签组成的
- 表现主要是css样式表
- 行为有JavaScript控制 w3c对web标准提出了规范的要求,就是在实际编程中的一些规范:
- 对结构的要求 (标签规范化:更有利于seo等)
- 标签字母要小写
- 标签要闭合
- 标签不能随意嵌套
- 对css和js来说
- 尽量使用外链css样式表和js脚本。结构、表现、行为三层分离。同时提高页面渲染速度。提高用户的体验。
- 少使用行间样式
- 标签id和class等属性名要做到规范见文知义
- 标签越少,加载越快,用户体验越好;代码易于维护
# 2、Iframe的作用?优缺点?
解析:
作用:表示嵌套的browsing content。它能够将另一个html页面嵌入到当前页面中。 优点:便于修改,模块分离。一些信息管理系统会用到。 缺点:不推荐使用;
- iframe的创建比一般的dom创建速度满了1-2和数量级;
- 2.iframe会阻塞页面的加载。在safari和chrome中可以通过js动态设置irrame的src属性来避免阻塞。
# 3、如何理解css中的渐进增强,优雅降级?两者的区别是什么?
解析:
css3出现后的一个概念,由于低版本浏览器不支持css3,css3效果又太优秀,所以要在高版本浏览器使用css3,低版本保证基本功能就行。
渐进增强和优雅降级概念差不多,只是侧重点不同。
优雅降级侧重高版本浏览器的css3优秀的效果,如果低版本不支持的话往下兼容;
渐进增强更关注功能本身,从低版本浏览器兼容开始,高版本就增强功能,也就是渐进增强。
# 4、函数的柯里化和反柯理化是什么?作用是什么?有哪些应用场景?
解析:
函数柯里化(currying):将接受多个参数的函数变成接受单一参数(最初函数的第一个参数)的函数,返回接受其余参数而且返回结构的新函数的技术。 参考 (opens new window)
为什么?
- 参数复用
// 正常正则验证字符串 reg.test(txt)
// 函数封装后
function check(reg, txt) {
return reg.test(txt)
}
check(/\d+/g, 'test') //false
check(/[a-z]+/g, 'test') //true
// Currying后
function curryingCheck(reg) {
return function(txt) {
return reg.test(txt)
}
}
var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)
hasNumber('test1') // true
hasNumber('testtest') // false
hasLetter('21212') // false
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
上面示例是一个正则校验,正直接调用check函数就行,但是很多地方会用到是否要校验数字,可以进行封装一次,方便复用。
- 提前确认
// 法一
var on = function(element, event, handler) {
if (document.addEventListener) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
} else {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
}
}
// 法二
var on = (function() {
if (document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
};
}
})();
//换一种写法可能比较好理解一点,上面就是把isSupport这个参数给先确定下来了
var on = function(isSupport, element, event, handler) {
isSupport = isSupport || document.addEventListener;
if (isSupport) {
return element.addEventListener(event, handler, false);
} else {
return element.attachEvent('on' + event, handler);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
自执行返回一个新的函数,提前确定了要走哪个函数。 3. 延时运行
Function.prototype.bind = function (context) {
var _this = this
var args = Array.prototype.slice.call(arguments, 1)
return function() {
return _this.apply(context, args)
}
}
2
3
4
5
6
7
8
bind实际上就是currying。
柯里化通用封装:
function add(a,b,c,d){
return a + b + c + d
}
function currying(fn,args=[]){
let len = fn.length //获取函数的参数长度
return (..._)=>{
args.push(..._)
if(args.length<len){
return currying(fn,args);
}
return fn(...args);
};
}
const addFn = currying(add)(1,2,3)(4)
2
3
4
5
6
7
8
9
10
11
12
13
14
柯里化的一些问题(性能问题):
- 存取arguments对象通常要比存取命名参数要慢一点( es6拓展字符串)
- 一些老版本的浏览器在arguments.length的实现上是相当慢的(原文章采用的es5,es6采取拓展字符串是否还有性能问题呢?)
- 使用fn.apply( … ) 和 fn.call( … )通常比直接调用fn( … ) 稍微慢点
- 创建大量嵌套作用域和闭包函数会带来花销,无论是在内存还是速度上
# 5、场景题:电商网站A和电影票网站B合作,A的用户,可以通过A网站下单独购买电影票,之后跳转到B(不需要登录)去选座位。如果A、B网站同域名。比如a.domain.com , b.domain.com 能不能共享cookie?如果不同域名如何处理?
解析:
方案一 :如果是相同一级域名的话,可以将cookie设置在一级域名下面,那么所有一级域名下的子域名都可以共享cookie 缺点: 1. 首先是有了一级域名的限制,2.所有服务端生成和解析cookie的规则要保持一致
方案二: 如果一级域不同的话,需要一个user系统,只有在该系统可以进行user信息输入和校验,比如密码和用户名; 其他系统需要重定向到该user系统,user授权完毕之后,user系统生成令牌,携带该令牌并且返回其他系统,其他系统拿着该令牌到服务器端去用户系统同校验,拿到用户的相关信息,
缺点: 多个系统都需要共享一个用户登录页面,但是像天猫和淘宝这样的就不会共享登录页面,因为他们有各自的品牌,那么这个问题又变成了前端不通过跳转去拿到另一个系统的登录状态,这就变成了跨域请求的问题,跨域请求推荐使用jsonp,1是没有兼容性问题,2服务端可以直接跨域写入将用户信息写入cookie