1、数据双向绑定
http://jixianqianduan.com/frontend-javascript/2015/11/29/js-data-two-ways-binding.html
实现方式:
(1)发布-订阅模式(backbone.js)
http://www.html-js.com/article/Study-of-twoway-data-binding-JavaScript-talk-about-JavaScript-every-day
(2)脏值检查(angular 1.0)
最简单就是使用 setInterval()
定时轮询检测数据变动,Google 是在指定的事件发生时进行检测,如DOM事件,XHR响应事件,Timer事件
(3)数据劫持(+发布-订阅模式)(Vue.js)
Object.defineProperty() 对数据对象做get和set的监听
https://segmentfault.com/a/1190000006599500
2、https的过程?https将什么加密了?
http://blog.csdn.net/wangjun5159/article/details/51510594
- 客户端发送请求到服务器
- 服务器返回证书和公开密钥,公开密钥作为证书的一部分而存在
- 客户端验证证书和公开密钥的有效性,如果有效,则生成共享密钥并使用公开密钥加密发送到服务器
- 服务器使用私有密钥解密数据,并使用收到的共享密钥加密数据,发送到客户端
- 客户端使用共享密钥解密数据
- SSL加密建立
https 加密了共享密钥和数据
对性能的影响:
- 加密解密消耗了计算机的CPU资源
- 连接过程中客户端与服务器的通信次数比三次握手多,建立连接的时间花销较大
3、实现 remove
删除 object 的属性
// 如果键名不是字符串,则用一个变量保存键名
Object.prototype.remove = function (attr) {
delete this[attr];
}
4、实现 map
Array.prototype.myMap = function (callback, context) {
context = context || window;
var newArray = [];
if (typeof callback === 'function') {
for (i = 0; i < this.length; i++) {
var val = callback.call(context, this[i], i, this);
newArray[i] = val;
}
}
return newArray;
}
5、实现 compose
// 自左到右
var flow = function (...funcs) {
var length = funcs.length;
var index = length;
while (index--) {
if (typeopf funcs[index] !== 'function') {
throw new TypeError('Expected a function');
}
}
return function (...args) {
var index = 0;
var result = length ? funcs[index].apply(this, args) : args[0];
while (++index < length) {
result = func[index].call(this, result);
}
return result;
}
}
// 自右到左
var flowRight = function (...funcs) {
return flow(funcs.reverse());
}
6、浏览器缓存
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
7、移动端点击事件的300ms延时
http://blog.csdn.net/qq_34986769/article/details/62046696
- 禁用缩放
- 更改视口宽度
- 使用指针事件(IE10+):touch-action(非标准css)
- FastClick
点击穿透(使用touchstart代替click时会出现的情况):
假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件。
这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转。
8、HTTP状态码
http://www.runoob.com/http/http-status-codes.html
- 1** :信息,服务器收到请求,需要请求者继续执行操作
- 2** :成功,操作被成功接收并处理
- 3** :重定向,需要进一步的操作以完成请求
- 4** :客户端错误,请求包含语法错误或无法完成请求
- 5** :服务器错误,服务器在处理请求的过程中发生了错误
200:请求成功
301:永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302:临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
304:未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
307:临时重定向。与302类似。使用GET请求重定向
400:客户端请求的语法错误,服务器无法理解
401:请求要求用户的身份认证
403:服务器理解请求客户端的请求,但是拒绝执行此请求
404:服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
410:客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
500:服务器内部错误,无法完成请求
501:服务器不支持请求的功能,无法完成请求
9、原型链
对象的原型指向原型对象,原型对象的原型又指向其父类的原型...
obj.__proto__ = Object.prototype
10、babel配置, webpack配置,gulp配置
http://www.ruanyifeng.com/blog/2016/01/babel.html
webpack配置:
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
devtool: '#eval-source-map' // 包含dataURL
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map' // 只在末尾加上sourcemap文件的地址,需要请求
module.exports.plugins = [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
})
]
}
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
}
// 导入模块
var gulp = require('gulp');
var cssmin = require('gulp-cssmin');
var uglify = require('gulp-uglify');
var htmlmin = require('gulp-htmlmin');
var rename = require('gulp-rename'); // 改名
// 配置任务
gulp.task('uglify:css', function() {
gulp.src('css/*.css')
.pipe(cssmin()) // 压缩
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('build/css')) // 输出
});
gulp.task('uglify:js', function() {
gulp.src('js/*.js')
.pipe(uglify()) // 压缩
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('build/js')) // 输出
});
gulp.task('uglify:html', function() {
gulp.src('*.html')
.pipe(htmlmin({ // 压缩
collapseWhitespace: true,
removeComments: true
}))
.pipe(gulp.dest('build')) // 输出
});
gulp.watch('*.*', ['uglify:css', 'uglify:js', 'uglify:html']);
gulp.task('default', ['uglify:css', 'uglify:js', 'uglify:html']);
11、同源策略,跨域方式,手动实现jsonp
同源策略:
对于绝对的URIs,源就是{协议,主机,端口}定义的。只有这些值完全一样才认为两个资源是同源的。
同源策略可以保护用户信息,防止用户在A网站的信息被B网站获取到
cookie只有同源的网站可以访问到,可设置document.domain设置同源获取cookie,localstorage和IndexDB不可以通过这种方式获取
cookie 可设置所属域名为一级域名,其二级域名,三级域名等就可以直接获取
iframe和window.open可以通过片段识别符
(即url的#后面的内容)修改和获取
window.postMessage可以跨文档通信
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
跨域方法:
jsonp
-
document.domain设置同源
使用条件:
- 有其他页面 window 对象的引用。
- 二级域名相同。
- 协议相同。
- 端口相同。
-
window.name
window.postMessage(HTML5)
websocket(里面发出的请求头包含了Origin,指定了请求源)
-
CORS(允许任何类型的转换)
IE10+
简单请求和非简单请求,跟正常的ajax调用差不多,关键是服务器实现CORS接口
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
手动实现jsonp:
function addScriptTag (src) {
var scriptTag = document.createElement('script');
scriptTag.setAttribute('type', 'text/javascript');
scriptTag.src = src;
document.body.appendChild(scriptTag);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public Ip address is: ' + data.ip);
}
服务器返回的信息
foo({
'ip': '8.8.8.8'
});
12、手动实现ajax
http://www.jb51.net/article/104873.htm
function ajax ({url, type = 'GET', data = {}, success, error}) {
type = type.toUpperCase();
data = formatData(data);
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
var status = xhr.status;
if (status >= 200 && status < 300) {
var response = '';
var type = xhr.getResponseHeader('Content-type');
if (type.indexOf('xml') !== -1 && xhr.responseXML) {
response = xhr.responseXML;
} else if (type == 'application/json') {
response = JSON.parse(xhr.responseText);
} else {
response = xhr.responseText;
}
success && success(response);
} else {
error && error(response);
}
}
}
if (type === 'GET') {
xhr.open(type, url + '?' + data, true);
xhr.send();
} else {
xhr.open(type, url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhr.send(data);
}
function formatData (data) {
var arr = [];
for (var name in data) {
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
}
// 加上一个随机数,防止缓存
arr.push('v=' + random());
return arr.join('&');
}
function random () {
return Math.floor(Math.random() * 10000 + 500);
}
}
13、渐进增强和优雅降级
渐进增强:一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验
优雅降级:一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用css3的特性构建了一个应用,然后逐步针对各大浏览器进行hack使其能在低版本浏览器上正常浏览。
http://www.jianshu.com/p/d313f1108862
14、HTTP长连接,keep-alive
Connection: keep-alive
keep-alive: 20ms
保持TCP的长连接不断开,20ms 后断开连接,TCP的keep-alive是检查当前TCP连接是否还活着,两者概念不一样,使用Content-Length(静态)或Transfer-Encoding(动态,chunk模式)判断消息内容的大小
http://www.cnblogs.com/skynet/archive/2010/12/11/1903347.html
15、从输入url到看到页面发生了什么
http://www.cnblogs.com/xianyulaodi/p/6547807.html
- 输入地址
- 浏览器查找域名的IP地址
- 浏览器向web服务器发送一个HTTP请求
- 服务器的永久重定向响应
- 浏览器跟踪重定向地址
- 服务器处理请求
- 服务器返回一个HTTP响应
- 浏览器显示HTML
- 浏览器发送请求获取嵌在HTML中的资源(如图片,音频,视频,JS,CSS等)
16、前端性能优化
https://www.cnblogs.com/liulilin/p/7245125.html
17、深拷贝
http://blog.csdn.net/sysuzhyupeng/article/details/70340598
18、前端安全
http://blog.csdn.net/fengyinchao/article/details/52303118
http://www.cnblogs.com/vajoy/p/4176908.html
19、类数组
具有length属性,其他属性为非负整数,不具备数组所具有的方法
类数组:arguments,以及DOM操作返回的结果
20、for...in..
- 循环计数器是字符串,不是数字
- 会遍历原型上的方法和属性,不适合遍历数组
21、forEach
forEach 无法使用return终止
22、HTML5 新特性
http://blog.csdn.net/gane_cheng/article/details/52819118
23、IE盒子和W3C盒子
IE5.5以下:width = content + padding + border
W3C: width = content
避免IE盒子的方法:头部加上 <!DOCTYPE html>
24、实现斐波那契序列
// 递归,时间复杂度O(2^n),空间复杂度O(n)
function fib (n) {
if (n == 1 || n == 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
// 非递归,时间复杂度O(n),空间复杂度O(n)
function fib (n) {
var ret = [1, 1];
if (n == 1 || n == 2) {
return 1;
}
for (var i = 2; i < n; i++) {
ret[i] = ret[i - 1] + ret[i - 2];
}
return ret[n - 1];
}
// 非递归,时间复杂度O(n),空间复杂度O(1)
function fib (n) {
var res, a, b;
a = b = 1;
if (n == 1 || n == 2) {
return 1;
}
for (var i = 3; i <= n; i++) {
res = a + b;
a = b;
b = res;
}
return res;
}
25、盒子模型的折叠问题
http://blog.csdn.net/zerlinda_c/article/details/50054639
margin塌陷:http://www.cnblogs.com/hugejinfan/p/5901320.html
水平方向不会坍塌
26、块级元素和行级元素
http://www.cnblogs.com/asqq/archive/2012/10/04/3194956.html
27、Less特性
http://blog.csdn.net/u014695532/article/details/50957356
28、git 命令
http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
30、面经回答
http://blog.csdn.net/bossmango/article/details/77369805
https://segmentfault.com/a/1190000008644536
31、行内元素设置行高
display或者float
32、requireJS 解决循环依赖
http://www.cnblogs.com/terrylin/p/3347073.html
33、实现垂直居中
http://blog.csdn.net/wolinxuebin/article/details/7615098
- 行内文字:line-height
- display:table-cell;vertical-align:middle;
- position和margin(负数)
- position和stretch
- 设置相同padding-top和padding-bottom
- display:flex;aling-items:center;
34、伪类和伪元素
http://www.cnblogs.com/ihardcoder/p/5294927.html
35、AMD 和 CMD的区别
http://blog.csdn.net/jackwen110200/article/details/52105493
36、event loop
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
37、DOCTYPE
<!DOCTYPE> 声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令
38、强缓存和协商缓存
http://caibaojian.com/browser-cache.html
39、https与http
https比http长3倍的时间
优化:
- CDN加速,拉进节点
- 服务器硬件加速,释放CPU
- 远程解密,使用CPU负载较低的服务器