CSS 四列产业布局
CSS 盒数学模型
国际标准商业模式/IE数学模型的差别
CSS怎样增设三种数学模型
示例:依照盒数学模型说明边距重合
BFC(边距重合软件系统)
基本原理:块级序列化语句
渲染准则:
BFC原素的横向路径的边距会出现重合BFC地区不能与自由浮动原素的Box重合(可用作去除自由浮动)BFC是三个分立的罐子,外边的原素不能负面影响里头的原素,里头的原素也不能负面影响外边的原素排序BFC度时,自由浮动原素也会参予排序建立 BFC:
float值不为noneposition值不为static/relativeoverflow值不为visible(等同于auto/hidden)display值为table-cell示例:BFC横向路径重合问题(建立包裹div,增设overflow特性为hidden)
1
3
{
margin: 0;
padding: 0;
}
#margin {
background: pink;
overflow: hidden;
}
#margin > p {
background: red;
margin: 5px auto 25px;
}{
margin: 0;
padding: 0;
}
#layout {
background: red;
}
#layout .left {
background: pink;
width: 100px;
height: 100px;
float: left;
}
#layout .right {
background: #ccc;
height: 110px;
overflow: auto;
}{
margin: 0;
padding: 0;
}
#float {
background: red;
// overflow: auto;
float: left;
}
#float .float {
float: left;
font-size: 30px;
}原型链
建立对象的几种方法
原型链概念
instanceof 的原理
new 运算符
// 实现方法 _new,模拟 new 的作用
function _new(f) {
// 返回三个function
return function() {
var obj = {“proto”: f.prototype};
f.apply(obj, arguments);
return obj;
}
}
// 测试
function Person(name, age) {
this.name = name;
this.age = age;
}
var pp = _new(Person)(“Jialin”, 25);
pp instanceof Person; // true;// 使用 Object.create 模拟 new 方法
var _new2 = function(func) {
var obj = Object.create(func.prototype);
var k = func.call(obj);
if(typeof k === object) {
return k;
} else {
return obj;
}
}面向对象
借助构造函数实现继承(部分继承)
借助原型链实现继承
function Parent() { this.name = parent; this.arr = [1, 2, 3];}function Child() { this.type = child;}Child.prototype = new Parent();var c1 = new Child();var c2 = new Child();console.log(c1.arr); // [1, 2, 3]c1.arr.push(4); console.log(c2.arr); // [1, 2, 3, 4]
c1.proto === c2.proto; // true组合方式
function Parent() { this.name = parent; this.arr = [1, 2, 3];}function Child() { Parent.call(this); this.type = child;}Child.prototype = new Parent();
var cc = new Child();
cc.constructor; // Parent(){…}function Parent() { this.name = parent; this.arr = [1, 2, 3];}function Child() { Parent.call(this); this.type = child;}Child.prototype = Parent.prototype;
var cc = new Child();
cc.constructor; // Parent(){…}原型式继承
寄生式继承
DOM事件
DOM事件类
DOM事件捕获/冒泡过程
Event 对象的常见应用
自定义事件(无需使用回调)
类型转换
7 种数据类型
显示类型转换
对象,先调用该对象自身的 valueOf 方法,
var obj = {a:1};
console.log(Number(obj));
其中,
obj.valueOf()返回{a: 1}, {a: 1}的toString()返回[object Object]复合类型,先调用该对象自身的 toString 方法,
若返回原始类型的值,则执行String方法转换;若返回符合类型的值,调用自身的valueOf方法,若返回原始类型的值,使用String方法转换若仍返回复合类型的值,则报错失败
复制代码Boolean 函数隐式类型转换
常见题目
[] + [] ==> [] + {} ==>
{} + [] ==> 0{} + {} ==> “[object Object][object Object]”
true + true ==>
1 + {a: 1} ==>设计商业模式
通信类
同源政策及其限制
前后端怎样通信
怎样建立 Ajax
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject(Microsoft.XMLHTTP);
var data = opt.data;
var url = opt.url;
var type = opt.type.toUpperCase();
var dataArr = [];
for(var k in data) {
dataArr.push(k + = + data[k]);
}
if(type === GET) {
url = url + ? + dataArr.join(&);
xhr.open(type, url.replace(/?$/g, ), true);
xhr.send();
}
if(type === POST) {
// 第三个参数:预设为true,表示异步发送
xhr.open(type, url, true);
xhr.setRequestHeader(Content-type, application/x-www-form-urlencoded);
xhr.send(dataArr.join(&));
}
xhr.onload = function(){
if(xhr.status === 200 || xhr.status === 304) {
var res;
if(opt.success && opt.success instanceof Function) {
res = xhr.responseText;
if(typeof res === string) {
res = JSON.parse(res);
opt.success.call(xhr, res)
}
}
} else {
if(opt.error && opt.error instanceof Function) {
opt.error.call(xhr, res);
}
}
}// Promise封装
var getJSON = function(url) {
var promise = new Promise((resolve, reject) => {
var client = new XMLHttpRequest();
client.open(GET, url);
client.onreadystatechange = handler;
client.responseType = json;
client.setRequestHeader(Accept, application/json);
client.send();
function handler() {
if(this.readyState !== 4) {
return;
}
if(this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
});
return promise;
}跨域通信的几种方式
util.jsonp = function(url, onsuccess, onerror, charset) {
var callbackName = util.getName(name);
window[callbackName] = function() {
if(onsuccess && util.isFunction(onsuccess)) {
onsuccess(arguments[0]);
}
}
var script = util.createScript(url + &callback= + callbackName, charset);
script.onload = script.onreadystatechange = function() {
if(!script.readyState || /loaded|complete/.test(script.readyState)) {
script.onload = script.onreadystatechange = null;
if(script.parentNode) {
script.parentNode.removeChild(script);
}
window[callbackName] = null;
}
};
script.onerror = function() {
if(onerror && util.isFunction(onerror)) {
onerror();
}
}
}//动态建立 script 标签,并请求
function addScriptTag(src){
var script = document.createElement(script);
script.setAttribute(type, text/javascript);
script.src = src;
document.body.appendChild(script);
};
// 在 onload 后,跨域请求
window.onload = function(){
addScriptTag(http://127.0.0.1:8080/jsonp?callback=test);};
//回调函数,必须为全局,不然会报错
function test(data){
alert(data.name);
};server.on(request,function(req, res){
var urlPath = url.parse(req.url).pathname;
var qs = querystring.parse(req.url.split(?)[1]);
if(urlPath === /jsonp && qs.callback){
res.writeHead(200,{Content-Type:application/json;charset=utf-8});
var data = {
“name”: “Monkey”
};
data = JSON.stringify(data);
var callback = qs.callback+(+data+);;
res.end(callback);
} else {
res.writeHead(200, {Content-Type:text/html;charset=utf-8});
res.end(Hell World\n);
}
});// 当前页面A通过iframe嵌入了跨域页面B
// A中:
var B = document.getElementsByTagName(iframe);
B.src = B.src + # + data;
// B中
window.onhashchange = function() {
var data = window.location.hash;
}// 窗口A(http://A.com)向窗口B(http://B.com
)发送消息
Bwindow.postMessage(data, http://B.com);
// 在B窗口中
window.addEventListener(message, function(evet) {
console.log(event.origin); //http://A.comconsole.log(event.source); // Bwindow
console.log(event.data); // data
}, false);var ws = new WebSocket(wss://echo.websocket.org
);
ws.onopen = function(evt) {
console.log(Connection open…);
ws.send(Hello WebSockets);
}
ws.onmessage = function(evt) {
console.log(Received Message: , evt.data);
ws.close();
}
ws.onclose = function(evt) {
console.log(Connection closed.);
}CORS浏览器会拦截ajax请求,如果被认为是跨域,则会加origin字段服务器端会在响应中加入Access-Control-Allow-Origin字段CORS请求预设不发送Cookie和HTTP认证信息,如需要发送Cookie,可使用// 客户端var xhr = new XMLHttpRequest();xhr.withCredentials = true;
// 服务器端Access-Control-Allow-Credentials: true补充:fetch API
// url必须,options可选fetch(/some/url, { method: get,}).then(function(response) {
}).catch(function(err){
});安全类
举例:通过客户端脚本(JS)在三个论坛发帖中发布一段恶意的JS代码就是脚本注入,如果这个代码内容有请求外部服务器,那么就叫做XSS!
防护:
CSRF 跨站请求伪造
防护:token防御的整体思路是:
HTTP协议类
HTTP协议的主要特点
HTTP报文的组成部分
HTTP方法
POST和GET的差别
HTTP状态码
请求1 – 响应1 – 请求2 – 响应2 – 请求3 – 响应3
// 管线化,请求打包发送,依次进行响应(单独),并保持顺序
请求1 – 请求2 – 请求3 – 响应1 – 响应2 – 响应3https 的介绍
HTTPS 介绍
HTTPS = HTTP + 加密 + 认证 + 完整性保护
1)HTTPS使用SSL,先和SSL通信,再由SSL和TCP通信
补充:
对称密钥加密:加密和解密用同三个密钥的方式(共享)
非对称密钥加密:
2)HTTPS采用混合加密机制
3)证明公开密钥的正确性 –> 使用由数字证书认证机构颁发的公开密钥证书
4)HTTPS还可以使用客户端证书
HTTP 2.0 与 HTTP1.1 的差别
3 次挥手 && 4 此握手
图形机制
DTD 文件格式类型定义
DOCTYPE
常见的 DOCTYPE:
HTML 5
<!DOCTYPE html>HTML 4.01 Strict 该DTD包涵所有HTML元素和特性,但不包括展示型的和弃用的原素(如:font)
HTML 4.01 Transitional 该DTD包涵所有HTML原素和特性,包括展示型和弃用的原素
定义:DOM结构中的各个原素都有自己的盒子数学模型,这些都需要浏览器依照各种样式排序后将原素放到它该出现的位置,这个过程称为Reflow 重排
触发Reflow:
增加、删除、修改或移动DOM节点修改CSS样式修改网页的预设字体(极其不推荐!白屏闪现)定义:将页面要呈现的内容都画在页面上,这个过程称之为Repaint
触发Repint:
DOM改动CSS改动 (只要页面显示内容不同就会Repaint)怎样减少Repaint的频率?
通过DocumentFragment,将新建立的节点添加进去,向浏览器中一次性加入DocumentFragment:
JS运行机制 — 任务队列和 EventLoop
整个最基本的 Event Loop 如图所示:
task主要包涵:setTimeout、setInterval、setImmediate、I/O、UI交互事件
microtask主要包涵:Promise、process.nextTick、MutaionObserver
console.log(1)
setTimeout(() => {
console.log(2)
}, 0)
Promise.resolve().then(() => {
console.log(3)
}).then(() => {
console.log(4)
})
console.log(5)
// 1 5 3 4 2分析如下:
同步运行的代码首先输出:1、5,接着,清空microtask队列:3、4
setTimeout(fn, 0) 的含义
console.log(abc);setTimeout(() => { console.log(执行啦)},3000);setTimeout(() => { console.log(执行啦123)},0);
// abc
// 执行啦123
// 执行啦process.nextTick(callback) 的含义
setTimeout 与 Promise 混合
console.log(1)
setTimeout(() => {
console.log(2)
new Promise(resolve => {
console.log(4)
resolve()
}).then(() => {
console.log(5)
})
})
new Promise(resolve => {
console.log(7)
resolve()
}).then(() => {
console.log(8)
})
setTimeout(() => {
console.log(9)
new Promise(resolve => {
console.log(11)
resolve()
}).then(() => {
console.log(12)
})
});分析如下:
同步运行的代码首先输出:1、7
接着,清空microtask队列:8
第三个task执行:2、4
接着,清空microtask队列:5
第二个task执行:9、11
接着,清空microtask队列:12setTimeout,Promise 与 process.nextTick 的混合
console.log(1);
setTimeout(function() {
console.log(2);
process.nextTick(function() {
console.log(3);
})
new Promise(function(resolve) {
console.log(4);
resolve();
}).then(function() {
console.log(5)
})
})
process.nextTick(function() {
console.log(6);
})
new Promise(function(resolve) {
console.log(7);
resolve();
}).then(function() {
console.log(8)
})
setTimeout(function() {
console.log(9);
process.nextTick(function() {
console.log(10);
})
new Promise(function(resolve) {
console.log(11);
resolve();
}).then(function() {
console.log(12)
})
})
复制代码setTimeout 函数中,0ms 和 1ms 的效果一样(结果都是 1ms 后,传入 task 队列)
setTimeout(() => {
console.log(2)
}, 2)
setTimeout(() => {
console.log(1)
}, 1)
setTimeout(() => {
console.log(0)
}, 0)
// 1, 0, 2页面性能
强缓存(直接使用浏览器的缓存,不再请求服务器)
Expires: Thu, 21 Jan 2017 23:39:02 GMT(当然时间)Cache-Control: max-age=3600(相对时间,单位为妙)其他值:no-store(不缓存) no-cache(不缓存过期的,需revalidation)若服务器响应同时包涵Expires和Cache-Control,以Cache-Control为准协商缓存(询问服务器,浏览器的缓存是否可以使用)
If-Modified-Since:Last-Modified …Etag/If-None-Match使用了缓存后, 更改js文件内容但未更改js文件名。 重新发布后,怎么保证浏览器加载的是最新的js文件?
A:让浏览器上的强缓存事件变短
错误监控
)performance.getEntries()返回三个数组,包涵所有成功加载的资源(一种间接方法)Error事件捕获window.addEventListener(error, (e) => { console.log(捕获, e);}, true);
// true表示捕获,false表示冒泡跨域的JS运行错误可以捕获吗?错误提示是什么?应该怎么处理?
跨域错误只提示 Script Error,解决方法:script 标签增加 crossorigin 特性,增设 js 资源响应头为 Access-Control-Allow-Origin: *
笔试题
写出下面的输出
function Foo() {
getName = function(){console.log(1);}
return this; // 指window对象
}
Foo.getName = function(){console.log(2);}
Foo.prototype.getName = function(){console.log(3);}
var getName = function(){console.log(4);} // 变量定义提升
function getName(){console.log(5);} // 函数定义提升
Foo.getName(); // 2
getName(); // 4
Foo().getName();
// 1,返回window对象,调用window对象的getName方法(已经被从4修改为1)
getName(); // 1
new Foo.getName(); // 2
// 等价于
new function(){console.log(2);}();
new Foo().getName(); // 3
// 等价于
新建三个Foo函数的示例,调用该示例上(或原型上)的getName方法
new new Foo().getName();// 3
// 等价于
new foo.getName();
先执行new Foo(),得到Foo函数的示例;
由于点操作符的优先级高于new(不带参数),故先执行foo.getName(),返回3算法类
数组扁平化
Array.prototype.valueOf = function() { return this.join(,);}var flat = function(arr) { return arr + ;};
flat(arr);方法3:[Symbol.iterator] 遍历器
Array.prototype.[Symbol.iterator] = function() { let arr = [].concat(this); let getFirst = function(array) { let first = array.shift(); return first; } return { next: function() { let item = getFirst(arr); if(item) { return { value: item, done: false }; } else { return { done: true } } } }}
var flat = function(arr) {let r = [];for(let i of arr) {r.push(i);}return r.join(,);}实现如下功能
// 递归实现(深拷贝)function func(arr, str) { str = Array.isArray(str) ? str : JSON.parse(str.replace(/([a-z]+)/g, “$1”)); let obj = {}; str.forEach((val, index) => { let res = arr[index]; if(Array.isArray(val)) { Object.assign(obj, func(res, val)) } else { obj[val] = res; } }}
}