front-end SEO
Search engine Optimization,具体方法包括:
- 合理的title、description、keywords:搜索对着三项的权重逐个减小,title值强调重点即可,重要关键词出现不要超过2次,而且要靠前,不同页面title要有所不同;description把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面description有所不同;keywords列举出重要关键词即可
- 语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页
- 重要内容HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取
- 重要内容不要用js输出:爬虫不会执行js获取内容
- 少用iframe:搜索引擎不会抓取iframe中的内容
- 非装饰性图片必须加alt
- 提高网站速度:网站速度是搜索引擎排序的一个重要指标
How to do SEO optimization? - 标题与关键词,设置有吸引力切合实际的标题,标题中要包含所做的关键词
- 网站结构目录,最好不要超过三级,每级有”面包屑导航”,使网站成树状结构分布
- 页面元素,给图片标注”Alt”可以让搜索引擎更友好的收录
- 网站内容,每个月每天有规律的更新网站的内容,会使搜索引擎更加喜欢
- 内链的布置,使网站形成类似蜘蛛网的结构,不会出现单独连接的页面或链接
- 流量分析,通过统计工具(百度统计,CNZZ)分析流量来源,指导下一步的SEO
JS knowledge
- Array methods:isArray,slice,join,splice,shift(移除),unshift,push,pop,every,some,forEach,map,indexOf,lastIndexOf,concat,includes,reverse.splice返回移除的元素,reverse改变原数组
- 事件委托:利用冒泡的原理,把事件加到父级上,触发执行效果。同一类型事件只在父级元素添加一次。提高性能。
NodeJS性能优化:使用async并行执行,异步代码(NodeJS是单线程的),缓存不经常用的数据:Redis模块,redis.createClient(),检查是否存在then读取并缓存。打包JS。Session不能存放太多数据:典型的 Express页面应用,Session数据默认是保存在内存中的。当你把太多数据保存在Session的时候,会导致服务器开销显著增大。 - 跨域问题:AJAX是同源策略,浏览器在请求不同域的资源时,会受到浏览器的同源策略影响,常常请求资源不成功。同源策略:浏览器限制脚本中发起的跨站请求,要求JavaScript或cookie只能访问同源的资源。这里的同源指的是,域名,协议名,以及端口号相同。 使用JSONP解决跨域问题,json是一种数据存储的基本格式,通常见于js脚本存储数据,ajax请求数据。而jsonp是一种非正式的传输协议,该协议的一个要点是允许用户传递一个callback参数给服务端,服务端返回数据时,会将callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。Jsonp的原理是:普通资源请求都会受到跨域影响,但含有src属性的跨域资源在调用时并不会受到影响。Jsonp就是由于这种特性被发掘并实现跨域的. 如果浏览器支持HTML5,那么就可以一劳永逸地使用新的跨域策略:CORS了。CORS全称Cross-Origin Resource Sharing,是HTML5规范定义的如何跨域访问资源。只要响应头
Access-Control-Allow-Origin
为http://my.com,或者是*,本次请求就可以成功。可见,跨域能否成功,取决于对方服务器是否愿意给你设置一个正确的`Access-Control-Allow-Origin`,决定权始终在对方手中。 - AJAX技术:无需刷新页面就能够从服务器交换数据并更新部分网页的一种方法。出现使得向服务器请求额外的数据而无需卸载页面。停留在当前页面,用JS发送请求,再用JS获取数据,数据可以不断更新。最早使用的Gmail。要通过回调函数获得响应(异步的)。 request.onreadystatechange = function(){return success()}
1
2
3
4
5
6
7
8
9
10
11
12
13var xmlh;
if(window.XMLHttpRequest) {
xmlh = new XMLHttpRequest();
} else {
xmlh = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlh.open("GET",url,true);
xmlh.send();
xmlh.onreadystatechange = function() {
if(xmlh.readState == 4&&xmlh.status == 200) {//200OK,404Not found
document.getElementById("showbox").innerHTML=xmlh.resnponseText;
}
} - JS事件循环
异步IO.NodeJS单线程。
当函数执行完毕后本地变量会从stack中弹出,这只有在使用numbers string boolean 这种基本数据类型时才会发生。而对象、数组的值是存在于heap(堆)中的,stack只存放了他们对应的指针。
当函数之行结束从stack中弹出来时,只有对象的指针被弹出,而真正的值依然存在 heap 中,然后由垃圾回收器自动的清理回收。
回调函数正在等待轮到自己执行所排的队就被称为任务队列(或者事件队列、消息队列)。每当主线程完成前一个任务,回调函数就会在一个无限循环圈里被调用,因此这个圈被称为事件循环。 - 函数声明能变成立即执行函数,函数表达式不行。声明:function fun(){}。
(function(a){console.log(a); //firebug输出123,使用()运算符})(123)
;(function(){console.log('Hello World');})()
立即执行函数。 - == for [] =false,[1] = true/1,{}(object)什么都不==/===
if([]==false){console.log(1)};
if({}==false){console.log(2)};
if([]){console.log(3)}
if([1]==[1]){console.log(4)}
// 只输出1,3 - setTimeout(function() {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5);
// 2 3 5 4 1.Settimeout直接被压栈进入回调了。i==9999才resolve.
其实JS引擎在处理这段代码的时候,并不是真正的延迟0ms执行。不同的浏览器会默认有一个最小的延迟时间,低于这个时间间隔会按照默认最小的时间间隔来处理。
HTML
- 块级元素和行内元素有什么区别,举例常用的块级和行内元素,行内元素有padding/margin吗.没有margin/padding-top/bottom.行内元素设置width、height不起作用.行内元素:只占据它对应标签的边框所包含的空间.只能容纳文本或者其他内联元素.块级元素占据其父元素(容器)的整个空间,因此创建了一个“块”。通常浏览器会在块级元素前后另起一行。能容纳其他块元素或者内联元素。内联元素(input,strong,img,abbr,em,span,label),和其他元素在一行。2.float 当把行内元素设置完float:left/right后,该行内元素的display属性会被赋予block值,且拥有浮动特性。行内元素去除了之间的莫名空白。
- call,apply,bind的区别,并举例使用的场景
- 画出一个正方形,并且自适应,列出的方法越多越好
- 父级元素下面无固定宽高的块元素,实现水平垂直居中.Flex
{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
} - argument是数组吗?不是的话,怎么变成数组
不是,类数组对象,var a=[].slice.call(argments)
.
[…arguments],Array.prototype.slice.call(arguments)CSS
- CSS3.0 new feature:
- border-radius:50%.方角变成圆角.
- box-shadow:2px,20px,3px,#777.
- border-image:url(),30,30,round.
- transform:旋转,倾斜,平移,拉伸(scale)等变化,没有过渡时间。transition:有过渡动画,从一种style变成另一种style。animation专门做动画,
.div {
transition-property: width
transition-duration:
transition-timing-function:linear
transition-delay:2s
}
@keyframes myani {
from:
to:
}
.div {
animation:myani
} - 盒模型可以帮助块级元素的定位和计算面积,简单来说W3C的盒模型包括content、padding、border、margins。
the content area’s size can be explicitly defined with the width;
The padding area, bounded by the padding edge, extends the content area to include the element’s padding. is determined by the padding-top, padding-right, padding-bottom, padding-left, and shorthand padding properties.
The margin area, bounded by the margin edge, extends the border area to include an empty area used to separate the element from its neighbors.is determined by the margin-top, margin-right, margin-bottom, margin-left, and shorthand margin properties. - 自适应宽度三等分布局: display:table-cell;width:10000px.width:0px,margin:0px.
- 字体个数一般用偶数
Network
- Status code:200服务器成功返回网页,204No Content无内容,301 重定向,304 资源没有修改,直接从缓存返回资源.503服务不可用.403Forbidden(禁止)服务器拒绝请求。400Bad request.502BadGateway.500Internal-server-error.
- GET,POST,POST has not content length limit and put message in the content body,
- Cookie, localStorage.
- HTTP request, response
- 跟缓存相关的HTTP请求头中有三个字段:Cache-control、Expires(指定具体过期日期)、Last-Modified(验证资源是否过期).关于优先级,Cache-Control比Expires可以控制的多一些, 而Cache-Control会重写Expires的规则,Cache-Control是关于浏览器缓存的最重要的设置,因为它覆盖其他设置,比如 Expires 和 Last-Modified。Mainfest可以缓存一个应用,pwa中有Mainfest和Service Worker可以实现缓存.
- HTTP/HTTPs
- Http是超文本传输协议,信息是明文传输;Https是具有安全性的ssl加密传输协议.
- Http和Https使用的是完全不同的连接方式,用的端口也不一样,Http是80,Https是443.
- Http的连接很简单,是无状态的;Https协议是由SSL+Http协议构建的可进行加密传输,身份验证的网络协议,比Http协议安全。
- XSS是什么?跨站脚本攻击,这些可执行的脚本由攻击者提供,最终为用户浏览器加载,不同于大多数攻击,有存储型和反射型,防御方式,编码,过滤,解码.CSRF:跨站请求伪造
- 一个列表,假设有100000个数据,分页的原理,就是每次服务器端返回一定数目的数据。
- HTTP响应步骤:(1)客户端连接到Web服务器:一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接(2)发送HTTP请求:通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成(3)服务器接受请求并返回HTTP响应:Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成(4)释放TCP连接(5)客户端浏览器解析HTML内容
function.prototype.bind/apply/call
apply&call return the result of calling the function with the specified this & arguments。func.bind creates new function with this keyword设置成指定值,copy of func with specified this & initial value.
var module = {
x: 42,
getX: function() {
return this.x;
}
}
var retrieveX = (module.getX);//提取出来这个函数
console.log(retrieveX());//undefined
修改方法:var retrieveX = ().bind(module);//绑定执行上下文,要绑定的参数
没有return这个函数,不构成闭包。
bind()
call can accept argument lists, apply can only apply function to single array/array like objects,function.apply(null/this keyword,arr),function.call(this,name,price), which are argument lists.bind
React
- lifecycle
- reactjs中虚拟dom要这样实现的原因是什么?
- 谈谈你对reactjs的理解?为什么项目中选用reactjs?与其他框架的区别?
在React中,render执行的结果得到的并不是真正的DOM节点,结果仅仅是轻量级的JavaScript对象,我们称之为virtual DOM。虚拟DOM确保只对页面上改变的部分进行刷新。高效的diff算法O(n)和Batching处理。
MVVM 的变化检查是数据层面的,而React的检查是DOM结构层面的。算法题
- 从一个无序,不相等的数组中,选取N个数,使其和为M实现算法
- 值传递,因此引用的是自己变量,0-4(增加i作为参数)。下面这样是55555
for (var i = 0; i < 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
} - 给一个数组如:[[“a”,”b”,”c”],[“d”,”e”],…..]得到[ad,ae,bd,be,cd,ce],手写实现的方法?
Array.prototype.join(‘ ‘).直接把数组拼接。String.concat(string).
function(arr) {
let ans = [];
var help = function(arr1,arr2){
};let ans = []; for(let ele1 of arr1) { for(let ele2 of arr2) ans.push(ele1.concat(ele2)): }
help.apply(this,arr[1],arr[2]);
return ans;
} - setTimeout(,100)是否会100ms后执行,原因是?EventLoop?
同步任务直接在主线程队列中顺序执行,而异步任务会进入另一个任务队列,不会阻塞主线程。等到主线程队列空了(执行完了)的时候,就会去异步队列查询是否有可执行的异步任务了(异步任务通常进入异步队列之后还要等一些条件才能执行,如ajax请求、文件读写),如果某个异步任务可以执行了便加入主线程队列,以此循环。
setTimeout注册的函数fn会交给浏览器的定时器模块来管理,延迟时间到了就将fn加入主进程执行队列,如果队列前面还有没有执行完的代码,则又需要花一点时间等待才能执行到fn,所以实际的延迟时间会比设置的长。
在各JS环境中,Promise都是最先执行的,setTimeout(0)、setImmediate requestAnimationFrame顺序不确定。setInterval(). - new完成了什么事,用代码表达
- 正则表达式的运用,完成模板函数
- inline-block标签之间的空白块
- Bom是什么?列举你知道的Bom对象
- 是视频面试,面了一个半小时。先是问了比较基础的三列布局,问了居中处理。然后问了项目,框架。我说的react,就问了生命周期。然后问了闭包。手写一个闭包。根据这个手写的闭包开始问各种问题。他把这个你写的代码改了,问你输出。改了好几次。然后问了冒泡,捕获。又让自己写一个parseInt函数。
parseInt(str,base) {
if(typeof str !==”string”) return NaN;
if (radix == null) {
} else if(base>36||base < 2) return NaN;radix = 10;
let result = 0;
for(var i = 0; i < str.length; i++) {
}var c = str.charCodeAt(i); if(c >= 97) c-=87; else if(c >=65) c-=55; else c-=48;f (c >= radix) { if (i === 0) { return NaN; } break; } result = (result * radix) + c;
return result;
}
函数奇数次调用输出1偶数次调用输出2
var A = (function A(){
var index = 1;
function f(){
if(index % 2 == 1){
console.log(1);
}else{
console.log(2);
}
index++;
}
return f
})()
DOM事件流:事件捕获阶段、处于目标阶段、事件冒泡阶段.
浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件.与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点.从内到外输出,child-parent-body.用e.stopPropogation()停止传播.事件委托利用事件冒泡.
设置true用事件捕获,false冒泡.
提交的两种实现(input+type=submit, button+点击事件)
点击事件具体js实现及Jquery对应的api. .click(),.mouseover(),.ready().
事件流:
绑定事件:addEventListner(false,)默认是false事件冒泡,attachEvent(eventName,handler)..onclick=function(){}.React里面用camelCase
React的flex的实现原理
弹性布局。任何一个容器都可以指定为 Flex 布局。
.box{
display: flex;////inline-flex;子元素的float、clear和vertical-align属性将失效。
align-items:center;//主轴对齐方式,水平对齐
justify-content:center;//垂直居中;flex-start/flex-end/baseline
flex-direction:决定主轴方向
}
jQuery API:hide(),parent(),parents(),children(),find查找后代元素,fadeIn,fadeOut,fadeToggle,.animate({property},ms(speed),function),addClass,removeClass,.ready(),.load().
解析过程:创建DOM树,解析CSS,CSS和DOM合并成渲染树。
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建.这就称为回流(reflow).每个页面至少需要一次回流,就是在页面第一次加载的时候.
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color,则就叫称为重绘。改变字体,增加或者移除样式表,内容变化,设置CSS属性值.回流一定重汇,重汇不一定回流
在html方面问了:1、重绘和回流的区别2、视图属性3、CSS标准盒子 (box-sizing)4、清除浮动5、两列布局(右侧定宽200px,左边随屏幕自动填充宽度)6、垂直水平居中7、addEventListener()有几个参数,是什么?type,handler(function/implement EventHandler的函数)
padding+border+width/height=盒子长宽
js问了:1、typeof的类型(举例说属于什么类型),typeof null=object,typeof a=number/function/undefined/boolean
判断是否是数组
用typeof判断:typeof null/[]/{} === ‘object’.if({}) true;{}==true/false false. if([]) true
ES6:Array.isArray()
if(Object.prototype.toString.call(arr)===’[object Array]’)
同理判断是否为objectif(Object.prototype.toString.call(arr)) === ‘[object Object]’;
判断是否是对象实例,instanceof
2、function.prototype.bind/call/apply的用法及区别
CSS上下左右居中
答父元素position:relative 子元素position:absolute margin:auto 方法很多,还可以用flex, table-cell等
BOM浏览器对象模型
对象包括Window,images,layers,links,frames,areas.
1、图片预加载
window.onload = function() {
setTimeout(function() {
// XHR to request a JS and a CSS
var xhr = new XMLHttpRequest();
xhr.open(‘GET’, ‘http://domain.tld/preload.js‘);
xhr.send(‘’);
xhr = new XMLHttpRequest();
xhr.open(‘GET’, ‘http://domain.tld/preload.css‘);
xhr.send(‘’);
// preload image
new Image().src = “http://domain.tld/preload.png“;
}, 1000);
};
Function.prototype.bind = function(cxt){
var fn = this;
return function() {
fn.apply(cxt,arguments);
}
}
Function.prototype.bind2 = function (context) {
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
// 当作为构造函数时,this 指向实例,此时结果为 true,将绑定函数的 this 指向该实例,可以让实例获得来自绑定函数的值
return self.apply(this instanceof fBound ? this : context, args.concat(bindArgs));
}
fBound.prototype = this.prototype;
return fBound;
}
4、自己实现一个promise、sleep; 5、用call或者apply实现bind; 6、==与===,===类型不同直接false,函数对象检查是否指向同一对象。undefined与null===false,undefined==null true。==同一类型一样,不同类型会做类型转换。null/undefined==[]/{} false
7.requireJS,怎么解决循环依赖。a依赖b,b依赖a,调用其中之一时会提示undefined。
canvas:beginPath closePath 有什么用
closePath是关闭路径的API,如果它将当前点与起点进行连线,形成一个封闭图形。
在函数中,传参实际传的是值,所以每次都传的是i的值;值传递就能避免闭包。
this.name = b.name;
console.log(a()); //‘bbb’。使a返回b的name
(function (){
var i = 9;
funcs2;
})因为在立即执行函数里var i =9;此时i是局部变量,不会影响闭包中i的引用不会访问到立即执行函数中的i,所以就是5;去掉立即执行函数后,var i = 9;此时的i是全局变量,所以就覆盖了原来的i,所以输出为9.
Responsive Web Design - The Viewport
The viewport is the user’s visible area of a web page.
1、构造继承
2、原型继承
3、实例继承
4、拷贝继承
列出JavaScript的继承实现方式,并使用一种你喜欢的方式实现如下继承
原型链继承,children = new Parent();
为父类构造函数被执行了两次,子类的原型对象(Sub.prototype)中也有一份父类的实例属性,而且这些属性会被子类实例(sub1,sub2)的属性覆盖掉,也存在内存浪费。
Children.prototype.helloword = “”;
function Child() {
Parent.call(this,username);
//Parent.apply(this,new Array(username));
}
多个标签页通信主要是利用了localStorage的增删改事件监听
function sendMsg(text) {
window.localStorage.setItem(‘msg’,text);
}
window.addEventListener(‘storage’, function (evt) {
if(evt.key===’msg’)
console.log(evt.newValue);
});
冒泡排序
for (i = 0; i < len; i++) {
for (j = 0; j < len-i-1; j++) {
}
}
等高布局:left:top:0;bottom:0;absolute实现等高。
水平居中:
1.{
width:200px;
margin:0,auto;//左右全设置成auto,要有固定宽度值
}
2.{
width:800px;
position:absolute;
margin-left:-400px;
left:50%;
}
垂直居中:
1.高度不固定{
padding-top:==padding-bottom
}
2.加一个空标签:
#floater{
float:left;
height:50%;/相对于父元素高度的50%/
margin-bottom: -120px;/值大小为居中元素高度的一半(240px/2)/
}
#content {
clear:both;/*清除浮动*/
height: 240px;
position: relative;
}
3.垂直水平居中:.wrap{
position:absolute;
left:50%;
top:50%;
width:800px;
height:800px;
margin-left:-400px;
margin-top:-400px; //不知道宽度高度可以用transform:translate(-50%,-50%)
} parent:position:relative
垂直居中
parentElement {
display:flex;/Flex布局/
display: -webkit-flex; / Safari /
align-items:center;/指定垂直居中/
justify-content:center;
}
如何获取一个元素到浏览器边缘的距离?
offset: 获取匹配元素在当前视口的相对偏移
position: 获取匹配元素相对父元素的偏移
scrollTop: 获取匹配元素相对滚动条顶部的偏移
scrollLeft: 获取匹配元素相对滚动条左侧的偏移
$.trim()是啥,移除开头结尾的空白。然后让我现场写代码实现一个。然后问我$(document).ready() 与window.onload的区别,写代码实现一个$(document).ready()。
ready会比onload先执行,绘制完DOM树就开始执行,DOM一旦ready就开始执行绑定的handler.ready能同时编写多个.
return (text || “”).replace(/^\s+|\s+$/g, “”)
//^匹配输入的开始
http并发请求资源数
对每一个host限制个数2、4或8.Firefox 3.6.8和chrome 5.0的并发连接数都为6。
css雪碧图可以优化http请求数,减少请求数,具体如何减少请求数目。
怎样实现一个可以根据浏览器动态宽高(边长)变化的正方形?
.placeholder {
width: 100%;
height: 100vw;
}
.placeholder {
width: 100%;
padding-bottom: 100%;
height:0;
}
给一个无序列表里面的每个li元素添加事件监听器,我显然知道挖了一个坑呀,然后被我机智地绕过去了。写完之后问我,如果现在要给这个列表再添加两个子元素,这个事件监听要怎么加,然后我说,那就用事件代理吧,就是给父组件绑定事件嘛。还问了我一个简单的算法题,就是判断一个字符串中出现次数最多的那个字符。
var str = ‘我爱北京天安门,天安门上太阳升’;
var freqs = {}; // 用来记录所有的字符的出现频次
var mostFreqChar = ‘’; //用来记录最大频次的字符
for (var i = 0; i < str.length; i++) {
var char = str[i];
if (!freqs[char]) {
freqs[char] = 0;
}
freqs[char] ++;
if (mostFreqChar == ‘’ || freqs[char] > freqs[mostFreqChar]) {
mostFreqChar = char;
}
}
console.log(freqs);
console.log(mostFreqChar);
//if(undefined/null) 都不会输出
块级元素:address - 地址
blockquote - 块引用
center - 居中对齐块
dir - 目录列表
div - 常用块级,也是css layout的主要标签
dl - 定义列表
fieldset - form控制组
form - 交互表单
h1 - 大标题
h2 - 副标题
h3 - 3级标题
h4 - 4级标题
h5 - 5级标题
h6 - 6级标题
ol,ul
行内:abbr,em,strong,input,br,span,img,input
z-index
function foo () { var a = 1 function bar () { console.log(a) } return bar }
var baz = foo();
baz() // 1
for (var i = 1; i <= 5; i++) { setTimeout(function timer () { console.log(i) }, i 1000) }
访问的是i的全局变量,已经变成6了。
for (var i = 1; i <= 5; i++) { (function (j) { setTimeout(function timer () { console.log(j) }, j 1000) })(i) }
let声明的变量只在自己的代码块内有效,外部引用不到。
同一作用域不能重复声明。不存在变量提升(先使用后声明)。
console.log(a);//undefined
var a = 0;
加块级作用于就能显示0
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a6; // 10全局的i。let则返回6
for (let i = 0; i < 3; i++) {
let i = ‘abc’;
console.log(i);//abcabcabc
}
主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。绘画canvas;用于媒介回放的video和audio元素;
本地离线存储localStorage长期存储数据,浏览器关闭后数据不丢失;sessionStorage的数据在浏览器关闭后自动删除;cookie设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭.存储在本地客户端,在http请求之间传递.
自然样式标签、语义样式标签.首选自然样式标签
访问对象里面的属性的规则(原型链):
先在对象自身寻找,找不到去原型找,原型找不到去原型的原型上去找,直到找到Object.prototype为止。如果Object.prototype也没有则报错。
CSS不可继承的样式:border padding margin width height
block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
none 缺省值。象行内元素类型一样显示。
inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
list-item 象块类型元素一样显示,并添加样式列表标记。
table 此元素会作为块级表格来显示。
inherit 规定应该从父元素继承 display 属性的值。
absolute
生成绝对定位的元素,相对于值不为static的第一个父元素进行定位。
fixed (老IE不支持)
生成绝对定位的元素,相对于浏览器窗口进行定位。
relative
生成相对定位的元素,相对于其正常位置进行定位。
浮动的元素,高度会塌陷,而高度的塌陷使我们页面后面的布局不能正常显示。
style标签写在body后与body前有什么区别?
写在head标签中利于浏览器逐步渲染(resources downloading->CSSOM+DOM->RenderTree(composite)->Layout->paint)。写在body标签后由于浏览器以逐行方式对html文档进行解析,当解析到写在尾部的样式表(外联或写在style标签)会导致浏览器停止之前的渲染,等待加载且解析样式表完成之后重新渲染
SSR:server sends ready to be rendered HTML。有利于SEO,打开速度比本地渲染快。
renderToString,renderToStaticMarkup这是 React 服务器端渲染的基础
server-side rendering,nodemon,route
数组的随机排序
var arr = [1,2,3,4,5,6,7,8,9,10];
function randSort2(arr){
var mixedArray = [];
while(arr.length > 0){
var randomIndex = parseInt(Math.random()*arr.length);
mixedArray.push(arr[randomIndex]);
arr.splice(randomIndex, 1);
}
return mixedArray;
}
this总是指向函数的直接调用者;在事件中,this指向触发这个事件的对象;如果有new关键字,this指向new出来的那个对象.
闭包是指有权访问另一个函数作用域中变量和形参的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
New干了什么
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
js延迟加载的方式有哪些?
defer=”defer”和async、动态创建DOM方式(用得最多)、按需异步载入js
var js = document.createElement(“script”);
js.type = “text/javascript”;
js.src = “”;
document.getElementsByTagName(“head”).appendChild(js);
什么都不实用同步加载,在浏览器继续解析页面之前,立即读取并执行脚本
创建script,插入到DOM中,加载完毕后callBack
document.write只能重绘整个页面;element.innerHTML可以重绘页面的一部分
slice不改变原数组,splice改变原数组。
继承Dog.prototype = new Animal();
实例化:var doge = new Animal();
jQuery怎样转换JSON字符串$(“”).stringifyArray(array)
$.fn.stringifyArray = function(array) {
return JSON.stringify(array)
}
$.fn.parseArray = function(array) {
return JSON.parse(array)
}
jQuery 的队列是如何实现的?队列可以用在哪些地方?
判断是不是原生js
this === window ? ‘browser’ : ‘node’;
var a = 6;
setTimeout(function () {
alert(a);
var a = 666;
}, 1000);
a = 66; 输出undefined,变量提升,声明提升到函数开头,但是没有赋值,拆成了两句话
var a = 6;
setTimeout(function () {
alert(a);
a = 666;
}, 1000);
a = 66;//66
The tag should represent a range of text with a different semantic meaning whose typical typographic representation is italicized. This means a browser will typically still display its contents in italic type, but is,by definition, no longer required to.
jQuery 的队列是如何实现的?队列可以用在哪些地方?
jQuery .trigger(type,function params).fire所有匹配类型的事件
react-router路由系统的实现原理?
React中如何解决第三方类库的问题?
什么是“前端路由”?什么时候适合使用“前端路由”? “前端路由”有哪些优点和缺点?
先发生捕获事件,后发生冒泡事件
路由交给浏览器处理就算是;单页应用
axios,redux-promise
*(优点)因为Node是基于事件驱动和无阻塞的,所以非常适合处理并发请求,
因此构建在Node上的代理服务器相比其他技术实现(如Ruby)的服务器表现要好得多。
此外,与Node代理服务器交互的客户端代码是由javascript语言编写的,
因此客户端和服务器端都用同一种语言编写,这是非常美妙的事情。
*(缺点)Node是一个相对新的开源项目,所以不太稳定,它总是一直在变,而且缺少足够多的第三方库支持。看起来,就像是Ruby/Rails当年的样子。
XSS:攻击者在网页中嵌入客户端脚本(例如JavaScript)。
CSRF:跨站请求伪造,通过伪装来自受信任用户的请求来利用受信任的站点。
一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?(流程说的越详细越好):
而高手可以根据自己擅长的领域自由发挥,从URL规范、HTTP协议、DNS、CDN、数据库查询、到浏览器流式解析、CSS规则构建、layout、paint、onload/domready、JS执行、JS API绑定等等;
详细版:
1、浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;
2、调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;
3、通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;
4、进行HTTP协议会话,客户端发送报头(请求报头);
5、进入到web服务器上的 Web Server,如 Apache、Tomcat、Node.JS 等服务器;
6、进入部署好的后端应用,如 PHP、Java、JavaScript、Python 等,找到对应的请求处理;
7、处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回304;
8、浏览器开始下载html文档(响应报头,状态码200),同时使用缓存;
9、文档树建立,根据标记请求所需指定MIME类型的文件(比如css、js),同时设置了cookie;
10、页面开始渲染DOM,JS根据DOM API操作DOM,执行事件绑定等,页面显示完成。
简洁版:
浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求;
服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS等);
浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM);
载入解析到的资源文件,渲染页面,完成。
fetch和$().ajax()区别:1.return of fetch won’t reject on HTTP error, only reject when network failure or anything prevented request from completing.
2.by default, doesn’t send& receive cookies, if needed sessions need to set init options.
400,404,403forbidden,401unauthorized
500,502badgateway
结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如W3C DOM)、ECMAScript等。
W3C万维网联盟,指定XML,XHTML,CSS等标准。
doctype决定浏览器如何解析文档。说明HTML/XHTML是什么版本
global attributes:class,id,hidden,lang,style,title,contextmenu,dir,itemid,itemscope.
SVG 是一种使用XML描述2D图形的语言,支持事件处理器,不依赖分辨率。Canvas通过 JavaScript 来绘制2D图形。Canvas是逐像素进行渲染的。
圆形可点击区域
//第二种 使用CSS border-radius
#red{
cursor:pointer;
background:red;
width:100px;
height:100px;
border-radius:50%;
}
CSS Sprites是一种网页图片应用处理方式,就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位。减少HTTP请求。
display:none空间没了,visibility:hidden占据的空间仍然保留。
link和@import的差别
老祖宗的差别。link属于XHTML标签,而@import完全是CSS提供的一种方式。import不是DOM可以控制的。link引用的CSS会同时被加载,而@import引用的CSS会等到页面全部被下载完再被加载。
FOUC文档样式闪烁,IE里面head里没有标签导致没加载。
CSS2.1中三种定位方式:
普通流(Normal Flow)、浮动(Floats)和绝对定位(Absolute Positioning),下面分别对这三种布局简略说明一下。
然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。主要是为了文字环绕图片效果。在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定
BFC:1. BFC会阻止外边距折叠2. BFC可以包含浮动的元素3. BFC可以阻止元素被浮动元素覆盖
meta常用标签:name,content,viewport,charset:声明编码,http-equiv.
CSS样式优先级:最高的是内联
png无损数据,jpg多次上传下载会逐渐失真
写一个xyz
function mul (x) {
return function (y) { // anonymous function
return function (z) { // anonymous function
return x y z;
};
};
}
var salary = “1000$”;
(function () {
console.log(“Original salary was “ + salary);//undefined,变量提升
var salary = "5000$";
console.log("My New Salary " + salary);
})();
var声明的变量优先提升到头部,函数表达式声明也会提升到头部,再进行函数赋值
作用域链的原理和原型链很类似,如果这个变量在自己的作用域中没有,那么它会寻找父级的,直到最顶层。因此变量提升先在本块内进行。
异步加载JS脚本:动态创建元素,createElement(“script”);
script.src = “A.js”;
document.getElementsByTagName(‘head’)[0].appendChild(script);//塞进页面
HTML5:async;defer通用,async新特性
设计模式:单例,工厂,
内置对象:NaN,Date,Math,Obejct,eval,parseInt,parseFloat.
parseInt(“546”, 2); // 除了“0、1”外,其它数字都不是有效二进制数字
typeof NaN = number
会话跟踪的方式:URL重写,URL末尾添加数据标识对话;Cookie
eval(String)如果没有返回值返回undefined.
XML重量级,自我设计,W3C推荐标准。
1、写一个通用的事件侦听器函数
2、如何判断一个对象是否为数组
3、冒泡排序
4、快速排序
5、编写一个方法 求一个字符串的字节长度
中文占2字节,判断中文或替换
export default function qsort(arr) {
if(arr.length === 0 ) return [];
else {
let [pivot, …rest] = arr;
return [
…qsort(arr.filter(ele=>ele <= pivot)),
pivot,
…qsort(arr.filter(ele=>ele >= pivot))
]
}
}
export default function bubble(arr) {
var temp;
for(var i = 0; i < arr.length; i++) {
for(var j = 0; j < arr.length-i-1;j++) {
if(arr[j]>arr[j+1])
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
var EventUtil = {
//根据情况分别使用dom2 || IE || dom0方式 来添加事件
addHandler: function(element,type,handler) {
if(element.addEventListener) {
element.addEventListener(type,handler,false);
} else if(element.attachEvent) {
element.attachEvent(“on” + type,handler);
} else {
element[“on” + type] = handler;
}
},
//根据情况分别获取DOM或者IE中的事件对象,事件目标,阻止事件的默认行为
getEvent: function(event) {
return event ? event: window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function(event) {
if(event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
//根据情况分别使用dom2 || IE || dom0方式 来删除事件
removeHandler: function(element,type,handler){
if(element.removeHandler) {
element.removeEventListener(type,handler,false);
} else if(element.detachEvent) {
element.detachEvent("on" + type,handler);
} else {
element["on" + type] = null;
}
}
//根据情况分别取消DOM或者IE中事件冒泡
stopPropagation: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
}
var btn = document.getElementById(“myBtn”),
handler = function () {
alert(“Clicked”);
};
EventUtil.addHandler(btn,”click”,handler);
EventUtil.removeHandler(btn,”click”,handler);
GET指定了资源在服务器上的位置,而POST没有
XHTML元素必须被正确地嵌套,闭合,区分大小写,文档必须拥有根元素
var foo = (function() {
var t;
return function() {
if (t) return t;
t = new Date();
return t;
}
})();
函数返回首次调用的Date对象
常见布局:
float+margin
左浮动,右浮动,margin-left/right=left/right的宽度。DOM文档先写两侧蓝,再写主栏。
position+margin
.left,.right{
position:absolute;
top:0;
width:200px;
}.left{left:0;} .right{right:0;}
.main{
margin:0,200px;
}
流体布局
圣杯布局
main必须优先书写,left,right
三者都设置浮动,main width:100%,left+right设置相对布局.都设置margin-left
.main {
float: left;
width: 100%;
}
.sub {
float: left;
width: 190px;
margin-left: -100%; //左边栏
position: relative;
left: -190px;
}
.extra {
float: left;
width: 230px;
margin-left: -230px;
position: relative;
right: -230px; //自身宽度
}
#bd {
padding: 0 230px 0 190px;
}
双飞翼布局,main用margin.圣杯则用padding。
用div-wrapper包含div,left+right.
.main-wrapper{
width:100%;
float:left;
}
.left{
float:left;
width:100px;
margin-left:-100%;
}
.right{
float:left;
width:200px;
margin-left:-200px;
}
.main{
margin:0,200px,0,100px;
}
事件委托的原理是事件冒泡。
捕获阶段,目标阶段,冒泡阶段。DOM事件流同时支持两种事件。
阻止冒泡:stopPropogation();阻止捕获:preventDefault().
工厂模式:解决重复实例化
src放在页面最后加载,防止堵塞。
combineReducers from redux;
export default combineReducers(form,postReducer);
applyMiddleware(promise,rootReducers)
必须写default.
function(state={},action)
switch(action.type) {
case FETCH_POSTS:
}
redux-promise provides a promise as middleware and only return when it is resolved. You can use redux-promise in combination with redux-actions.
axios make http requests from nodejs,保护XSRF/CSRF
reducer actions:function deletePost. Component里面
mapStateToProps(state) {
return {posts:state.post};//props自身属性
}
mapActionToProps(dispatch) {
bindActionCreators({fetchPost:fetchPost},dispatch);
}
目的是为了变成props在View视图中进行触发,obSubmit={this.formSubmit.bind(this)}
connect(mapStateToProps,mapActionToProps)(Conponent);
componentDidMount()内部进行获取数据改变State等操作.
React-router:
state是只读的,用触发action修改state.reducer接受新的action把当前state返回新的state.
bindActionCreators() 可以自动把多个 action 创建函数 绑定到 dispatch() 方法上。
Redux 应用只有一个单一的 store。拆分逻辑通过拆分reducer。
维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
严格的单向数据流是 Redux 架构的设计核心。
展示组件和容器组件相分离
React Rarely have their own state (when they do, it’s UI state rather than data).
需要传递的state很深,传递给多层子组件,考虑使用容器来从store直接获取状态。
在这类框架中,middleware 是指可以被嵌入在框架接收请求到产生响应过程之中的代码。可以被链式组合,使用多个第三方middleware。redux-middleware提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。
使用dev-server开发。 browserHistory移除URL中的#
devServer: {
historyApiFallback: true,
}
hot reload(热加载) 就是每次修改某个 js 文件后,页面局部更新。通常来说,当我们修改了代码刷新页面,那应用里的所有状态就都没有了。这对于开发一个单页应用来说是非常痛苦的,因为需要重新跑一遍流程。如果有模块热加载,当你修改了代码,你的代码会直接修改,页面并不会刷新,所以状态也会被保留。
Nodejs
- dirname:当前文件所在路径。filename:当前文件路径名。
app.use('/user/:id', function (req, res, next) {console.log('Request Type:', req.method);next();});
在指定路径上使用中间件,对req/res对象进行更改,结束请求和响应循环。- 后台也有API和MySQL通信。
npm install mysql --save
. Connection config - Use template files as View.(不使用React).类似JSP,直接获取要显示的内容。典型例子:Jade,ejs,pug.Jade has been updated to Pug.
app.set('views', './views')
to set the view source dir.app.set('view engine', 'pug')
.When you make a request to the home page, the index.pug file will be rendered as HTML.
var connection = mysql.createConnection({});
connection.connect();
connection.query(‘’,function(){});
connection.end();
isSorted
function isSorted(arr) {
const limit = arr.length - 1;
return arr.every((, i) => (i < limit ? arr[i] <= arr[i + 1] : true));
}
intersection of 2 array
arr1.filter((n)=>arr2.includes(n)); .intersection(arr1,arr2);
bind solves problem of context, bind(function, {name:whw});
apply takes an array of arguments; call takes a column-list of arguments.功能基本一样
每次调用then,你都在创建一个新的Promise对象。then就像一个锁链一样,将前后的两个Promise对象连接起来。
Promise.prototype.then = function(resFn, rejFn) {
var pP = this;
return new Promise((res, rej) => thenHandler(res, rej, resFn, rejFn, pP))
}
垂直水平居中复习
{
top:50%;
left:50%;
position:absolute;
margin-top:-xx;-height/2
margin-left:-xx;-width/2
}
{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
}
三等分布局
1..child{
float:left;
width:33.3%;
}
2..child{
display:inline-block;////
width:33.3%;
}
清除浮动:父元素overflow:auto
下一个标签:clear:both;
一般核心区域自适应,侧栏固定.左右两列固定,中间自适应宽度
浮动+分别向左右两边浮动.先写侧栏后写main.
#left,
#right {
float: left;
width: 220px;
height: 200px;
background: blue;
}
#right {
float: right;
}
#main {
margin: 0 230px;
background: red;
height: 200px;
}
///////
左右absoulte position, left,right:0;main:margin
使用margin负值:margin-right:-4px;
font-size:///移除空格代码
消除inline-block的空格站位问题。
左右带有侧栏,中间自适应,左右分别向左右两边浮动。main:margin-left/margin-right
padding/margin百分比是相对于父级宽度还是自身的宽度,父容器宽度
height,top,bottom相对于父容器高度
let暂时性死区:let.const区块开始就构成封闭作用域,不能先使用后声明。reference error.
控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
function qsort(arr) {
let [pivot,…rest] = arr;
if(arr.length==0) return [];
return [
…qsort(arr.filter((ele)=>ele
]
}
function(left,right){
var tmp=[];
while (left.length && right.length) {
if (left[0] < right[0])
tmp.push(left.shift());
else
tmp.push(right.shift());
}
return tmp.concat(left, right);
}
function mergeSort(a) {
if (a.length === 1)
return a;
var mid = ~~(a.length / 2)
, left = a.slice(0, mid)
, right = a.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
继承的几种方法:
1.构造继承:
function Animal() {
this.species = “动物”;
}
function Cat() {
Animal.call(this,specifies);///Animal.apply(this, arguments);
this.name = name;
this.color = color;
}
2.原型继承
Cat.prototype = new Animal();核心语句
Cat.prototype.constructor = Cat;//必须手动修改构造函数
//Cat.prototype = Animal.prototype;
//Cat.prototype.constructor = Cat;
3.拷贝继承
var c = Animal.prototype; var p = Animal.prototype;
for..=;
二者皆为异步加载模块。
Commonjs适合服务端 require
AMD:先定义所有依赖,然后在加载完成后的回调函数中执行:
AMD依赖前置,js可以方便知道依赖模块是谁,立即加载;而CMD就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块,
function merge(left,right) {
var emp=[];
while(left.length&&right.length) {
if(left[0]>right[0])
emp.unshift(right[0]);
else emp.unshift(left[0]);
}
return emp.concat(left,right);
}
fucntion mergesort(arr) {
if(arr.length <=1)return arr;
var mid = arr.length/2;
var left = arr.slice(0,mid);
var right = arr.slice(mid);
return merge(mergesort(left),mergesort(right))
}
如果display为none,那么position和float都不起作用,这种情况下元素不产生框
否则,如果position值为absolute或者fixed,框就是绝对定位的,float的计算值为none,display根据下面的表格进行调整。
否则,如果float不是none,框是浮动的,display根据下表进行调整
否则,如果元素是根元素,display根据下表进行调整
其他情况下display的值为指定值
总结起来:绝对定位、浮动、根元素都需要调整display
display:inline-block 什么时候不会显示间隙?(携程)
移除空格
使用margin负值
使用font-size:0
letter-spacing
word-spacing
document.getElementById(“ul”).addEventListner(“click”,function(){
if(ul.length <0) return;
if(event.target.Nodename ===”li”)
console.log(“edf”+target.innerHTML);
},false);
函数的变量对象:保存所有包含的参数,内部函数,和变量数据。
function foo (arg) {
var variable = ’我是变量‘;
function innerFoo () {
alert(“我是彭湖湾”)
}
}
foo(‘我是参数’);
ExecutionContext = {
variableObject: {
variable:’我是变量‘
innerFoo: [对函数声明innerFoo的引用]
arg: ‘我是参数’
},
this: thisValue,
Scope: [ // Scope chain
// 所有变量对象的列表 ]
};
innerFoo的作用域链包含所有的变量对象。foo的包含自己和外部。
可能会使用到多层嵌套的闭包,这种用法,叫做“柯里化”。而闭包柯里化有两大作用:参数累加和延迟调用只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
var foo1 = foo(‘我’);
var foo2 = foo1(‘叫’);
foo2(‘彭湖湾’); // 打印 我叫彭湖湾
function createArray() {
var arr = new Array();
for (var i = 0; i < 10; i++) {
arr[i] = function () {
return i;
}
}
return arr;
}
var funcs = createArray();
for (var i = 0; i < funcs.length; i++) {
document.write(funcsi + “
“);
}
这几个函数都保留着对同一个外部函数的变量对象的引用
因为闭包函数“延迟调用”的特性,而关键变量值i的获取是在闭包函数调用(f也即uncsi)的时候才从外部函数的变量对象中获取,而这个时候,外部函数早就完成for循环使 i =10了 !!!
.main {
position:absolute;
width:200px;
height:300px;
top:50%;
left:50%;
margin-top:-150px;
margin-left:-100px;////transform:translate(-50%,-50%);
}box-sizing:border-box;
var a = 1;
a.a = 2;
console.log(a.a);//undefined
//split返回字符数组。str.split(seprator).reverse().join(seprator);
var arr=msg.split(“-“); //split(“-“)以-为分隔符截取字符串,返回数组
for(var i=1;i<arr.length;i++){
arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1);
}
msg=arr.join(“”); //join()加入什么,连接数组元素,返回字符串
return msg;
//范围内随机整数
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
数组去重,新数组indexOf().
var arr = [2,4,2,2,5,6,7,8,9,9,9];
function unique(arr){
var arr1 = [];
for (var i = 0;i < arr.length;i ++){
if(arr1.indexOf(arr[i]) == -1){
arr1.push(arr[i]);
}
}
return arr1;
}
function unique(array) {
var res = array.filter(function(item, index, array){
return array.indexOf(item) === index;
})
return res;
}
Function.prototype.bind = function(ctx) {
var fn = this;
return function() {
fn.apply(ctx, arguments);
};
};
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}立即输出0-4
箭头函数没有this,不能new,没有原型属性prototypes
异步编程的四种方式:
1.callback
2.事件监听:任务的执行不取决于代码的顺序,而取决于某个事件是否发生。f1.on('done', f2);
,function f1(){setTimeout(function () {// f1的任务代码 f1.trigger('done');}, 1000);}
.
3.发布/订阅:jQuery.subscribe("done", f2);
.
4.Promise:(1)顺序promise,链式调用。(2)Promise类有一个all方法,其接受一个promise数组:1
2Promise.all([promise1,promise2,...,promise10]).then(function(){
});
new Promise(function(resolve,reject){
setTimeout(function(){},1000);
});
Promise.all([promise1,promise2,promise3]);
只有promise数组中的promise全部兑现,才会调用then方法。使用Promise.all,我们可以并发性的进行网络请求,并在所有请求返回后在集中进行数据展示。1
2
3
4
5
6//并发请求章节数据,一次性按顺序展示章节
Promise.all(chapterStrs.map(getChapter)).then(function(chapters){
chapters.forEach(function(chapter){
addToPage(chapter);
});
});
并发处理多个AJAX请求,jQuery:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var d1 = $.Deferred();
var d2 = $.Deferred();
function async1(){
d1.resolve( "Fish" );
}
function async2(){
d2.resolve( "Pizza" );
}
**$.when(deferred)提供一种方法执行一个或多个对象的回调函数。**
等待所有延迟函数解析完返回.then/.done(function(){})
$.when( d1, d2 ).done(function ( v1, v2 ) {
console.log( v1 + v2 + '已完成');
});
函数节流,不希望函数太频繁的触发:resize,scroll,mousemove,keydown/keyup.在 JavaScript 中,debounce 函数所做的事情就是,强制一个函数在某个连续时间段内只执行一次,哪怕它本来会被调用多次。
debounce实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function debounce(fn, delay) {
// 定时器,用来 setTimeout
var timer
// 返回一个函数,这个函数会在一个时间区间结束后的 delay 毫秒时执行 fn 函数
return function () {
// 保存函数调用时的上下文和参数,传递给 fn
var context = this
var args = arguments;
console.log(context);//打印this就是打印当前这个函数
// 每次这个返回的函数被调用,就清除定时器,以保证不执行 fn
clearTimeout(timer)
// 当返回的函数被最后一次调用后(也就是用户停止了某个连续的操作),
// 再过 delay 毫秒就执行 fn
timer = setTimeout(function () {
fn.apply(context, args)
}, delay)
}
}
实例:在用户“停止”输入一小段时间以后,再发送请求。那么 debounce 就派上用场了:
$(‘input’).on(‘keyup’, debounce(function(e) {
// 发送 ajax 请求
}, 300))
固定函数执行的速率,即所谓的“节流”。正常情况下,mousemove 的监听函数可能会每 20ms(假设)执行一次,如果设置 200ms 的“节流”,那么它就会每 200ms 执行一次。1
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
29function throttle(fn, threshhold) {
// 记录上次执行的时间
var last
// 定时器
var timer
// 默认间隔为 250ms
threshhold || (threshhold = 250)
// 返回的函数,每过threshhold毫秒就执行一次 fn 函数
return function () {
// 保存函数调用时的上下文和参数,传递给 fn
var context = this
var args = arguments
var now = +new Date()
// 如果距离上次执行 fn 函数的时间小于 threshhold,那么就放弃
// 执行 fn,并重新计时
if (last && now < last + threshhold) {
clearTimeout(timer)
// 保证在当前时间区间结束后,再执行一次 fn
timer = setTimeout(function () {
last = now
fn.apply(context, args)
}, threshhold)
// 在时间区间的最开始和到达指定间隔的时候执行一次 fn
} else {
last = now
fn.apply(context, args)
}
}
}
debounce&&throttle区别
The setInterval() method of the WindowOrWorkerGlobalScope mixin repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval()./clearTimeout()
loadash可以直接替换underscore,并获得性能上的提升。
.debounce/.throttle()都是返回一个特定执行的函数。
_.before(n,func)call n次才invoke func.
_.spread(func)return function much like apply.
spread operator, myfunc(…args);多个参数参数传递、多个变量(用于解构赋值)。
function test(a, b, c) { }
var args = [0, 1, 2];
test.apply(null, args);
//test(…args);
字面变量合并:var arr2=[…arr1,’d’,’e’];
解构:let [pivot,…rest] = arr;//只能用在最后
二面还是会手写代码,实现一些函数
大概过了5分钟,二面面试官就上线了,开始也是自我介绍,还是一面的那几句。然后问了和一面基本一样的问题,html5的新特性,CSS3的新特性,追问我localStorage、sessionStorage和session的区别(这次加了个session)。然后问我addeventListener第三个参数是干嘛的,好像答错了,平时确实没怎么用到过。
session存在于服务期端,cookie存在于客户端。session会在一定时间内保存在服务器上。webStorage仅仅在本地客户端存储。sessionStorage不在不同窗口共享;cookie&localStorage在同源窗口共享。sessionId每次客户发起请求会带上sessioonID,没有的话服务端分配。
Cookie隔离:
把js,css,图片等静态资源放在非主域名下,这样在请求这些资源的时候就不会带上主域名的cookie。从而降低传输成本和服务端的压力
先是问我对jquery熟不熟,我说没怎么用过,平时用的比较多的是vue和react这些框架。但是,面试官仿佛对jquery有一种执念,还是继续问我jquery的问题,很崩溃,jquery我真是几乎没用过,先问我知不知道$.trim()是啥,然后让我现场写代码实现一个。然后问我$(document).ready() 与window.onload的区别,接着让我写代码实现一个$(document).ready() ,这几个问题应该都没答好,然后面试官也懒得问了,就让我实现一个快速排序,然后说一说时间和空间复杂度,然后再就问了几个基础题,就让我等消息了。
str.replace(‘/^\s+|\s+$/‘);
//Next greater element
//从后面开始的数字应该依次递增,找到第一个递减的。记录位置,从末尾开始找第一个比这个数字大的,交换数字,逆向排序后面的元素。
this.咋回事
实现一个$(document).ready()
Array.prototype.apply(this,arguments);
flex属性都代表什么意思
事件函数:发生某一事件会触发回调:$(document).ready(function(){
$().click(function(){….}).加载对象,DOM解析之后
}). focus, mouseover,
chaining,事件依次发生执行。
.attr(“width”,”180px”),.attr()获取属性值,.text(),.val(value)设置或返回匹配元素的值。返回表单字段值。.remove()删除子元素、选中元素且删除其下面的所有包含事件。
load()方法从服务器加载数据,并把返回的数据放入被选元素中。
$().load(URL,data,callback)回调函数。
arguments.callee contains the currently executing function.
function (fn) {
if($(document).addEventListner) {
$(document).addEventListner(“DOMContentLoaded”,function(){
$().removeEventListner(“DOMContentLoaded”,arguments,callee,false);
fn();
},false)
}
}
const animal = {
name:[“es6”,”c++”,”java”],
love:[“lxj”,”mama”,”java”],
fun:function(){
let fn = this;//增加这一句function才能辨别到外部对象的this是什么
setTimeout(function(){
console.log(fn.name[2]);
console.log(fn.love[1]);
},200);
}
}
animal.fun();
或者用立即执行函数bind(this).
const animal = {
name:[“es6”,”c++”,”java”],
love:[“lxj”,”mama”,”java”],
fun:function(){
setTimeout((function(){
console.log(this.name[2]);
console.log(this.love[1]);
}).bind(this),200);
}
}
animal.fun();
///////////////////////////////////////////////
rem工作原理
熟悉node和element对象
原生的DOM操作
断点调试法nodejs
严格模式(ES5)
em作为字体单位为父元素大小,作为其他属性为相对自身大小。
rem相对于非根元素相对于根元素字体大小。vm/vw视口高度宽度
文档本身是文档节点
所有HTML元素是元素节点
所有HTML属性是属性节点
HTML元素内的文本是文本节点
注释是注释节点
element.scrollTop上边缘与视图间距/scrollLeft与左边缘的距离
element.scrollWidth宽度、scrollHeight
文字垂直居中:vertical-align:center只适用于有这个属性的标签,
多行内容居中,且容器高度可变,也很简单,给出一致的padding-bottom和 padding-top 就行:
.middle-demo-2{
padding-top: 24px;
padding-bottom: 24px;
}
box-sizing:border-box;保证border和padding不改变元素自身大小。
padding-bottom和width设置为百分比来保证元素自适应宽高
DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。
document.createElement(“div”);//并未添加到html文档中;
document.querySelector(“.class”);//选中第一个
document.getElementByClassName(“class”);
document.querySelectorAll(“class”);
ele.appendChild(e1);//////jQuery append,prepend,after(在被选元素之后插入内容),before(在被选元素之前插入内容)
ele.removeChild(e2);
ele.replaceChild(el1, el2);//替换子元素
var c = el.getAttribute(‘class’);
el.setAttribute(‘class’, ‘highlight’);
jQuery appendTo()添加到文档结尾.
$().html()写入标签内部内容
DOM元素的innerHTML, outerHTML, innerText, outerText属性的区别也经常被面试官问到。
Node有一个属性nodeType表示Node的类型,它是一个整数,其数值分别表示相应的Node类型,JS中所有节点都继承自Node类型,都共享着相同的基本属性和方法。 element nodetype==1.nodeName为元素标签名,tagName也是返回标签名,返回大写形式(DIV). document nodeValue为null,nodeName为#document。
nodejs调试方式
npm install -g node-inspector
node-inspector –web-port 8080 –debug-port 5859
8080为调试页面窗口。
http://localhost:8080/debug?port=5858打开页面
V8 Inspector Integration可以让DevTools直接连接 Node.js的Debugger进行调试。
node –inspect app.js
apply可以不传入参数:则为null 或 undefined.
类数组对象变成数组:[…arguments];//Array.prototype.slice.apply(null,arguments);
只要不是float和绝对定位方式布局的,都在普通流里面。
元素如果被定位了,那么它的top,left,bottom,right值就会生效,能设置定位的属性是relative,absolute和fixed
立即执行函数
// 下面2个括弧()都会立即执行
(function () { / code / } ()); // 推荐使用这个
(function () { / code / })(); // 但是这个也是可以用的
事件的Event对象
当一个事件被触发的时候,会创建一个事件对象(Event Object),这个对象里面包含了一些有用的属性或者方法。事件对象会作为第一个参数,传递给我们的回调函数。function(e) {console.log(e.target.value);}
event.type()事件名称;event.target要触发的目标节点;event.currentTarget正在处理事件的元素。
Flex元素是可以让你的布局根据浏览器的大小变化进行自动伸缩,自动适应空间。
align-items:交叉轴上对齐/justify-content:水平方向对齐
浏览器环境中this是全局window.
var foo = 2;
this.foo==window.foo.
函数正常调用时指向的是全局作用域,function foo(){this.x=”sad”;}foo();
使用new进行调用创建新的上下文,对象实例,console.log(foo().x)//sad;this.x=外部x.
用new创建的对象开始时会共用一个原型。
在原型上创建属性,一个做改变都会受影响,在函数内部创建不会受影响。
Thing.prototype.foo = “dsa”;new Thing(),thing1.foo=”das”.thing2.foo=也会受到改变。
如果原型链中某个地方对变量赋值,就进行了覆盖。
function Thing() {
}
Thing.prototype.foo = “bar”;
Thing.prototype.logFoo = function () {
var info = “attempting to log this.foo:”;
// var fn=this;
function doIt() {
console.log(info, this.foo);//这样打出来是UNdefined
}
doIt();
}
var thing = new Thing();
thing.logFoo(); //logs “attempting to log this.foo: undefined”
this指代的是window全局对象、访问函数外部对象是通过闭包。因此要bind(this).
使用变量保存this在函数做参数传递时不奏效。exter(fun);
对于对象,直接的函数方法可以访问到this属性;包含的函数还是访问不到。
var obj = {
foo: “bar”,
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs “bar”
DOM中的回调this指向绑定元素。
无法重写this。
.on/off(eventName)取消绑定。
.on({
mouseover:function(){},
mouseleave:function(){},
click:function(){}
})
.on(click,function(){});
event.currentTarget==this,事件委托的话是绑定的元素、target是真正触发的元素。
$.Deferred()解决如何处理耗时操作,返回一个可供链式调回调函数队列。它彻底改变了如何在jQuery中使用ajax。相当于异步回调操作
$.ajax(“index.html”).done(function(){alert(“dsa”)}).fail(function(){fail})可以添加多个回调函数.done().done(function(){});
ajax返回一个deferred对象;$.when(havefun()).done(…).fail(…).
when函数传递进去的必须是一个deferred对象,可以new Deferred();dtn.resolve().
$.data(id,key,value)
jQuery.noConflict();库冲突原理
Normal Flow
Containing Block
Margin Collapse
BFC 块格式化上下文
Baseline
Writing Mode
unicode-bidi
模板引擎
理解方法的 arguments 变量,包括如何使用它来通过 arguments.length 重载函数,以及通过 arguments.callee 来进行递归调用,需要注意使用这个特性有一定的危险性,因为 ECMAScript 5 的 Strict 模式不支持此功能,但 jQuery 和 Dojo 都用到了它。
高级闭包比如 self-memoizing 函数,partially applied 函数,以及最可爱的 (function(){})() 调用。
函数以及 HTML prototype,prototype chain,以及如何使用基本的javascript对象和函数(比如 Array)来简化代码。
对象类型以及 instanceof 的使用
正则表达式和表达式编译
With 语句以及为什么不要使用它们
with的本意是减少键盘输入。比如
obj.a = obj.b;
obj.c = obj.d;
可以简写成
with(obj) {
a = b;
c = d;
}
但是,在实际运行时,解释器会首先判断obj.b和obj.d是否存在,如果不存在的话,再判断全局变量b和d是否存在。这样就导致了低效率,而且可能会导致意外,因此最好不要使用with语句。
eval性能和安全性的问题
尽量使用函数表达式声明函数,这样遵循先声明后使用的规范。
如何高效的操作 DOM(添加,删除以及更新),还有如何通过使用 document fragments 这样的工具来最小化浏览器的 re-flows。
跨浏览器的事件处理,绑定,反绑定,冒泡,以及如何取得期望的回调上下文。在一次,现成的框架也可以很好的处理这些事情,但是你应该对 IE 浏览器和 W3C 标准浏览器之间的不同有所了解。
正则表达式选取 DOM 节点
$代表jQuery函数.
$.fn=$.prototype
jQuery.fn.extend({})添加成员函数.
$(‘[name=NameOfSelectedTag] :selected’)
//jQuery中使用,等待DOM加载完毕后就执行
$(document).ready(fucntion(){…})
//jQuery中使用,等待页面全部加载完毕后才执行(图片音频视频等全部加载完毕后才执行)
$(window).load(function(){ …})
//纯js中使用,等待页面全部加载完毕后才执行(图片音频视频等全部加载完毕后才执行)
window.onload = function(){…}
detach()和remove()方法的区别是什么?
detach仅仅从DOM中删除,不删除绑定的事件和数据,还能恢复;remove全部删除。
如何利用jQuery来向一个元素中添加和移除CSS类?
addClass,removeClass().
.each chain选中的元素:$().each(function(element){}),对每个选中的元素进行操作。
$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法
使用CDN的优势
除了报错节省服务器带宽以及更快的下载速度这许多的好处之外, 最重要的是,如果浏览器已经从同一个CDN下载了相同的jQuery版本, 那么它就不会再去下载它一次.
原生js更高效,直接调用了JS引擎。
$().attr(name,value)设置或返回属性值,string格式”color”:”blue”
DOM tree+CSSOM===render tree
什么是JS的函数防抖?
jQuery一个对象可以绑定多个事件,$().on({})
“click”:function(){},””:function(){}.
$(“div”).trigger(“click”,data);传递数据进来
this总是指向函数的直接调用者(而非间接调用者);
如果有new关键字,this指向new出来的那个对象;
在事件中,this指向触发这个事件的对象
Cookie隔离:如果静态文件都放在主域名下,那静态文件请求的时候都带有的cookie的数据提交给server的,非常浪费流量,所以不如隔离开。
因为cookie有域的限制,因此不能跨域提交请求,故使用非主要域名的时候,请求头中就不会带有cookie数据,这样可以降低请求头的大小,降低请求时间,从而达到降低整体请求延时的目的。同时这种方式不会将cookie传入Web Server,也减少了Web Server对cookie的处理分析环节,提高了webserver的http请求的解析速度。
jquery.extend 为jquery类添加类方法,可以理解为添加静态方法
源码中jquery.fn = jquery.prototype,所以对jquery.fn的扩展,就是为jquery类添加成员函数
使用:
jquery.extend扩展,需要通过jquery类来调用,静态对象,而jquery.fn.extend扩展,所有jquery实例都可以直接调用。
for
Keys负责帮助React跟踪列表中哪些元素被改变/添加/移除。
(function(){
var a = b = 3;
})();
console.log(“a defined? “ + (typeof a !== ‘undefined’));
console.log(“b defined? “ + (typeof b !== ‘undefined’));
false,true
b=3;
var a=b;
b被定义成全局变量
var myObject = {
foo: “bar”,
func: function() {
var self = this;
console.log(“outer func: this.foo = “ + this.foo);
console.log(“outer func: self.foo = “ + self.foo);
(function() {
console.log(“inner func: this.foo = “ + this.foo);
console.log(“inner func: self.foo = “ + self.foo);
}());
}
};
myObject.func();
bar.bar.undefined.bar;直接对象的成员能访问到.
立即执行函数:jQuery中避免变量污染.
js里面return 后面不能跟换行,否则会加分号,变undefined。
function foo2()
{
return
{
bar: “hello”
};
}
判断数字是否是整数
function isInteger(x) {
return parseInt(x, 10) === x;
}
Number.isInteger(x);
判断参数的个数,arguments.length
function sum() {
var fir = arguments[0];
if(arguments.length === 2) {
return arguments[0] + arguments[1]
} else {
return function(sec) {
return fir + sec;
}
}
}
slice(),使用-index返回数组里最后几个元素组成的数组.(-1)返回最后一个元素.
reverse会改变数组本身,并返回数组的引用.
if(undefined)—>false
加定时器防止堆栈溢出
if([])console.log()会显示输出.区别于[]==false
[]==[] false/////[]===[] false
if({})//会显示输出
[]==false true; {}==false false {}==true false
‘0’==false true Boolean(‘0’) true
var hero = {
_name: ‘John Doe’,
getSecretIdentity: function (){
return this._name;
}
};
var stoleSecretIdentity = hero.getSecretIdentity;
console.log(stoleSecretIdentity());
console.log(hero.getSecretIdentity());//undefined
需要绑定上下文
给所有children增加callback
函数接受指定的参数////回调函数
function Traverse(p_element,p_callback) {
p_callback(p_element);
var list = p_element.children;
for (var i = 0; i < list.length; i++) {
Traverse(list[i],p_callback); // recursive call
}
}
function Foo() {
getName = function () { alert(1); }
return this;
}
Foo.getName = function () { alert(2); }//静态属性
Foo.prototype.getName = function () { alert(3); }
var getName = function () { alert(4); }//函数变量表达式
function getName () { alert(5); }//函数声明
/ 写出输出 /
Foo.getName(); //2,访问静态属性
getName(); //4,,,,,,函数声明和函数表达式会进行变量提升拆分成两部分
//////////var getName;function getName;//下面的函数表达式又一次进行覆盖
Foo().getName(); //1,调用Foo(),进行了函数赋值,当前作用育没有,向上寻找,将全局的覆盖掉。
getName();//1,相当于window.getName()
new Foo.getName();//2,.的运算及高,出现2、、内部属性
new Foo().getName();//3 ()运算及高,先执行new Foo()
new new Foo().getName();//3
slice/concat浅拷贝,对象只拷贝指针,互相影响
JSON.stringify(JSON.parse(arr))深拷贝
数组去重,filter保留index是他本身的
function unique (arr) {
var res = arr.filter(function (item, index, array) {
return array.indexOf(item) === index;
})
return res;
}
数组扁平化,全部展开。_.flatten
var arr = [1, [2, [3, 4]]];
function flatten(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(…arr);
}
return arr;
}
Array.isArray()调用传参.
函数防抖:debounce,尽管事件发生多少次,一定在ns之后触发函数。如果又触发就以此作为新的时间节点。
debounce.cancel = function(){clearTimeout(timer);timer=null;}
组合函数嵌套,函数作为参数:
compose
function compose() {
var args = arguments;
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i–) result = args[i].call(this, result);
return result;
};
};
$.extend(obj,obj1,obj2)将两个更多对象合并到目标对象里面.
数组乱序
function shuffle(a) {
var j, x, i;
for (i = a.length; i; i–) {
j = Math.floor(Math.random() * i);
x = a[i - 1];
a[i - 1] = a[j];
a[j] = x;
}
return a;
}
MVVM,View,Viewmodel,model.Model和Viewmodel之间双向通信。
唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。
deferred.done(callback) callback function to be called.
Design pattern
工厂模式定义创建对象的接口,但是让子类决定实例化哪个类。工厂方法将类的实例化延迟到子类。
jQuery中的$()其实就是一个工厂函数,它根据传入参数的不同创建元素或者去寻找上下文中的元素,创建成相应的jQuery对象。
当需要根据不同参数产生不同实例,这些实例都有相同的行为,这时候我们可以使用工厂模式,简化实现的过程,同时也可以减少每种对象所需的代码量。工厂模式有利于消除对象间的耦合,提供更大的灵活性。
Lazy Load其实是对图片的一种延迟加载技术,直到用户滚动图片出现在用户可视范围时才把它加载出来。它与图片预加载技术完全相反,却都是为了提高用户体验而设计。
$().load(url,data,callback)从服务器获取数据
$().ready(function(){});只能用于当前文档;无需选择器//$(document).ready
jQuery ready函数实现
function ready(fn){
if(document.addEventListener) { //标准浏览器
document.addEventListener(‘DOMContentLoaded’,function() {
//注销时间,避免反复触发
document.removeEventListener(‘DOMContentLoaded’,arguments.callee,false);
fn(); //执行函数
},false);
}
}