nexttick
是作什么用的?JavaScript数据类型转换: juejin.im/post/5cee56…css
gulp 任务执行器html
侧重规范前端开发的流程,经过配置一系列的task,定义task处理的事务(例如:文件压缩合并,启动server),而后定义执行顺序,来让gulp执行task,从而构建其前端项目的流程。合并后仍然是你写的代码,只是局部变量名被替换,一些语法作了转换而已,总体内容并无发生改变。前端
webpack 模块打包器vue
侧重模块打包,把开发中的全部资源(图片,js文件,css文件等)都开成模块,经过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。打包后的代码已经不仅是你写的代码,其中夹杂不少webpack自身的模块处理代码。webpack
区别es6
Gulp是对整个过程进行控制,因此在其配置文件(gulpfile.js)中配置的每个task对项目中该task配置路径下全部的资源均可以管理 Webpack则不是这样管理资源的,它是根据模块的依赖关系进行静态分析,而后将这些模块按照指定的规则生成对应的静态资源, 对资源文件的处理是经过入口文件产生的依赖造成的,不会像Gulp那样,配置好路径后,该路径下全部规定的文件都会受影响web
chunk([1, 2, 3, 4, 5], 2) -> [[1, 2], [3, 4], [5]]
// 先计算出生成的数组长度,而后利用Array.from的第二个参数去映射
const chunk = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
arr.slice(i * size, i * size + size)
);
复制代码
30 seconds of code 这个连接收集了不少短小但实用的代码片断,你能够在30秒内理解它。里面极可能就有你天天在用的lodash方法Function.prototype.bind = function (oThis) {
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () { },
fBound = function () {
return fToBind.apply(this instanceof fBound
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 如下两行代码解决了什么问题,试举例说明
if (this.prototype) fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
复制代码
若是没有上面的简单原型链继承,这里F的原型对象上的print方法就会丢失:const F = function() {
this.name = 'haha'
}
F.prototype.print = function() {
return this.name
}
const FBound = F.myBind(null)
const f = new FBound()
console.log(f)
console.log(f.print()) // 不维护原型的话,这里会找不到print,进而报错
复制代码
除此以外,这个bind实现没有处理函数的length属性,而原生的bind会进行处理。例如:const add = (a, b) => a + b
const addOne = add.bind(null, 1)
addOne.length // 1
复制代码
这可能会致使依赖length的后续操做失败,例如柯里化等Function.prototype.myBind = function (ctx, ...fixed) {
if (typeof this !== 'function') {
throw new TypeError('What is trying to be bound is not callable');
}
const fToBind = this
const fNOP = function () { }
const fBound = function (...args) {
return fToBind.call(
this instanceof fBound ? this : ctx,
...fixed, ...args
)
}
if (this.prototype) fNOP.prototype = this.prototype
fBound.prototype = new fNOP()
// 设置新函数的length,若是原本就是0,那咱们就也设置为0
Object.defineProperty(fBound, 'length', {
value: Math.max(0, fToBind.length - fixed.length),
writable: false,
configurable: true
})
return fBound
}
const addThreeNum = (a, b, c) => a + b + c
console.log(addThreeNum.myBind(null, 1).length) // 2
复制代码
MDN - Function.prototype.bind()class Observable {
constructor() {
this.cbs = []
}
subscribe (cb) {
this.cbs.push(cb)
}
emit (x) {
this.cbs.forEach(cb => cb(x))
}
}
const observable = new Observable()
observable.subscribe(console.log)
observable.subscribe(x => console.log(x * 2))
observable.emit(3) // output: 3 6
复制代码
咱们来分析一下:[]==![] 是true仍是false?
vue-router
- 首先,咱们须要知道 ! 优先级是高于 == (更多运算符优先级可查看:运算符优先级)
- ![]引用类型转换成布尔值都是true,所以![]的是false
- 其中一方是 boolean,将 boolean 转为 number 再进行判断,false转换成 number,对应的值是 0.
- 有一方是number,那么将object也转换成Number,空数组转换成数字,对应的值是0.(空数组转换成数字,对应的值是0,若是数组中只有一个数字,那么转成number就是这个数字,其它状况,均为NaN)
- 0 == 0; 为true
- commonJS 浅拷贝,值能够被修改,优先从缓存中取值,加载时执行,一旦出现某个模块被“循环加载”,就只输出已执行的部分,还未执行的部分不输出
- es6 动态(原始值发生变化,import加载的值也会发生变化)只读引用,脚本执行时,去取值
全部的声明都会提高到当前做用域最顶上,
同一个变量只会声明一次,其它会被忽略
函数声明的优先级高于变量声明的优先级,而且函数声明和函数定义的部分一块儿被提高
gulp
- for...in 循环读取键名,for...of 循环读取键值
- for...of 循环须要调用遍历器接口,for...in不须要。对于普通的对象,由于没有遍历器接口,因此不能直接用for...of 遍历对象
- 某些状况下,for。。。in循环会以任意顺序遍历键名
- (补充)for...of 与forEach 对比,for...of 可使用break,continue,return跳出循环
- 通俗地来说,就是把一个元素响应事件(click、keydown......)的函数委托到另外一个元素;通常来说,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到须要绑定的元素上时,会经过事件冒泡机制从而触发它的外层元素的绑定事件上,而后在外层元素上去执行函数。
- 事件委托的实现是利用事件冒泡的机制
- 对于不支持冒泡机制的事件(如focus、blur等),想要使用事件委托,须要利用捕获机制。经过document.addEventListener 将事件模型设置为事件捕获
- 使用 instanceof 操做符
- 使用Array.isArray()
- 使用Object的toString()方法
Object.prototype.toString.call([]); //"[object Array]"
- 建立空对象
- 设置新对象的constructor属性为构造函数的名称,设置新对象的__proto__属性指向构造函数的prototype对象
- 使用新对象调用函数,函数中的this被指向新实例对象中
- 将初始化完毕的新对象地址保存到等号左边的变量中
- 若构造函数中返回this或返回值是基本类型(number、string、boolean、null、undefined、symbol)的值,则返回新对象;若返回值是引用类型的值,则实际返回值为这个引用类型。
- 原理:Web页面上调用js文件时不受是否跨域的影响(不只如此,咱们还发现凡是拥有src这个属性的标签都拥有跨域的能力,好比script、img、iframe、link)
- 实现:容许用户传递一个callback参数给服务端,而后服务端返回数据时会将这个callback参数做为函数名来包裹住JSON数据,这样客户端就能够随意定制本身的函数来自动处理返回数据了
跨域请求在发送前,会判断该请求是简单请求仍是复杂请求。跨域
- 若是是简单请求,浏览器会在请求头增长Origin字段后发送跨域请求。请求发送过去后,服务端通常会在响应头里添加上Access-Control-Allow-Origin 字段,浏览器经过校验该值是不是Origin的值或者是*,来判断是否跨域
- 若是是复杂请求,跨域请求会先发送一个预检请求(携带复杂请求部分信息)来询问服务器是否赞成此次复杂请求。
- 预检请求使用OPTIONS方法,发送Origin、Access-Control-Request-Method、Access-Control-Request-Headers(可选)头部。
- 发送该请求后,服务器能够经过在响应头中携带如下头部
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Max-Age (预检请求的有效期)
- 预检请求结束后,结果将按照响应中指定的时间缓存起来,下次再发送这样的复杂请求时,不会再发送预检请求
- 从外到内,再从内到外,mixins先于组件
- 父组件beforeCreated ->父组件created ->父组件beforeMounted ->子组件beforeCreated ->子组件created ->子组件beforeMounted ->子组件mounted -> 父组件mounted。
- CSS中关于文字排版的属性如:font、word-break、letter-spacing、text-align、text-rendering、word-spacing、white-space 、text-indent、text-transform、text-shadow
- 其余类型的如:line-height、color、visibility、cursor
- offsetWidth/offsetHeight返回值包含content + padding + border,效果与e.getBoundingClientRect()相同
- clientWidth/clientHeight返回值只包含content + padding,若是有滚动条,也不包含滚动条
- scrollWidth/scrollHeight返回值包含content + padding + 溢出内容的尺寸
let a = ?
if (a == 1 && a == 2 && a ==3 ) {
console.log(1)
}
复制代码
在类型不一样时,用==比较会进行隐式类型转换,而在隐式类型转换时会调用toString()或者valueOf()方法,因此咱们能够利用这个特性,定义a为一个对象类型,而且复写这两个方法其中之一就能够达到题目中的效果。
let a = [1, 2, 3] a.valueOf = a.shift // a.toString = a.shift 这个方法也能够 if (a == 1 && a == 2 && a == 3) { console.log(1) } 复制代码
防抖(debounce)
- 概念:指定时间内只执行一次回调函数,若是在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻从新开始计算。
- 用途:好比用户搜索时,当输入中止后再去触发搜索事件
节流(throttle)
- 概念:频繁触发事件时,只会在指定的时间段内执行事件回调,即触发事件间隔大于等于指定的时间才会执行回调函数
- 用途:好比处理浏览器滚动事件
当初始的 HTML 文档被彻底加载和解析完成以后,DOMContentLoaded事件被触发,而无需等待样式表、图像和子框架的完成加载。
window的load事件仅在 DOM 和全部相关资源所有完成加载后才会触发。
JavaScript 解析器将 function foo(){ }();解析成function foo(){ }和();。其中,前者是函数声明;后者(一对括号)是试图调用一个函数,却没有指定名称,所以它会抛出Uncaught SyntaxError: Unexpected token )的错误。 修改方法是:再添加一对括号,形式上有两种:(function foo(){ })()和(function foo(){ }())。以上函数不会暴露到全局做用域,若是不须要在函数内部引用自身,能够省略函数的名称。
每一个元素被表示为一个矩形的盒子,由四部分组成:内容content/内边距padding/边框/border/外边距margin
盒模型有两种:标准盒模型(W3C盒模型)、IE盒模型
区别:标准盒模型内容大小就是content大小,而IE盒模型内容大小则是content+padding+border总的大小
相邻的两个标准流中的块元素,若是它们在垂直方向上设置了外边距,那么外边距会发生重叠,最终的外边距等于发生层叠的外边距中绝对值较大者
解决:触发BFC(Block Formatting Contexts 块级格式化上下文) 一、 body根元素 二、浮动元素:float:除none觉得的值 三、绝对定位元素:position:absolute/fixed 四、display:inline-block/table-cells/flex 五、overflow:除了visible之外的值(hidden/auto/scroll)
做用:都是让元素不可见
区别: display:none会让元素彻底从 render 树中消失,渲染的时候不占据任何空间,子元素不容许覆盖值。 visibility:hidden不会让元素从渲染树 dom 中消失,并且仍是会占据空间,只是内容不可见而已,子元素容许覆盖值(设置visibility:visible;元素可见)。
直接在路由组件内部直接进行定义的
接收参数(to,from,next) 一、 to:router即将进入的路由对象 二、 from:当前导航即将离开的路由 三、 next:,进行管道中的一个钩子,若是执行完了,调用next();不然为false,终止导航。 beforeRouteEnter:进入路由以前执行的函数 beforeRouteUpdate:当前路由改变 beforeRouteLeave:离开路由以前执行的函数
共同点: 1.改变行内元素的呈现方式,display被置为block;2.让元素脱离普通流,不占据空间;3.默认会覆盖到非定位元素上
不一样点: absolute:生成绝对定位的元素,相对于static定位之外的第一个父元素进行定位。 fixed:生成绝对定位的元素,相对于浏览器窗口进行定位。滚动网页,fixed元素与浏览器窗口之间的距离不变。
script - HTML 解析中断,脚本被提取并当即执行。执行结束后,HTML 解析继续。
script async - 脚本的提取、执行的过程与 HTML 解析过程并行,脚本执行完毕可能在 HTML 解析完毕以前。当脚本与页面上其余脚本独立时,可使用async,好比用做页面统计分析。
script defer - 脚本仅提取过程与 HTML 解析过程并行,脚本的执行将在 HTML 解析完毕后进行。若是有多个含defer的脚本,脚本的执行顺序将按照在 document 中出现的位置,从上到下顺序执行。 注意:没有src属性的脚本,async和defer属性会被忽略。
把link标签放在head之间是规范要求的内容。此外,这种作法可让页面逐步呈现,提升了用户体验。将样式表放在文档底部附近,会使许多浏览器(包括 Internet Explorer)不能逐步呈现页面。一些浏览器会阻止渲染,以免在页面样式发生变化时,从新绘制页面中的元素。这种作法能够防止呈现给用户空白的页面或没有样式的内容。把script标签刚好放在body以前脚本在下载和执行期间会阻止 HTML 解析。把script标签放在底部,保证 HTML 首先完成解析,将页面尽早呈现给用户。 例外状况是当你的脚本里包含document.write()时。可是如今,document.write()不推荐使用。同时,将script标签放在底部,意味着浏览器不能开始下载脚本,直到整个文档(document)被解析。也许,对此比较好的作法是,script使用defer属性,放在head中。
浏览器经过优先级规则,判断元素展现哪些样式。优先级经过 4 个维度指标肯定,咱们假定以a、b、c、d命名,分别表明如下含义: a表示是否使用内联样式(inline style)。若是使用,a为 1,不然为 0。 b表示 ID 选择器的数量。 c表示类选择器、属性选择器和伪类选择器数量之和。 d表示标签(类型)选择器和伪元素选择器之和。 优先级的结果并不是经过以上四个值生成一个得分,而是每一个值分开比较。a、b、c、d权重从左到右,依次减少。判断优先级时,从左到右,一一比较,直到比较出最大值,便可中止。因此,若是b的值不一样,那么c和d无论多大,都不会对结果产生影响。好比0,1,0,0的优先级高于0,0,10,10。
优雅的降级:为现代浏览器构建应用,同时确保它在旧版浏览器中正常运行。
渐进式加强:构建基于用户体验的应用,但在浏览器支持时添加新增功能。
利用 caniuse.com 检查特性支持。
使用 autoprefixer 自动生成 CSS 属性前缀。
使用 Modernizr进行特性检测。