-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch_plus_index.json
1 lines (1 loc) · 341 KB
/
search_plus_index.json
1
{"./":{"url":"./","title":"前言","keywords":"","body":"collect-notes 对日常学习的笔记的汇总 访问网址:笔记收纳 深入浅出 Webpack ECMAScript 6 入门 前端工程师手册 计算机网络 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-21 11:16:35 "},"necessary/":{"url":"necessary/","title":"necessary","keywords":"","body":" 页面布局 Flex弹性布局 css盒模型 DOM事件 HTTP协议 原型链 面向对象 通信类 安全类 算法类 算法类笔记 渲染机制-HTML 页面性能类 错误监控 错误笔记 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-08 18:29:44 "},"css/":{"url":"css/","title":"css","keywords":"","body":" 深入理解 CSS 中的行高与基线 16种方法实现水平居中垂直居中 CSS设置居中的方案总结-超全 position 的 static、relative、absolute、fixed、inherit Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-04-22 11:14:45 "},"css/盒子模型.html":{"url":"css/盒子模型.html","title":"盒子模型","keywords":"","body":"盒子模型 一、问题 题目:谈谈你对CSS盒模型的认识 1、基本概念:标准模型+IE模型 2、标准模型和IE模型的区别 3、CSS是如何设置这两种模型 4、js如何设置获取盒模型对应的宽和高 5、实例题(根据盒模型解释边距重叠) 6、BFC(边距重叠解决方案) 二、回答 1.基本概念 盒模型的组成,如下图,由里向外为content,padding、border、margin 盒模型有两种标准:标准模型、IE模型 2.标准模型和IE模型的区别 标准模型:宽高=内容(content) IE模型:宽高=内容(content)+填充(padding)+边框(border) 3.CSS如何设置两种模型 使用css3中的属性box-sizing(浏览器默认的为标准模型) /*标准模型*/ box-sizing:content-box; /*IE模型*/ box-sizing:border-box; 4.CSS如何获取盒模型对应的宽和高 tip:dom表示获取的HTML节点 /*只能获取到内联样式的宽和高*/ 1. dom.style.width/height /*获取渲染以后的宽和高,仅IE支持*/ 2. dom.currentStyle.width/height /*补充2的不足,其余浏览器支持,获取渲染以后的宽和高*/ 3. window.getComputeStyle(dom).width/height /*计算一个元素的绝对位置,在视图以左上角为基点*/ 4.dom.getBoundingClientRect().width/height /*兼容最好的*/ 5.dom.offsetWidth/offetHeight 元素视图属性 offsetWidth 水平方向 width + 左右padding + 左右border-width offsetHeight 垂直方向 height + 上下padding + 上下border-width clientWidth 水平方向 width + 左右padding clientHeight 垂直方向 height + 上下padding offsetTop 获取当前元素到 定位父节点 的top方向的距离 offsetLeft 获取当前元素到 定位父节点 的left方向的距离 scrollWidth 元素内容真实的宽度,内容不超出盒子高度时为盒子的clientWidth scrollHeight 元素内容真实的高度,内容不超出盒子高度时为盒子的clientHeight 元素视图属性结束 Window视图属性(低版本IE浏览器[5.实例题(根据盒模型解释边距重叠) 什么是边距重叠 6.BFC 1)BFC的基本概念 BFC(Block Formatting Context):块级格式化上下文 1)BFC 的原理(渲染规则) 1、在BFC这个元素的垂直反向的边距会发生重叠 2、BFC的区域不会与浮动元素的box重叠 3、BFC在页面山是一个独立的元素,外面的元素不会影响它里面的元素,里面的元素也不会影响外面的元素 4、计算BFC高度的时候,浮动元素也会参与计算 2)如何创建BFC 1、float值不为null 2、position的值为absolute和fixed 3、display属性为inline-block,table-cell,table-caption,flex,inline-flex 4、overflow不为visible 3)应用场景 1、自适应两栏布局 2、清除内部浮动 3、防止垂直margin重叠 4、BFC子元素即使是float也会参与高度计算 参考链接 深入理解CSS盒模型 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-04 11:17:26 "},"css/页面布局.html":{"url":"css/页面布局.html","title":"页面布局","keywords":"","body":"页面布局 code code 一、问题 题目:假设高度已知,请写出三栏布局,其中左栏、右栏宽度各为300px,中间自适应 提醒: 1. float布局 2. 绝对定位 3. flexbox 4. 表格布局 5. 网格布局 二、回答 代码结构,以float为例 *{ margin:0; padding:0; } .layout{ margin-top:20px; } .layout article>div{ min-height:100px; } 浮动解决方案 这是三栏布局中间部分 这是三栏布局中间部分 1.float布局 左 width:300px;float:left;background:red; 中 background:yellow; 右 width:300px;float:right;background:blue; 2.绝对定位 左中右都设置 position:absolute; 左 width:300px;left:0;background:red; 中 left:300px;right:300px;background:yellow; 右 width:300px;right:0;background:blue; 3.flex-box 左中右父类设置 display:flex; 左 width:300px; 中 flex:1;(重点) 右 width:300px; 4.表格布局 左中右父类设置 display:table;width:100%; 左中右都设置 display:table-cell; 左 width:300px;background:red; 中 background:yellow; 右 width:300px;background:blue; 5.网格布局 左中右父类设置 display:grid; width:100%; grid-template-rows:100px; grid-template-columns:300px auto 300px;(重点) 左 background:red; 中 background:yellow; 右 background:blue; 三、延伸与小结 1.延伸 1). 这五种方案各有什么优缺点? float: 缺点:清除浮动,浮动以后会脱离文档里流,处理不当会带来很多问题,本身有一定的局限性; 优点:兼容性比较好,需要处理好周围元素的关系。 绝对定位: 缺点:布局脱离了文档流,意味着下面所有子元素也必须脱离文档流,导致可使用性比较差。 优点:快捷,方便,配合js使用不容易出问题。 flex布局: 缺点:IE8不支持flex 优点:比较完美的方案,解决了上面两个方案的不足。 表格布局: 缺点:历史诟病,当某一个单元格的高度超出之后,两侧的单元格也是要调整高度的; 有时候的场景是不需要同时增高的 优点:轻易做到,兼容性好。 网格布局: 缺点:兼容性问题 优点:可以作很多复杂的事情,简化代码量。 2). 如果把假设高度去掉,考虑纵向,左右内容撑高了,中间也需要撑高,哪些能使用,哪些不能使用? flex和表格布局是可以通用的; float:为什么中间左右内容都超出来了? float的基本原理:它的内容像左浮动的时候,被左侧的块挡住了, 所以它的文案在左边块的右边排的,当内容超出之后,它发现左侧没有遮挡物, 也就没有了float元素,就会向左排;若不想让中间超出部分转到左边,创建BFC 3). 这五种方案的兼容性如何,业务中选出最优的方案? 没有绝对的最优方案,需要根据业务需要来定 2.小结 1. 语义化要到位 2. 页面布局理解深刻 3. css基础知识扎实 4. 思维灵活且积极上进 5. 代码书写规范 3.布局变通思考 1. 三栏布局 左右宽度固定,中间自适应 上下高度固定,中间自适应 2. 两栏布局 左宽度固定,右自适应 右宽度固定,左自适应 山高度固定,下自适应 下高度固定,上自适应 四、思考 1. 如果五种方案,都不设置高度,会是什么样? 2. BFC是什么 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-03 14:15:15 "},"css/Flex弹性布局.html":{"url":"css/Flex弹性布局.html","title":"Flex弹性布局","keywords":"","body":"参考网址 Flex 布局教程:语法篇 Flex 布局教程:实例篇 Flex 布局语法教程-runoob 5分钟学会 CSS Grid 布局 布局的传统解决方案,基于盒状模型,依赖display属性+position属性+float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。 2009年,W3c提出了一种新的方案,flex布局,可以简便,完整,响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很快安全地使用这项功能。 一、Flex布局是什么 Flex是Flexible Box的缩写,意为“弹性布局,用来为盒状模型提供最大的灵活性。” 任何一个容器都可以指定为Flex布局。 .box{ display:flex; } 行内元素也可以使用Flex布局。 .box{ display:inline-flex; } webkit内核的浏览器,必须加上-webkit前缀。 .box{ display:-webkit-flex; display:flex; } 注意: 设为Flex布局以后,子元素的Float、cleat和vertical-align属性将失效。 二、基本概念 采用Flex布局的元素。称为Flex容器(flex container),简称\"容器\"。它的所有子元素自动称为容器成员,称为Flex项目(flex item),简称\"项目\"; 三、容器的属性 以下6个属性设置在容器上。 1. flex-direction 2. flex-wrap 3. flex-flow 4. justify-content 5. align-items 6. align-content 3.1 flex-direction属性 flex-direction属性决定主轴的方向(即项目的排列方向)。 .box{ flex-direction:row|row-reverse|column|column-reverse } 它可能有4个值。 1. row(默认值):主轴为水平方向,起点在左端。 2. row-reverse:主轴为水平方向,起点在右端。 3. column:主轴为垂直方向,起点在上沿。 4. column-reverse:主轴为追至方向,起点在下沿。 3.2 flex-wrap属性 默认情况下,项目都排在一条线上(又称\"轴线\")上,flex-wrap属性定义,如果一条轴线排不下,如何换行。 .box{ flex-wrap:nowrap|wrap|wrap-reverse; } 它可能取3个值。 1. nowrap(默认):不换行。 2. wrap:换行,第一行在上方。 3. wrap-reverse:换行,第一行在下方。 3.3 flex-flow flex-flow属性是flex-direction属性和flex-wrap属性的简写形式。默认值为row nowrap。 .box{ flex-flow:||; } 3.4 justify-content属性 justify-content属性定义了项目在主轴上的对齐方式。 .box{ justify-content:flex-start|flex-end|center|spae-between|space-around; } 它可能取5个值,具体对齐方式与轴的方向有关,下面假设主轴为从左到右。 1. flex-start(默认值):左对齐 2. flex-end:右对齐 3. center:居中 4. space-between:两端对齐,项目之间的间隔都相等 5. sapce-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 3.5 align-items属性 align-items属性定义项目在交叉轴上如何对齐。 .box{ align-items:flex-start|flex-end|center|baseline|stretch; } 它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。 1. flex-satrt:交叉轴的起点对齐。 2. flex-end:交叉轴的终点对齐。 3. center:交叉抽的中点对齐。 4. baseline:项目的第一行文字的基线对齐。 5. stretch(默认值):如果项目未设置高度或设为auto,将沾满整个容器的高度。 3.6 align-content属性 align-content属性定义了多艮轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。 .box{ align-content:flex-start|flex-end|center|spance-between|spance-around|stretch; } 该属性可能取6个值。 1. flex-start:与交叉轴的起点对齐。 2. flex-end:与交叉轴的终点对齐。 3. center:与交叉轴的中点对齐。 4. spance-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 5. space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 6. stretch(默认值):轴线沾满整个交叉轴。 四、项目的属性 以下6个属性设置在项目上。 1. order 2. flex-grow 3. flex-shrink 4. flex-basis 5. flex 6. align-self 4.1 order属性 order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0. .item{ order: } 4.2 flex-grow属性 flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。 .item{ flex-grow: } 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项目多一倍。 4.3 flex-shrink属性 flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足。该项目将缩小。 .item{ flex-shrink:; } 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小,如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。 4.4 flex-basis属性 flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,技术主轴是否有多余空间,它的默认值为auto,即项目的本来大小 .item{ flex-basis:|auto; } 它可以设为跟width或height属性一样的值(比如350px)则项目将占据固定空间。 4.5 flex属性 flex属性是flex-grow,flex-shrink和flex-basis的简写,默认值为0,1,auto。后两个属性可选 .item{ flex:none|[?||] } 该属性有两个快捷值:auto(1,1, auto)和none(0 0 auto)。 建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。 4.6 align-self属性 align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属相。默认值为auto,表示继承父元素的align-item属性,如果没有父元素,则等同于stretch item{ align-self:auto|flex-start|flex-end|center|baseline|stretch } 该属性可能取6个值,除了auto,其他都与align-items属性完全一致。 五、总结 code flex code grid code Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-04 14:17:43 "},"css/CSS设置居中的方案总结.html":{"url":"css/CSS设置居中的方案总结.html","title":"CSS设置居中的方案总结","keywords":"","body":"总结 参考: 16种方法实现水平居中垂直居中 CSS设置居中的方案总结-超全 水平居中 text-align:center; margin:0 auto; with:fit-content; flex 盒模型 transform 8两种不同的绝对定位方法 垂直居中 行内元素(单行文字垂直居中):设置 line-height = height 块级元素:绝对定位+margin:-(高度的一半) 块级元素:绝对定位+transform 块级元素:绝对定位+margin:auto 块级元素:padding 块级元素:dispaly:table-cell 块级元素:display:felx 块级元素:伪元素 块级元素:calc() 块级元素:inlie-block 我们发现,flex,盒模型,transform,绝对定位,这几种同时适用于水平居中和垂直居中 块级元素居中html代码部分 child 行内元素居中html代码部分 水平居中 1 行内元素 text-align:center; .parent{ text-align:center; } 2 块级元素width:xx; margin:0 auto; .child{ width:100px; margin:0 auto; } 或者设置父元素 text-aligm:center; .parent{ text-align:center } 3 若子元素包含float:left属性,为了让子元素水平居中,则可让父元素宽度设置fit-content,并且配合margin,作如下设置: .parent{ width: -moz-fit-content; width: -webkit-fit-content; width:fit-content; margin:0 auto; } .child{ float:left; } fit-content是css3中给width属性新加的一个属性值,它配合margin可以轻松实现水平居中,目前只支持Chrome和Firefox浏览器。 4 使用flex布局,可以轻松的实现水平居中,子元素设置如下: .child{ display:flex; justify-content:center; } 5 使用flex 2009年版本, 父元素display: box;box-pack: center;如下设置: .parent{ display: -webkit-box; -webkit-box-orient: horizontal; -webkit-box-pack: center; display: -moz-box; -moz-box-orient: horizontal; -moz-box-pack: center; display: -o-box; -o-box-orient: horizontal; -o-box-pack: center; display: -ms-box; -ms-box-orient: horizontal; -ms-box-pack: center; display: box; box-orient: horizontal; box-pack: center; } 6 使用css3中新增的transform属性,设置如下 .parent{ position:relative; } .child{ position:absolute; left:50%; transform:translate(-50%,0); } absolute生成绝对定位的元素,相对于static定位以外的第一个父元素进行定位。 7 使用绝对定位方式,以及负值的margin-lfet,设置如下: .parent{ position:relative; } .child{ position:absolute; width:固定; left:50%; margin-left:-0.5宽度; } 8 使用绝对定位方式,以及left:0;right:0;margin:0 auto;设置如下: .child{ position:absolute; width:固定; left:0; right:0; margin: 0 auto; } 垂直居中 1 行内元素(单行文字垂直居中) .parent{ height:200px; line-height:200px; border:1px solid pink; } 2 块级元素:绝对定位(需要提前知道尺寸) 优点:兼容性不错缺点:需要提前知道尺寸,margin-top:-(高度的一半);margin-left:-(宽度的一般);父元素空间不够时, 子元素可能不可见(当浏览器窗口缩小时,滚动条不出现时).如果子元素设置了overflow:auto, 则高度不够时, 会出现滚动条 .parnet{ position:relative; height:200px; border:1px solid pink; } .child{ width:80px; height:40px; position:absolute; left:50%; top:50%; margin-top:-20px; margin-left:-40px; border:1px solid blue; } 3 块级元素:绝对定位+transform 优点:不需要提前知道尺寸,代码量少缺点:兼容性不好,IE8不支持, 属性需要追加浏览器厂商前缀, 可能干扰其他 transform 效果, 某些情形下会出现文本或元素边界渲染模糊的现象. .parent{ postion:relative; height:200px; border:1px solid pink; } .child{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); border:1px solid blue } 4 块级元素:绝对定位+margin:auto; 优点:兼容性好缺点:需要知道尺寸,或者不设置尺寸(需要是图片这种自身包含尺寸的元素),都是居中显示的。没有足够空间时, 子元素会被截断, 但不会有滚动条. .parent{ postion:relative; height:200px; border:1px solid pink; } .child{ position:absolute; left:0; top:0; right:0; bottom:0; margin:auto; border:1px solid blue } 5 块级元素:padiing 缺点:如果高度固定,需要提前计算尺寸 .parent{ padding:5% 0; } .child{ padding:10% 0; } 6 块级元素:display:table-cell .parent{ width:600px; height:200px; border:1px solid pink; display:table; } .child{ display: table-cell; vertical-align: middle; text-align: center; } 或 .parent{ height: 300px; width: 600px; border: 1px solid red; display: table-cell; vertical-align: middle; text-align: center; } 同样适用于多行文字居中 .parent { width: 400px; height: 300px; display: table-cell; vertical-align: middle; border: 1px solid red; } .child { display: inline-block; vertical-align: middle; background: blue; } 7 块级元素:display:flex 优点:1.内容块的宽高任意, 优雅的溢出.2.可用于更复杂高级的布局技术中. 缺点:兼容性不好 .parent{ width: 600px; height: 200px; border: 1px solid red; display: flex; align-items: center; justify-content: center; /*水平居中*/ } 8 块级元素:伪元素 .parent { width: 300px; height: 300px; border: 1px solid red; text-align: center; } .child { background: blue; width: 100px; height: 40px; display: inline-block; vertical-align: middle; } .parent::before { content: ''; height: 100%; display: inline-block; vertical-align: middle; } 9 块级元素:calc() .parent { width: 300px; height: 300px; border: 1px solid red; position: relative; } .child { width: 100px; height: 100px; background: blue; padding: -webkit-calc((100% - 100px) / 2); padding: -moz-calc((100% - 100px) / 2); padding: -ms-calc((100% - 100px) / 2); padding: calc((100% - 100px) / 2); background-clip: content-box; } 10 块级元素:inline-block html代码: child brother css代码: .parent { width: 400px; height: 400px; border: 1px solid red; position: relative; } .child, .brother { display: inline-block; vertical-align: middle; } .child { background: blue; font-size: 12px; } .brother { height: 400px; font-size: 0; } Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-04-22 15:52:55 "},"css/常见的兼容性问题.html":{"url":"css/常见的兼容性问题.html","title":"常见的兼容性问题","keywords":"","body":"png24位的图片在iE6浏览器上出现背景,解决方案是做成PNG8.也可以引用一段脚本处理. 浏览器默认的margin和padding不同。解决方案是加一个全局的*{margin:0;padding:0;}来统一。 IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。 浮动ie产生的双倍距离(IE6双边距问题:在IE6下,如果对元素设置了浮动,同时又设置了margin-left或margin-right,margin值会加倍。) box{ float:left; width:10px; margin:0 0 0 100px;} 这种情况之下IE会产生20px的距离,解决方案是在float的标签样式控制中加入 display:inline;将其转化为行内属性。(这个符号只有ie6会识别) 渐进识别的方式,从总体中逐渐排除局部。 首先,巧妙的使用“\\9”这一标记,将IE游览器从所有情况中分离出来。 接着,再次使用“+”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。 css .bb{ background-color:#f1ee18;/*所有识别*/ .background-color:#00deff\\9; /*IE6、7、8识别*/ +background-color:#a200ff;/*IE6、7识别*/ _background-color:#1e0bd1;/*IE6识别*/ } 怪异模式问题:漏写DTD声明,Firefox仍然会按照标准模式来解析网页,但在IE中会触发 怪异模式。为避免怪异模式给我们带来不必要的麻烦,最好养成书写DTD声明的好习惯。现在 可以使用html5推荐的写法: 上下margin重合问题 ie和ff都存在,相邻的两个div的margin-left和margin-right不会重合,但是margin-top和mragin-bottom却会发生重合。 解决办法,养成良好的代码编写习惯,同时采用margin-top或者同时采用margin-bottom Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:19:55 "},"css/清除与浮动.html":{"url":"css/清除与浮动.html","title":"清除与浮动","keywords":"","body":"浮动的框可以向左或向右移动,知道他的外边缘碰到包含框或零个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流的块框表现得就像浮动框不存在一样。浮动框的块框会漂浮在文档普通流的块框下上 浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。 使用空标签清除浮动。 这种方法是在所有浮动标签后面添加一个空标签,定义css clear:both,弊端是增增加了无异议标签 使用overflow. 给包含浮动元素的父标签添加css属性 overflow:auto,zoom:1;zoom:1用于兼容IE6 使用after伪对象清除浮动。 该方法只适用于非IE浏览器。具体方法可参照以下示例。使用中需要注意以下几点。一、该方法中必须为需要清除浮动的伪对象中设置height:0,否则该元素会比实际高出若干像素; 浮动元素引起的问题和解决方法? 浮动元素引起的问题: 父元素的高度无法被撑开,影响与父元素同级的元素 与浮动元素同级的非浮动元素(内联元素)会跟随其后 若非第一个与元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构。 解决方法 使用css中的clear:both;属性来清除元素的浮动可解决2.3问题,对于问题1,添加如下样式,给父元素添加clearfix样式: .clearfix:after{content:\".\";display:block;height:0;clear:both;visibility:hidden;} .clearfix{display:inline-block;}/*for IE/Mac*/ 清除浮动的几种方法: 1,额外标签法,(缺点:不过这个办法会增加额外的标签使HTML结构看起来不够简洁。) 2,使用after伪类 #parent:after{ content:\".\"; height:0; visibility:hidden; display:block; clear:both; } 3,浮动外部元素 4,设置overflow为hidden或者auto Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-05-07 15:17:34 "},"css/position的值,relative和absolute分别是相对于谁进行定位的?.html":{"url":"css/position的值,relative和absolute分别是相对于谁进行定位的?.html","title":"position的值,relative和absolute分别是相对于谁进行定位的?","keywords":"","body":"position 有六个值:static、relative、absolute、fixed、inherit,sticky absolute:生成绝对定位的元素,相对于最近一级的定位不是static的元素进行定位。 脱离了布局流,此时可以使用top,right,bottom,left但这些属性不再是相对于static时的位置,而是相对于content-box,相对其边框内边缘的,而不是其padding内边缘 fixed:(老IE不支持)生成绝对定位的元素,通常相对于浏览器窗口或frame进行定位。 它的模式与absolute相同,不过无论怎么拖动滚动条,它始终固定在屏幕的指定位置。在IE6中不支持这个属性;在IE7中支持这个属性,但需要指明DOCTYPE;top,right,bottom,left属性指相对于视口的。 relative:生成相对定位的元素,相对于其在普通流中的位置进行定位。 没有脱离布局流,此时可以使用top,right,bottom,left属性 top和bottom共存时,使用top值,忽略bottom值; left和right共存时,使用left值,忽略right值; release是相对位置,指相对于元素的positionw位static时的位置: ``` top相对于static下移多少像素(若top是负值,则上移)。 right相对于static左移多少像素(若right是负值,则右移)。 bottom相对于static上移多少像素(若bottom是负值,则下移)。 left 相对于static右移多少像素(若left是负值,则左移) > 使用relative之后 原来的空间不会被其他元素挤占 元素在最终位置时也不会挤占其他元素的空间,它浮动到其他元素的上方。 ``` static:默认值。没有定位,元素出现在正常的流中, 就是按正常的布局流从上到下从左到右布局,平常我们做网页时,没有指定position,也就表示使用static sticky:生成粘性定位的元素,容器的位置根据正常文档流计算得出。 inherit:继承父元素的position值 参考网址:position 的 static、relative、absolute、fixed、inherit Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:32:42 "},"css/移动端性能优化.html":{"url":"css/移动端性能优化.html","title":"移动端性能优化","keywords":"","body":" 尽量使用css3动画,开启硬件加速。 适当使用touch事件代替click事件。 避免使用css3渐变阴影效果。 可以用transform:translateZ(0)来开启硬件加速。 不可滥用Float。Float在渲染时计算量比较大,尽量减少使用 不滥用Web字体。Web字体需要下载,解析,重绘当前页面,尽量减少使用。 合理使用requestAnimationFrame动画代替setTimeout css中的属性(CSS3 transitions,CSS3 3D transforms,Opactity,Canvas,WebGL,Video)会触发GPU渲染,请合理使用。过渡使用会引发手机耗电增加 PC端的在移动端同样适用 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-21 10:46:47 "},"js/":{"url":"js/","title":"js","keywords":"","body":"js 描述 JavaScript 教程_阮一峰 ECMAScript 6 入门_阮一峰 深入浅出webpack 深入理解javascript原型和闭包系列 这一次,彻底弄懂 JavaScript 执行机制 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-03-29 15:32:40 "},"js/基本概念.html":{"url":"js/基本概念.html","title":"基本概念","keywords":"","body":"单线程是JavaScript语言的一大特点,也就是在同一时间只能做一件事。所谓同步,愿意就是程序的执行顺序与书写顺序保持一致;而异步,指的是程序并非按照书写的顺序来执行,会存在“跳过”执行的现象。 谈及JS异步,就不得不提两个改变执行顺序的基础函数:setTimeout和setInterval函数。这两个函数在执行时会被压入事件循环队列当中,在当前作用域下的所有程序都执行完成后,才会开始执行排在事件循环队列当中的函数,所以这两个函数能够改变程序的执行顺序。例如 function test(){ console.log(1); setTimeout(function(){ console.log(2) },0); setTimeout(function(){ console.log(3) },100); setTimeout(function(){ console.log(4); },99); console.log(5); } test();//15243 栈和队列和堆的区别 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。 队列先进先出,栈先进后出 栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删除 栈区(stack) 由编译器自动分配释放,存放函数的参数值,局部变量的值等。 堆区(heap) 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。 堆(数据结构):堆可以被看成是一棵树,如:堆排序 栈(数据结构):一种先进后出的数据结构。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:38:54 "},"js/正则匹配.html":{"url":"js/正则匹配.html","title":"正则匹配","keywords":"","body":" 正则表达式是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。这些模式被用于RegExp的exec和test方法,以及string的match、replace、search和split方法。 1.创建正则表达式(以下有两种方式来参考): (1)使用正则表达式的构造函数(new的方式来创建) let regex=new RegExp(\"a\"); let regex=new RegExp(\"^[a-zA-Z]\",\"g\");//当使用引号时不必再加反斜杠‘/’ let regex=new RegExp(/^[a-zA-Z]/,'gi');//当有斜杠时就不用再加引号 (2)创建字面量(由两个反斜杠'//'包裹需要匹配的内容) let regex=/ab/; let regex=/^[a-zA-z]/; 这两种方式都可以用来创建一个正则表达式,但是相对来说第二种方式更加常用一些。 2.正则表达式的参数,写在//后面,可混合使用 g 全局匹配;找到所有匹配,而不是在第一个匹配后停止 i 匹配全部大小 m 多行;将开始和结束符(^和$)视为在多行上工作(也就是,分别每一行的开始和结束(由\\n或\\r分割),而不只是匹配整个输入字符串的最开始和最末尾处。 s和m相反,单行匹配let regex=/^[a-zA-Z]/gim 3.正则中常用方法以及字符串中与正则相关的方法 (1) test()方法检索字符串中的值是否匹配给出的正则规则,返回布尔值true或false。 检查“ab”是否匹配前面的正则表达式/../,正确返回true,不匹配返回false /../.test(\"ab\");//true (2)exec()方法检索字符串中的整定值,如果找到匹配的文本,则返回一个结果的数组,反之返回null。 检索正则表达式/abc/是否有在字符串defaabc有匹配到,返回匹配到内容,索引值,以及检索的字符串。 /a/.exec(\"defaabc\");//[\"abc\", index: 4, input: \"defaabc\"] 检索/qqq/是否在abcdefaabcz中匹配,返回null /qqq/.exec(\"abcdefaabc\");//null (3)compile()方法用于改变正则匹配内容 将/abc/的匹配内容改成后面的字符串的内容 /abc/.compile('def');// /def/ (4)split()将字符串分隔成字符串数组 将字符串abc以/b/中的b分隔成字符串数组 \"abcd\".split(/b/); //[\"a\",\"cd\"] (5)replace()方法用于在字符串中用一些字符替换另一些字符或者替换一个与正则表达式匹配的字符串 用正则内容/\\d\\d\\d/去匹配字符串12345abcde,将匹配的内容替换成*,并返回替换完成的字符串 '12345abcde'.replace(/\\d\\d\\d/g,'*');//*45abcde 去掉字符串的引号,全局索引',替换成''空 '12345abcde'.replace(/'/g,'');//12345abcde 去掉字符串中所有的空格,tab,换行符,换页符 ' 12 345ab cd e'.replace(/\\s/g,'');//12345abcde (6)search()用于检索字符串中指定的字符串与正则表达式匹配的字符串,返回匹配的字符串的起始位置的索引,反之返回-1 'abcdedfsdfs'.search(/d/);//3 即使是全局匹配,也只会匹配到第一个的位置 'abcdedfasdfs'.search(/d/g); // 3 如果没有匹配到,返回-1 'abcdedfasdfs'.search(/o/g); //-1 (7)match()方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配 检索指定的值,并返回,b+指多个 \"aabbbccbbaab\".match(/b+/g); // [\"bbb\", \"bb\", \"b\"] Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:19:14 "},"js/BOM.html":{"url":"js/BOM.html","title":"BOM","keywords":"","body":"浏览器对象模型(brower object model)是用于和浏览器窗口进行交互的对象,也可用于窗口与窗口之间的通信。它的核心对象是window,在window对象当中也提供了很多其他对象属性用于操作和管理浏览器的各个部分。常用的window对象属性有: location对象:表示该窗口中当前显示的文档的URL。history独享:用于将窗口的历史浏览记录用文档和文档状态列表的形式表示。navidator:该对象包含了浏览器厂商和版本信息。Screen对象:它提供了有关窗口显示大小和可用的颜色数量信息 常用的对话框也属于挂在在window对象上的方法:alert();confirm();prompt(); Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:48:09 "},"js/DOM事件.html":{"url":"js/DOM事件.html","title":"DOM-DOM事件","keywords":"","body":"DMO 事件 一、问题 基本概念:DOM事件的级别 DOM事件模型(冒泡补货) DOM事件流(页面中接受事件的顺序) 描述DOM事件捕获的具体流程 Event对象的常见应用 Dom操作方法 什么是事件代理 attribute和property的区别是什么? document.write()的用法 二、回答 1.基本概念:DOM事件的级别 DOM事件事件类 DOM1标准指定的时候没有涉及任何和事件相关的东西; 事件级别 DOM0 element.onclick=function(){}; //ture,false指定是冒泡还是捕获,默认为false,为冒泡 //IE attachEvent DOM2 element.addEventListener('click',function(){},false); //事件类型增加了很多; DOM3 element.addEventListener('keyup',function(){},false); 2.DOM事件模型 捕获(从上往下) 冒泡(从目标元素往上) 3.DOM事件流(页面中接受事件的顺序) 浏览器在为当前页面与用户做交互的过程中,比如点击了鼠标左键,这个左键是怎么传动到你的页面上,又怎么响应的。 1.捕获阶段 2.目标阶段 事件通过捕获到达目标元素 3.冒泡阶段 从目标元素上传到Window对象 4.描述DOM事件捕获的具体流程 第一个接受事件的对象是window; 取得body标签:document.body; 表示html节点:document.documentElement; 捕获流程:window-->document-->html标签-->body-->父级元素-->子级元素...-->目标元素。 冒泡流程;从目标元素一层一层最后到window完成一次冒泡的流程; 5.Event对象的常见应用 1.event.preventDefault();阻止默认行为 a标签绑定了click事件,在响应函数中设置了preventDefault,就阻止了链接默认跳转的行为。 2.event.stopPropagation();阻止冒泡 父级元素、子元素都绑定有事件,单击子元素做一件事,单击父元素在做一件事;如果不阻止冒泡,单击子元素的范围的时候,根据冒泡的原理,父级元素也会被响应; 3.event.stopImmediatePropagation();事件响应优先级 一个按钮绑定了两个click事件1和2,想通过优先级的方式,第一个响应函数是a。第二个响应函数是b,依次注册了a,b两个事件。想让执行a之后完不再执行b了;a响应函数中加上上面代码,就能成功阻止b执行。 4.event.currentTarget(currentTarget当前绑定事件的对象,指向添加监听事件的对象) 把子元素的事件代理都转移到父元素中,只绑定一次事件就可以了。做响应的时候就要区分是哪个元素被触发。 5.event.target(target是当前被点击的元素,指向触发事件监听的对象。) 6.自定义事件或者模拟事件(重要) eg:有一个按钮,增加一个事件,在别的地方触发这个事件,而不是用回调的方式处理; 1.var eve=new Event('custom'); //通过new Event声明了一个自定义事件,把eve这个事件当做普通事件对象,只不过这个事件是你定义的 2.ev.addEventListener('custom',function(){ console.log('hello custom'); });//ev是一个dom节点,通过dom2这种事件注册的方式绑定这个事件名称; 3. ev.dispatchEvent(eve);//最后触发就是用的这个dom节点,dispatchEvent这个api触发eve这个对象。 总结: Event的不足只能指定事件名,如果想要给这个事件加些数据,Event是做不到的;用customEvent; customEvent自定义事件的是一个方法;除了可以指定事件名,后边还可以跟一个object来做指定参数。这个参数是自定义的,所以用法是一样的。 6. Dom操作方法 文档对象模型(document object model)是用来表示和操作HTML和XML文档内容的基础API。Document类型代表了一个HTML或XML文档,document对象则是用来保存整个web页面的dom结构,在页面上所有的元素最终都会映射为一个dom对象。对页面节点的操作也是通过document对象中的方法来实现的。 document对象中常用的Dom操作方法有 getElementById(); getElementsByClassName() querySlector(); getAttribute() 创建新节点 createDocumentFragment()//创建一个DOM片段 createElement()//创建 createTextNode()//创建一个文本节点 添加、移除、替换、插入 appendChild() removeChild() replaceChild() insertBefore()//并没有insertAfter 查找 getElementsByTagName()//通过标签名称 getElementsByName()//通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name的值) getElementById()//通过元素Id,唯一性 7. 什么是事件代理 事件代理(EVent Delegation)又称之为事件委托。是JavaScript中常用绑定事件的技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素。让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。 8. attribute和property的区别是什么? property就是dom元素在js中作为对象拥有的属性。 所以 对于html的标准属性来说,attribute和property是同步的,是会自动更新的。 但是对于自定义的属性来说,他们是不同步的。 9. document.write()的用法 document.write()方法可以用在两个方面:页面载入过程中用实时脚本创建页面内容,以及用延时脚本创建窗口或新窗口的内容。 document.write只能重绘整个页面,innerHTMl可以只重绘页面的一部分。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-05 18:29:42 "},"js/原型、原型链.html":{"url":"js/原型、原型链.html","title":"原型、原型链","keywords":"","body":"参考网址 一篇文章看懂proto和prototype的关系及区别 JavaScript核心概念归纳整理 深入理解JavaScript原型和闭包系列 关联网址 个人笔记 图 关键概念 js在创建对象的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype 原型链的顶端是Object.prototype.proto,也即为null。 访问一个对象的原型属性时,现在基本属性中查找,如果没有,再沿着proto这条链向上找,这就是原型链。 主要内容 在JavaScript中,每一个对象都会和另一个对象产生关联,从另一个对象上继承属性,这里所指的另一个对象就是我们耳熟能详的原型。原型本身也是一个对象,其他对象可以通过它实现属性的继承,也可以将任何一个对象作为自身对象的原型。JS中的任何对象都有原型,除了原型链顶端的对象:Object.prototype 所谓原型链,就是由对象原型所构成的访问链,我称之为“原型继承链”。一个JS对象的原型指向其父类对象,而父类的原型又指向父类对象的父类对象,这种通过原型层层连接起来的关系就是原型链。 以下是几种获取原型对象的方法: var a={}; Object.getPrototypeOf(a); a.__proto__ a.constructor.prototype; 在所有实现中都无法访问到[[prototype]],但是可以通过一些方法来确认对象之间是否存在这种关系 instanceof,这个操作符只能处理对象person1和函数(带.prototype引用的Person)之间的关系 person1 instanceof Person//true isPrototypeOf,如果[[prototype]]指向调用此方法的对象,那么这个方法就会返回true Person.prototype.isPrototypeOf(person1)//true Person.prototype.isPrototypeOf(person2)//true Object.getPrototypeOf这个方法返回[[prototype]]的值,可以获取到一个对象的原型 Object.getPrototypeOf(person1)===Person.prototype//true 如何检测一个属性存在于实例中,还是原型中 hasOwnProperty 使用方法hasOwnProperty,属性只有存在于实例中才会返回true function Person(){ } var person1= new Person(); //实例属性 person1.name=\"J\"; person1.hasOwnProperty('name')//true 获取属性 in 操作符 前面提到hasOwnProperty方法可用于检测属性是否是实例属性,in则会遍历所有属性,不管是实例上的,还是原型上的 in操作符有两种使用方式,单独使用和在for-in循环中使用,先上基础代码 function Person(){ } Person.prototype.age='100'; var person1=new Person(); person1.name=\"J\"; 单独使用 'name' in person1//true 'age' in person1 //true person1.hasOwnproperty('age')//false for-in,会遍历所有能够通过对象访问的,可枚举的(enumerated)属性,不管是实例上还是原型上 for(var prop in person1){ console.log(prop)//name age } Object.keys()此方法可以获取对象的所有可枚举属性的名字 var keys=Object.keys(person1) console.log(keys);//[\"name\"] var keys=Object.keys(Person.prototype) console.log(keys)//[\"age\"]; Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:32:58 "},"js/原型链.html":{"url":"js/原型链.html","title":"原型链","keywords":"","body":"原型链 资料 深入理解javascript原型和闭包(完结)--王福朋 一篇文章看懂proto和prototype的关系及区别 一、提问 1.创建对象有几种方法 2.原型、构造函数、对象实例、原型链 3.instanceof的原理 4.new运算符 二、回答 1.创建对象有几种方法 1.从结果上来看这两种算是一类,写法不一样 var o1={name:\"o1\"};//字面量对象--默认这个对象原型链指向Object var o2=new Object({name:\"o2\"});//通过new Object声明的一个对象 2.使用显示构造函数创建对象(通过构造函数) var M=function(name){this.name=name;}; var o3=new M(\"o3\"); 3.Object.create方法创建 //创建一个具有指定原型可选择性地包含指定属性的对象 var P={name:\"p\"}; //Object.create方法是把参数中这个对象作为一个新对象的原型对象赋值给o4de o4本身不具备这个属性,通过原型链来连接这个原型对象的。 所以喔o4对象本身没有name这个属性,只能通过原型链来找name属性。 var o4=Object.create(P); o4.__proto__指向的就是p对象 o4.__proto__===p;//true o4创建出来是一个空对象,空对象本身没有name这个属性,它是在它的原型对象上。 ------>console o1 {name: \"o1\"} o2 {name: \"o2\"} o3 M {name: \"o3\"} o4 {} Object.create方法创建的这个对象,是用原型链来连接的; 2.原型、构造函数、对象实例、原型链 1.实例 只要是对象就是一个实例; 2.构造函数: 凡是通过new来操作的后边的这个函数,这个函数就是构造函数; (任何一个函数只要被new使用了,后面这个函数就可以被叫做构造函数。) 构造函数可以使用new运算符来生成一个实例;构造函数也是函数; 任何函数都可以用来当做构造函数,只要用new操作,立马就变成构造函数; 不用new就是普通函数。 3.原型对象 函数都有一个prototype属性,在声明一个函数时js自动加上去的属性,这个prototyp指的就是原型对象; 在声明一个函数,开始写function xx,js引擎给这个函数自动增加一个属性, 这个属性就是构造函数prototype属性,这个属性会初始化一个空对象,也就是这个原型对象。 3.1 原型对象怎么区分是被那个构造函数所引用呢? constructor构造器 原型对象中会有一个构造器,这个构造器会默认你声明的那个函数。 eg:var M=fucntion(name){this.name=name;}; var o3=new M('o3'); M是构造函数,o3是实例 M.prototype(原型对象) 是一个空对象,(原型对象)有construct属性,这个属性指向了一个函数,这个函数就是构造函数。 M.prototype.constructor===M;//true 1.构造函数通过new和实例关联; 2.构造函数的原型对象通过construct和构造函数关联; 3.实例和原型对象是一个什么关系?实例对象的__proto__这个属性引用的是M的原型对象; o3.__proto__===M.prototype;//true 4.原型链 从一个实例对象往上找,构造这个实例的相关联的对象,然后这个关联对象再往上找, 又有创建它的上一级的原型对象,以此类推,一直到Object.prototype原型对象终止, 这个链条就断了,也就是说Object.prototype属性是整个原型链的顶端,到那里就截止了 4.1.1原型链是通过什么来实现这个往上找的过程呢? 通过prototype这个原型和__proto__属性来完成原型链的查找的。 4.1.2原型对象和原型链之间起什么作用? eg:构造函数中增加了很多属性和方法,实例是不是就可以共用这个东西了? 当多个实例的时候,想去共用这个方法的时候,不能每个实例都copy一份, 他们有相同的方法,可以存到一个共同的东西上,共同的东西就是原型对象。 eg:var M=function(name){this.name=name;}; var o3=new M('o3'); 如果this.name下面写this.say=function(){}方法, 这样每个实例把这个东西都copy一份,占内存,没必要; 4.2.1原型链的功能 通过在M的原型链上(原型对象上)增加方法以后, 通过原型链的方式使这个对象可以找到这个原型对象的方法,实例也是可以拥有的, 这就是js引擎做的原型链的基本功能; 4.2.2原型的基本原理 任何一个实例对象通过原型链找到它上面的原型对象,上面的方法和属性都是被实例所共享的。 eg:M.prototype.say=function(){ console.log(\"say hello world\"); }; var o5=new M(\"o5\"); 4.2.3原型链的工作原理;通过原型链的方式,找到原型对象,原型对象的方法是被不同实例所共享的。 按照js引擎分析的方式,在访问一个实例的时候,这个实例上有什么方法, 在这个实例本身没找到的这个方法和属性,它会往它的原型对象上找, 通过__proto__上一级原型原型对象去找,如果它上一级对象还没有找到这个属性和方法, 它会在它原型对象的基础上,在通过原型对象的__proto__,在往上一级查找,以此类推, 直到找到Object.prototype,如果还没找到,原路返回,告诉它这个属性和方法没有找到,没有定义; 如果在某一环节找到了,就会停止向上查找,直接返回这个方法; 4.3实例是构造函数生成的,它怎么跟这个原型对象产生关联呢? 构造函数的prototype这个属性,修改这个属性,也就修改了实例所在上一级的原型对象。 3.instanceof的原理 实例对象上有__proto__这个属性,实例对象的这个属性引用是它构造函数的原型对象(也就是找到这个构造函数); 构造函数有prototype这个属性,这个属性引用的原型对象,在往下走,实例对象的__proto__这个属性, 其实是引用这个原型对象 虽然实例对象是一个构造函数产生的,但是这个属性(实例对象的__proto__属性)和构造函数本身没有关联, 它关联的是构造函数下面的一个属性prototype所引用的原型对象。 原理:就是来判断实例对象的__proto__这个属性和构造函数的prototype曾属性是不是同一个引用。 实例对象.__proto__ instanceof 构造函数的prototype; 判断这个实例对象是不是这个构造函数的实例的时候, 其实判断的是实例对象下面的属性__proto__与构造函数下的属性prototype是不是引用的同一个地址; 如果是,instanceof成立返回了true,如果不是返回false; o3 instanceof M;//true O3 instanceof Object;//true //只要是在原型链上的构造函数都会被instanceof看成o3的一个构造函数; o3.__proto__==M.prototype;//true M.prototype.__proto__=Object.prototype;//true (原型对象的__proto__指向的是Object的prototype,Object这个构造函数也会被instanceof看做是o3的一个构造函数) o3.__proto__.construtor=M//true o3.__proto__.construtor=Object//false //用constructot判断比用instanceof更严谨 construct来判断一个实例对象从严谨意义上是不是构造函数直接生成的实例对象, 是用原型对象的construct来构造,实例对象和构造函数是一个桥梁关系, 但construct是放在prototype下的construct属性来判断的。 4.new运算符 1.一个新对象被创建,它继承自(这个构造函数的原型对象)foo.prototyoe 2.构造函数foo被执行,执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例,new foo等同于new foo(),只能用在不传任何参数的情况 3.如果构造函数返回了一个对象,那么这个对象会取代这个new 出来的结果,如果构造函数没有返回对象, 那么new出来的结果为步骤1创建的对象,(一般情况下构造函数不返回返回值,不过用户如果想覆盖这个返回值, 可以自己返回一个普通对象来覆盖,当然,返回数组也会覆盖,因为数组也是对象) eg: var M=function(name){ this.name=name; }; M.prototype.say=function(){ console.log('hello world'); } var o5=new M('o5'); var new2=function(func){ //1.创建一个空对象,这个对象要继承这个构造函数的原型对象(空对象要关联构造函数的原型对象。) var o=Object.create(func.prototype); //var o={}; //o.__proto__=func.prototype; //2.执行构造函数 var k=func.call(o);//call用来转移上下文(this),把这个上下文转成o对象 //3.判断构造函数的运行结果是不是对象类型 if(typeof k=='object'){ return k; }else{ return o; } }; Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-05 15:29:43 "},"js/原型链_图.html":{"url":"js/原型链_图.html","title":"原型链_图","keywords":"","body":"参考网址 一篇文章看懂proto和prototype的关系及区别 Object.proto==Function.prototype f1.__proto__==Foo.prototype; Foo.prototype.constructor==Foo; Foo.prototype.__proto__==Object.prototype; Foo.__proto__==Function.prototype; o1.__proto__==Object.prototype; Object.prototype.constructor==Object; Object.prototype.__proto__==null; Object.__proto__=Function.prototype; Funciton.prototype.constructor==Function; Function.prototype.__proto__==Object.prototype; Function.__proto__==Function.prototype; Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:31:33 "},"js/JavaScript六种继承方式.html":{"url":"js/JavaScript六种继承方式.html","title":"JavaScript六中继承方式","keywords":"","body":"六种继承方式 原型链 借用构造函数 组合继承(原型链+构造函数) 最常用 原型式继承 寄生式继承 寄生组合式继承 参考网址 JavaScript六种继承方式 JavaScript继承方式详解 继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的 1.原型链 原型链继承基本思想就是让一个原型对象指向另一个类型的实例 function Parent(){ this.property=true; } Parent.prototype.getParentValue=function(){ return this.property; } function Child(){ this.Childproperty=false; } Child.prototype=new Parent(); Child.prototype.getChildValue=function(){ return this.Childproperty; } var instance=new Child(); console.log(instance.getParentValue)//true; 代码定义了两个类型Parent和Child,每个类型分别由一个属性和一个方法,Child继承了Parent,而继承是通过创建Parent的实例,并将该实例赋给Child.prototype实现的。 实现的本质是重写原型对象,代之以一个新类型的实例,那么存在Parent的实例中的所有属性和方法,现在也存在于Child.prototype中了 我们知道,在创建一个实例的时候,实例对象中会有一个内部指针指向创建它的原型,进行关联起来,在这里代码Child.prptotype=new Parent(),也会在Child.prototype创建一个内部指针,将Child.prototype与Parent关联起来 所以instance指向Child的原型,Child的原型有指向Parent的原型,继而在instance在调用getParentVlaue()方法的时候,会顺着这条链一直往上找 添加方法 在给Child原型添加方法的时候,如果,父类上也有同样的名字,Child将会覆盖这个方法,达到重写的目的。但是这个方法依然存在于父类中 记住不能以字面量的形式添加,因为,上面说过通过实例继承本质上就是重写,在使用字面量形式,又是一次重写了,但这次重写没有跟父类有任何关联,所以就会导致原型链截断 function Parent(){ this.property=true; } Parent.prototype.getParentValue=function(){ return this.property; } function Child(){ this.Childproperty=false; } Child.prototype=new Parent(); Child.prototype={ getChildValue:function(){ return this.Childproperty; } } var instance=new Child(); console.log(instance.getParentValue)//error; 问题 单纯的使用原型链继承,主要问题来自包含引用类型的原型。 function Parent(){ this.colors=['red','blue','green']; } function Child(){ } Child.prototype=new Parent(); var instance1=new Child(); var instance2=new Child(); instance1.colors.push('black'); console.log(instance1.colors);//[\"red\", \"blue\", \"green\", \"black\"] console.log(instance2.colors);//[\"red\", \"blue\", \"green\", \"black\"] 在Parent构造函数定义了一个colors属性,当Child通过原型链继承后,这个属性就会出现Child.prototype中,就跟专门创建了Child.prototype.colors一样,所以会导致Child的所有实例都会共享这个属性,所以instance1修改colors这个引用类型值,也会反应到instance2中 2.借用构造函数 此方法为了解决原型中包含引用类型值带来的问题 这种方法的思想就是在子类构造函数的内部调用父类构造函数,可以借助apply()和call()方法来改变对象的执行上下文 function Parent(){ this.colors=['red','blue','green']; } function Child(){ Parent.call(this); } var instance1=new Child(); var instance2=new Child(); instance1.colors.push('black'); console.log(instance1.colors);//[\"red\", \"blue\", \"green\", \"black\"] console.log(instance2.colors);//[\"red\", \"blue\", \"green\"] 在新建Child实例是调用了Parent构造函数,这样一来,就会在新Child对象上执行Parent函数中定义的所有对象初始化代码。 结果,Child的每个实例就会具有自己的colors属性的副本了。 传递参数 借用构造函数还有一个优势就是可以传递参数 function Parent(name){ this.name=name; } Parent.prototype.say=function(){ console.log('hello'); } function Child(){ Parent.call(this,'Jiang'); this.job='student'; } var instance=new Child(); var parent=new Parent(); console.log(parent.say()); console.log(instance.name)//Jiang console.log(instance.job)//student console.log(instance.say());//error 问题 如果仅仅借助构造函数,方法都在构造函数中定义,因此函数无法达到复用。这种方法只能继承父构造函数中声明的实例属性,并没有继承父类原型的属性和方法,所以就找不到sayfa方法,为了同时继承父类原型,从而诞生了组合继承的方式。 3.组合继承(原型链+构造函数) 组合继承是将原型链继承和构造函数结合起来,从而发挥二者之长的一种模式 思路就是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承 这样,既通过在原型上定义方法实现了函数的复用,又能够保证每个实例都有它自己的属性 function Parent(name){ this.name=name; this.colors=['red','blue','green']; } Parent.prototype.sayName=function(){ console.log(this.name); } function Child(name,job){ Parent.call(this,name); this.job=job } Child.prototype=new Parent(); Child.prototype.constructor=Parent Child.prototype.sayJob=function(){ console.log(this.job); } var instance1=new Child('Jiang','student'); instance1.colors.push('black'); console.log(instance1.colors)//[\"red\", \"blue\", \"green\", \"black\"] instance1.sayName();//Jiang instance1.sayJob();//student var instance2=new Child('J','doctor'); console.log(instance2.colors)//[\"red\", \"blue\", \"green\"] instance2.sayName();//J instance2.sayJob();//doctor 这种模式避免了原型链和构造函数继承的缺陷,融合他们的优点,是最常用的一种继承模式 4.原型式继承 借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型 function object(o){ function F(){} F.prototype=o; return new F(); } 在object函数内部,先创建一个临时性的构造函数,然后将传入的对象作为整个构造函数的原型,最后返回这个临时类型的一个实例 本质上来说,object对传入其中的对象执行了一次浅复制 var person={ name:'Jiang', friends:['Shelby','Court'] } var anotherPerson=object(person) console.log(anotherPerson.friends);//[\"Shelby\", \"Court\"] 这种模式要求你必须有一个对象作为另一个对象的基础 在这个例子中,person作为另一个对象的基础,把person传入object中,该函数就会返回一个新的对象 在这个新对象将person作为原型,所以它的原型中就包含一个基本类型和另一个引用类型 所以意味着如果还有另外一个对象关联了person,anotherPerson修改数组friends的时候,也会体现在这个对象中。 Object.create()方法 ES5通过Object.create()方法规范了原型式继承,可以接收两个参数,一个是作用新对象原型的对象和一个可选的为新对象定义额外属性的对象,行为相同,基本用法和上面的objcet一样,除了objcet不能接收第二个参数除外 var person={ name:'Jiang', friends:['Shelby','Court'] } var anotherPerson=Object.create(person) console.log(anotherPerson.friends);//[\"Shelby\", \"Court\"] 5.寄生式继承 寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数 function createAnother(o){ var clone=Object.create(o);//创建一个新对象 clone.sayHi=function(){//添加方法 console.log('hi') } return clone//返回这个对象 } var person={ name:'Jiang' } var anotherPerson=createAnother(person); anotherPerson.sayHi(); 基于person返回了一个新对象anotherPerson,新对象不仅有用了person的属性和方法,还有自己的sayHi方法 在主要考虑对象而不是自定义类型和构造函数的情况下,这是一个有用的模式 6.寄生组合式继承 在前面说的组合模式(原型链+构造函数)中,继承的时候需要调用两次父类构造函数 父类 function Parent(name){ this.name=name; this.colors=['red','blue','green']; } 第一次在子类构造函数中 function Child(name,job){ //继承属性 Parent.call(this,name); this.job=job; } 第二次将子类的原型指向父类的实例 //继承方法 Child.prototype=new Parent(); 当使用var instance=new Child()的时候,会产生两组name和color属性,一组在Child实例上,一组在Child原型上,只不过实例上的屏蔽了原型上的。 使用寄生式组合模式,可以规避这个问题 这种模式通过借用构造函数来继承属性,通过原型链的混成形式来继承方法 基本思路:不必为了执行子类型的原型而调用父类的构造函数,我们需要的无非就是父类原型的一个副本 本质上就是使用寄生式继承来继承父类的原型,在将结果指定给子类型的原型 function inheritPrototype(Child,Parent){ var prototype=Object.create(Parent.prototype) prototype.constructor=Child; Child.prototype=prototype; } 该函数实现了寄生组合继承的最简单模式 这个函数接受两个参数,一个子类,一个父类 第一步创建父类原型的副本,第二步将创建的副本添加construcot属性,第三步将子类的原型指向这个副本。 function Parent(){ this.name=name; this.colors=['red','blue','green'] } Parent.prototype.sayName=function(){ console.log(this.name); } function Child(name,job){ //继承属性 Parent.call(this,name) this.job=job; } //继承 inheritPrototype(Child,Parent) var instance=new Child('Jiang','student'); instance.sayName(); 补充:直接使用Object.create来实现,其实就是将上面封装的函数拆开,这样演示可以更容易理解 function Parent(){ this.name=name; this.colors=['red','blue','green'] } Parent.prototype.sayName=function(){ console.log(this.name); } function Child(name,job){ //继承属性 Parent.call(this,name) this.job=job; } //继承 Child.prototype=Object.create(Parent.prototype) //修复consrtuctor Child.prototype.constructor=Child; var instance=new Child('Jiang','Student') instance.sayName(); var instance=new Child('Jiang','student'); instance.sayName(); ES6新增了一个方法,Objcet.setPropertyOf,可以直接创建关联,而不用手动添加constructor属性 //继承 Object.setPropertyOf(Child.prototype,Parent.prototype) console.log(Child.prototype.constuctor===Child)//true Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:01:31 "},"js/JavaScript创建对象的七种方式.html":{"url":"js/JavaScript创建对象的七种方式.html","title":"JavaScript创建对象的七种方式","keywords":"","body":"七种方式 工厂模式 构造函数模式 原型模式 组合使用构造函数模式和原型模式 动态原型模式 =》 构造函数+动态原型 寄生构造函数模式 =》工厂模式+new 稳妥构造函数模式 =》工厂模式 去掉this 参考地址 JavaScript创建对象的七种方式 JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以创建单个对象,显然这两种方式会产生大量的重复代码,并不适合量产。接下来介绍七种非常经典的创建对象的方式,他们也各有优缺点 1.工厂模式 function createPerson(name,job){ var o=new Object(); o.name=name; o.sayName=function(){ consle.log(this.name) } return o; } var person1=createPerson('Jiang','student'); var person2=createPerson('X',\"Doctor\"); console.log(person1); console.log(person2) 可以无数个调用这个工厂函数,每次都会返回一个包含两个属性和一个方法的对象 工厂模式虽然解决了创建多个相似对象的问题,但是没有解决对象识别的问题,即不能知道一个对象的类型 2.构造函数模式 function Person(name,job){ this.name=name; this.job=job; this.sayName=function(){ console.log(this.name); } } var person1=new Person('Jiang','student'); var person2=new Person('X','Doctor'); 没有显示的创建对象,使用new来调用这个构造函数,使用new后会自动执行如下操作 创建一个新对象 这个新对象会被执行[[prototype]]链接 这个新对象会绑定到函数调用的this 返回这个对象 使用这个方式创建对象可以检测对象类型 person1 instanceof Object//true person2 instanceof Person//true 但是使用构造函数创建对象,每个方法都要在每个实例上重新创建一次 3.原型模式 function Person(){ } Person.prototype.name='Jiang'; Person.prototype.job='studeng'; Person.prototype.sayName=function(){ console.log(this.name); } var person1=new Person(); 将信息直接添加到原型对象上。使用原型的好处是可以让所有的实例对象共享它包含的属性和方法,不必再构造函数中定义对象实例信息。 更简单的写法 function Person(){ } Person.prototype={ name:'Jiang', job:'studeng', sayName:function(){ console.log(this.name); } } var person1=new Person(); 将Person.prototype设置为等于一个以对象字面量形式创建的对象,但是会导致.constructor不在指向Person了。 使用这种方式,完全重写了默认的Person.prototype对象,因此,.constructor也不会存在这里 Person.prototype.constructor===Person//false 如果需要这个属性的话,可以手动添加 function Person(){ } Person.prototype={ constructor:Person, name:'Jiang', job:'studeng', sayName:function(){ console.log(this.name); } } var person1=new Person(); 不过这种方式还是不够好,应为constructor属性默认为不可枚举的,这样直接设置,它是可枚举的,所以可以使用,Object.defineProperty方法 Object.defineProperty(Person.prototype,'constructor',{ enumerable:false, value:Person }) 缺点 使用原型,所有的属性都将被共享,这是很大的有点,同样也会带来一些缺点 原型中所有属性实例是被很多实例共享的,这种共享对于函数非常适合。对于那些包含基本值的属性也勉强可以,毕竟实例属性可以屏蔽原型属性。但是引用类型值,就会出现问题了 function Person(){ } Person.prototype={ name:'jiang', friends:['shelby','Court'] } var person1=new Person(); var person2=new Person(); person1.friends.push('Van'); console.log(person1.friends); console.loh(person2.friends); console.log(person1.friends===person2.friends)//true friends存在于原型中,实例person1和person2指向同一个原型,person1修改了引用的数组,也会反应到实例person2中 4.组合使用构造函数模式和原型模式 这是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点 使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用 这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了 function Person(){ this.name=name; this.friends=['Shelby','Court'] } Person.prototype.sayName=function(){ console.log(this.name) } var person1=new Person(); var person2=new Person(); person1.friends.push('Van'); console.log(person1.friends); console.log(person2.friends); console.log(person1.friends===person2.friends)//false 5.动态原型模式 动态原型模式将所有信息都封装在了构造函数中,初始化的时候,通过检测某个应该存在的方法时候有效,来决定是否需要初始化类型 function Person(){ this.name=name; this.job=job; if(typeof this.sayName!=='function'){ Person.protoytype.sayName=function(){ console.log(this.name) } } } var person1=new Person('Jiang','student'); person1.sayName(); 只有在sayName方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。 此后原型已经完成初始化,不需要在做什么修改了 这里对原型所做的修改,能够立即在所有实例中得到反映 其次,if语句检查的可以是初始化之后应该存在的任何属性和方法,所以不必用一大堆的if语句检查每一个属性和方法,只要检查一个就行 6.寄生构造函数模式 这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象 function Person(name,job){ var o=new Object() o.name=name; o.job=job; o.sayName=function(){ console.log(this.name) } return o } var person1=new Person('Jiang','student'); person1.sayName(); 这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样 构造函数如果不返对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值 7.稳妥构造函数模式 首先明白稳妥对象所指的是没有公共属性,而且其他方法也不引用this。 稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用 稳妥构造函数模式和寄生模式类似,有两点不同:一是创建对象的实例方法不引用this,二是不使用new操作符调用构造函数 function Person(name,job){ var o=new Object() o.name=name; o.job=job; o.sayName=function(){ console.log(name) } return o } var person1=Person('Jiang','student'); person1.sayName(); 和寄生构造函数模式一样,这样创建出来的对象和构造函数之间没有什么关系,instanceof 操作符对于他们没有意义 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:31:54 "},"js/ES5String基础.html":{"url":"js/ES5String基础.html","title":"ES5 string基础","keywords":"","body":"参考网址: js String对象中常用方法小结(字符串操作) 样式 JavaScript String 对象参考手册 一、基础 1.String 对象属性 var name1=\"hello world\" | 属性 | 描述 | 输出 | | ----------- | ---------------------------- | ----------------------------------- | | constructor | 对创建该对象的函数的引用 | function String() { [native code] } | | length | 字符串的长度 | 3 | | prototype | 允许您向对象添加属性和方法。 | undefined | 1.charCodeAt方法返回一个整数,代表指定位置字符的Unicode编码。 strObj.charCodeAt(index) 说明:index将被处理字符的从零开始计数的编号。有效值为0到字符串长度减1的数字。如果指定位置没有字符,将返回NaN。 例如: var str=\"ABC\"; var re=str.charCodeAt(0); var re2=str.charCodeAt(3); console.log(re);// 65 console.log(re2);// NaN console.log(str);//原字符串不改变 2.fromCharCode方法从一些Unicode字符串中返回一个字符串。 String.fromCharCode(code1,code2...,codeN) 说明:code1,code2....是要转换为字符串的Unicode字符串序列。如果没有参数,结果为空字符串。 例如: var re=String.fromCharCode(65,66,112); console.log(re);// ABp 3.charAt方法返回指定索引位置处的字符。如果超出有效范围的索引值返回空字符串。 strObj.charAt(index) 说明:index 从0到strObj.length-1,如果超过下标,结果为空字符串例如: var str=\"ABC\"; var re=str.charAt(1); var re2=str.charAt(3); console.log(re);//B console.log(re2);// 空 console.log(str);//ABC 原字符串不改变 4.slice方法返回字符串的片段。Array也有该方法 strObj.slice(start[,end]) 左闭右开 说明:start下标从0开始的strObj指定部分开始索引。如果start为负,将它作为length+start处理,此处length为字符串的长度。 end小标从0开始的strObj指定部分结束索引。如果end为负,将它作为length+end处理,此处length为字符串的长度。 对不符合条件的返回空。 例如: var str=\"ABCDEF\";//leng=6 var re=str.slice(2,4); var re2=str.slice(2,-1);//str.slice(2,5) var re3=str.slice(-1,-1);//str.slice(5,5) var re4=str.slice(-2,-3);//str.slice(4,3) console.log(re);//CD console.log(re2);//CDE console.log(re3);//空 console.log(re4);//空 console.log(str);//ABCDEF 原字符串不改变 5.substring方法返回位于String对象中指定位置的子字符串。 strObj.substring(start,end) 说明:start指明子字符串的起始位置,该索引从0开始起算。 end指明子字符串的结束位置,该索引从0开起算。 subString 方法使用start和end两者中的较小值作为子字符串的起始点。如果start或end为NaN或者为负数,那么将起替换为0。 例如: var str=\"ABCDEF\"; var re=str.substring(2,4); var re2=str.substring(4,2); var re3=str.substring(2,-1);//str.substring(2,0)=str.substring(0,2); console.log(re);//CD console.log(re2);//CD console.log(re3);//AB console.log(str);//ABCDEF 原字符串不改变 6.substr方法返回一个指定位置开始的指定长度的子字符串 strObj.substr(start[,length]) 说明:start所需的子字符串的起始位置。字符串的第一个字符的索引为0。 例如: var str=\"ABCDEF\"; var re=str.substr(1,3); var re2=str.substr(1,6);//长度超过字符串长度,按照最大的长度截取 var re3=str.substr(-1,6);//如果为负,该值为当前值加上字符串长度 var re4=str.substr(-1,-1);//如果长度为负数,不满足条件,返回空 console.log(re);//BCD console.log(re2);//BCDEF console.log(re3);//F console.log(re4);//kong console.log(str);//ABCDEF 原字符串不改变 7.indexOf方法返回String对象第一次出现的字符串位置。如果没有找到子字符串,则返回-1。 strObj.indexOf(substr[,startIndex]) 说明: substr要在String对象中查找的子字符串。startIndex该整数值指出在String对象内开始查找的索引。如果省略,则从字符串的开始出查找。 例如: var str=\"ABCDEF\"; var re=str.indexOf('B',1); var re2=str.indexOf('b',1); console.log(re);//1 console.log(re2);//-1 console.log(str);//ABCDEF 8.lastIndexOf方法返回String对象中字符串最后出现的位置。如果没有匹配到子字符串,则返回-1。 strObj.lastIndexOf(substr[,startindex]) 说明:substr要在String对象内查找的子字符串。startindex该整数值指出在String对象内进行查找的开始索引位置。如果省略,则查找从字符串的末尾开始。 例如: var str=\"ABCDBEFB\"; var re=str.lastIndexOf('B');//从字符串的末尾开始找 var re2=str.lastIndexOf('B',5);//从5位置从右向左查找 5,4,3,2,1 var re3=str.indexOf('BE'); var re4=str.indexOf('BE',-1);//如果为0或者负数,都从字符串的末尾开始找 console.log(re);//7 console.log(re2);//4 console.log(re3);//4 console.log(re4);//4 console.log(str);//ABCDBEFB 9.search方法返回与正则表达式查找内容匹配的第一个字符串的位置。 strObj.search(reExp) 说明:reExp包含正则表达式模式和可用标志的正则表达式对象。例如: var str=\"ABCDEFCD\"; var re=str.search('CD'); console.log(re);//2 console.log(str); 10.match 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。该方法类似indexOf和lastIndexOf,但是它返回指定的值,而不是字符串的位置。 stringObject.match(searchvalue)stringObject.match(regexp) 例如: var str = \"Hello world\"; var re=str.match(\"HE\") var re2=str.match(\"He\") console.log(re);// null console.log(re2);//[\"He\", index: 0, input: \"Hello world\"] console.log(str);//Hello world 11.replace 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。 stringObject.replace(regexp/substr,replacement) 说明:字符串 stringObject 的 replace() 方法执行的是查找并替换的操作。它将在 stringObject 中查找与 regexp 相匹配的子字符串,然后用 replacement 来替换这些子串。如果 regexp 具有全局标志 g,那么 replace() 方法将替换所有匹配的子串。否则,它只替换第一个匹配子串。 replacement 可以是字符串,也可以是函数。如果它是字符串,那么每个匹配都将由字符串替换。但是 replacement 中的 $ 字符具有特定的含义。如下表所示,它说明从模式匹配得到的字符串将用于替换。 例如 var str = \"ABCabc\"; var re=str.replace(/c/ig,'D')//方法用于把字符串转换为小写(); console.log(re);//ABDabD console.log(str);//ABCabc 12.concat 方法返回字符串值,该值包含了两个或多个提供的字符串连接。Array 也有该方法 str.concat(string1,string2...stringn) 说明:string1,string2要和所有其他指定的字符串进行连接的String对象或文字。 例如: var str=\"ABCDEFCD\"; var re=str.concat(' Hello ',\"World\") console.log(re);//ABCDEFCD Hello World console.log(str);//ABCDEFCD 原字符串不改变 13.split将一个字符串分隔为子字符串,然后将结果作为字符串数组返回。 strObj.split(separator[,limit]) 说明:separator字符串或正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符串。如果忽略该选项,则返回包含整个字符串的单一元素数组。 例如: var str=\"AA BB CC DD EE FF\"; var re=str.split(\" \",3); var re2=str.split(\" \"); console.log(re);//[\"AA\", \"BB\", \"CC\"] console.log(re2);//[\"AA\", \"BB\", \"CC\",\"DD\",\"FF] console.log(str);//AA BB CC DD EE FF 14.toLowerCase方法返回一个字符串,该字符串的字母被转换成小写。 strObj.toLowerCase() 例如: var str = \"ABCabc\"; var re=str.toLowerCase(); console.log(re);//abcabc console.log(str);//ABCabc 15.toUpperCase方法返回一个字符串,该字符串的字母都被转换为大写字母。 strObj.toUpperCase() 例如: var str = \"ABCabc\"; var re=str.toUpperCase(); console.log(re);//ABCABC console.log(str);//ABCabc 16.toLocaleLowerCase方法用于把字符串转换为小写 strObj.toLocaleLowerCase(); 说明:与 toLowerCase() 不同的是,toLocaleLowerCase() 方法按照本地方式把字符串转换为小写。只有几种语言(如土耳其语)具有地方特有的大小写映射,所有该方法的返回值通常与 toLowerCase() 一样。 例如: var str = \"ABCabc\"; var re=str.toLowerCase(); console.log(re);//abcabc console.log(str);//ABCabc 17.toLocaleUpperCase方法用于把字符串转换为小写 strObj.toLocaleUpperCase() 说明:与 toUpperCase() 不同的是,toLocaleUpperCase 方法按照本地方式把字符串转换为小写。只有几种语言(如土耳其语)具有地方特有的大小写映射,所有该方法的返回值通常与 toLowerCase() 一样。 例如: var str = \"ABCabc\"; var re=str.toLocaleUpperCase()//方法用于把字符串转换为大写(); console.log(re);//ABCABC console.log(str);//ABCabc 18.toSource()代表对象的源代码 19.toString()返回字符串。 20.valueOf()返回某个字符串对象的原始值。 21.localeCompare()用本地特定的顺序来比较两个字符串。 样式相关 var txt=\"Hello World!\" document.write(txt.anchor(\"myanchor\")) Hello world! document.write(\"Big: \" + txt.big() + \"\") document.write(\"Small: \" + txt.small() + \"\") document.write(\"Bold: \" + txt.bold() + \"\") document.write(\"Italic: \" + txt.italics() + \"\") document.write(\"Blink: \" + txt.blink() + \" (does not work in IE)\") document.write(\"Fixed: \" + txt.fixed() + \"\") document.write(\"Strike: \" + txt.strike() + \"\") document.write(\"Fontcolor: \" + txt.fontcolor(\"Red\") + \"\") document.write(\"Fontsize: \" + txt.fontsize(16) + \"\") document.write(\"Lowercase: \" + txt.toLowerCase() + \"\") document.write(\"Uppercase: \" + txt.toUpperCase() + \"\") document.write(\"Subscript: \" + txt.sub() + \"\") document.write(\"Superscript: \" + txt.sup() + \"\") document.write(\"Link: \" + txt.link(\"http://www.w3school.com.cn\") + \"\") Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:05:28 "},"js/ES5数组.html":{"url":"js/ES5数组.html","title":"ES5 数组","keywords":"","body":"参考网址: 参考网址 js数组依据下标删除元素 Array对象(javascript——MADN).aspx) MDN->Web 技术文档->JavaScript->JavaScript 指南->Indexed collections 判断是不是数组 Array.isArray(value) 一、基础 1.Array 对象属性 var name1=[1,2,3] | 属性 | 描述 | 输出 | | ----------- | -------------------------------- | ---------------------------------- | | constructor | 返回对创建此对象的数组函数的引用 | function Array() { [native code] } | | length | 设置或返回数组中元素的数目 | 3 | | prototype | 使您有能力向对象添加属性和方法。 | undefined | 1. 创建数组 var array=[item1,item2...itemN]; var array=new Array(); var array=new Array(size);//指定数组的长度 var array=new Array(item1,item2....itemN);//创建数组并赋值 2.取值、赋值 var item=array[index];// 获取指定元素的值 array[index]=value;// 为指定元素赋值 [0, 0, 0].fill(7, 1);//[0,7,7] 3.添加新元素 array.push(item1,item2...itemN);//将一个或多个元素加入数组,返回新数组的长度 eg: var xx=[1,2,3]; var xx2=xx.push(4); console.log(xx2);// 4 返回新数组的长度 console.log(xx);// [1,2,3,4] 原数组将改变 array.unshift(item1,item2...itemN);//将一个或多个元素加入到数组的开始位置,原有元素位置自定后移,返回新数组的长度 eg: var xx=[1,2,3]; var xx2=xx.unshift(4,5); console.log(xx2);// 5 返回新数组的长度 console.log(xx);// [4,5,1,2,3] 原数组将改变 array.splice(start,deCount,item1,item2...itemN);//从start的位置开始向后删除delCount个元素,然后从start的位置开始插入一个或多个新元素 eg: var xx=[1,2,3,4,5]; var xx2=xx.splice(1,2); console.log(xx2);// [2,3] 返回删除的数据,数组格式 console.log(xx);// [1,4,5] 原数组将改变 4.删除元素 array.pop()//删除最后一个元素,并返回该元素 eg: var xx=[1,2,3,4,5]; var xx2=xx.pop(); console.log(xx2);// 5 返回删除的数据 console.log(xx);// [1,2,3,4] 原数组将改变 array.shift()//删除第一个元素,数组元素位置自动前移,返回被删除的元素 eg: var xx=[1,2,3,4,5]; var xx2=xx.shift(); console.log(xx2);// 1 返回删除的数据 console.log(xx);// [2,3,4,5] 原数组将改变 array.splice(start,delCount);//从start的位置开始向后删除delCount个元素 eg: var xx=[1,2,3,4,5]; var xx2=xx.splice(2,2); console.log(xx2);// [3,4] 返回删除的数据 console.log(xx);// [1,2,5] 原数组将改变 5.数据的合并,截取 array.slice(start,end);//以数组的形式返回数组的一部分,注意不包括end对应的元素,如果省略end将复制start之后的所有元素(左闭又开,注意和splice的区别,splice第二个参数是长度,slice的第二个参数是结束位置) eg: var xx=[1,2,3,4,5]; var xx2=xx.slice(2,4); console.log(xx2);// [3,4] 返回新数组的长度 console.log(xx);// [1,2,3,4,5] 原数组不改变 array.concat(array1,array2);//将多个数组拼接成一个数组 eg: var xx1=[1,2,3],xx2=[4,5],xx3=[6,7]; var xx4=xx.concat(xx1,xx2,xx3); console.log(xx1);// [1,2,3] 原数组不改变 console.log(xx2);// [4,5] 原数组不改变 console.log(xx3);// [6,7] 原数组不改变 console.log(xx4);// [1,2,3,4,5,6,7] 6.数组的排序 array.reverse();//数组反转 eg: var xx=[1,10,2,3,4,5]; var xx2=xx.reverse(); console.log(xx2);// [5,4,3,2,10,1] 返回翻转后的数组 console.log(xx);// [5,4,3,2,10,1] 原数组将改变 array.sort();//数组排序,返回数组地址 eg: var xx=[1,2,3,10,5,4]; var xx2=xx.sort(); console.log(xx2);// [1,10,2,3,4,5] 返回排序后的数组 console.log(xx);// [1,10,2,3,4,5] 原数组将改变 注意:这里默认是按照字符串来排序的,所以10在2的前面,如果需要按数组排序,需要填代码 eg: var xx=[1,2,3,10,5,4]; function sortNumber(a,b){ return a - b } var xx2=xx.sort(sortNumber); console.log(xx2);// [1,10,2,3,4,5] 返回排序后的数组 console.log(xx);// [1,10,2,3,4,5] 原数组将改变 7.数组转字符串 array.join(separator);//将数组用separator分隔符链接起来 eg: var xx=[1,2,3,10,5,4]; var xx2=xx.join();// 分隔符默认为“,” var xx3=xx.join(\"|\"); //分隔符为 console.log(xx2);// 1,2,3,10,5,4 转换后的字符串 console.log(xx3);// 1|2|3|10|5|4 转换后的字符串 console.log(xx);// [1,2,3,10,5,4] 原数组不改变 8.字符串转数组 string.split(separator);//将字符串通过用separator分隔符分隔开来 eg: var xx=\"1,2,3,10,5,4\"; var xx2=xx.split(',');// 分隔符默认为“,” console.log(xx2);// 1,2,3,10,5,4 转换后的字符串 console.log(xx);// [1,2,3,10,5,4] 原数组不改变 二 、进阶 对数组进行处理 1. every方法(Array) 确定数组的所有成员是否满足指定的测试(全部满足则返回true,否则返回false) 语法: array1.every(callbackfn[, thisArg]) 参数: 参数 参数 定义 array1 必需。一个数组对象。 callbackfn 必需。一个接受最多三个参数的函数。 every 方法会为 array1 中的每个元素调用 callbackfn 函数,直到 callbackfn 返回 false,或直到到达数组的结尾 thisArg 可选。可在 callbackfn 函数中为其引用 this 关键字的对象。如果省略 thisArg,则 undefined 将用作 this 值 返回值: 如果 callbackfn 函数为所有数组元素返回 true,则为 true;否则为 false。如果数组没有元素,则 every 方法将返回 true 回调函数语法: function callbackfn(value, index, array1) 回调参数 定义 value 数组元素的值 index 数组元素的数字索引 array1 包含该元素的数组对象 var checkNumericRange=function(value){ if(typeof value!='number'){ return false; }else{ return value>=this.minimum&&value2. some方法(Array) 确定指定的回调函数是否为数组中的任何元素均返回 true (既有一个满足即返回true) 语法: array1.some(callbackfn[, thisArg]) 参数: 参数 参数 定义 array1 必需。一个数组对象。 callbackfn 必需。一个接受最多三个参数的函数。 some 方法会为 array1 中的每个元素调用 callbackfn 函数,直到 callbackfn 返回 true,或直到到达数组的结尾 thisArg 可选。可在 callbackfn 函数中为其引用 this 关键字的对象。如果省略 thisArg,则 undefined 将用作 this 值。 返回值: 如果 callbackfn 函数为任何数组元素均返回 true,则为 true;否则为 false。 var checkNumericRange=function(value){ if(typeof value!='number'){ return false; }else{ return value>=this.minimum&&value3. filter方法(Array) 返回数组中的满足回调函数中指定的条件的元素。 语法: array1.filter(callbackfn[, thisArg]) 参数: 参数 参数 定义 array1 必需。一个数组对象。 callbackfn 必需。一个接受最多三个参数的函数。对于数组中的每个元素,filter 方法都会调用 callbackfn 函数一次。 thisArg 可选。可在 callbackfn 函数中为其引用 this 关键字的对象。如果省略 thisArg,则 undefined 将用作 this 值 返回值: 一个包含回调函数为其返回 true 的所有值的新数组。如果回调函数为 array1 的所有元素返回 false,则新数组的长度为 0。 function checkIfPrime(value,index,ar){ high=Math.floor(Math.sqrt(value))+1; for(var div=2;div4. forEach方法(Array) 为数组中的每个元素执行指定操作。 语法: array1.forEach(callbackfn[, thisArg]) 参数: 参数 参数 定义 array1 必需。一个数组对象。 callbackfn 必选。最多可以接受三个参数的函数。对于数组中的每个元素,forEach 都会调用 callbackfn 函数一次。 thisArg 可选。 callbackfn 函数中的 this 关键字可引用的对象。如果省略 thisArg,则 undefined 将用作 this 值。 返回值: 没有返回值,或者说返回值为Undefined function showResults(value,index,ar){ console.log('value: '+value); } var letters=['ab','cd','ef']; var result=letters.forEach(showResults); console.log(result); //value: ab //value: cd //value: ef //undefined 5. map(Array) 对数组的每个元素调用定义的回调函数并返回包含结果的数组。 语法: array1.map(callbackfn[, thisArg]) 参数: 参数 参数 定义 array1 必需。一个数组对象。 callbackfn 必选。 最多可以接受三个参数的函数。 对于数组中的每个元素,map 方法都会调用 callbackfn 函数一次。。 thisArg 可选。 callbackfn 函数中的 this 关键字可引用的对象。 如果省略 thisArg,则 undefined 将用作 this 值。 返回值: 一个新数组,其中的每个元素均为关联的原始数组元素的回调函数返回值。 function areaOfCircle(radius){ var area=Math.PI*(radius*radius); return area.toFixed(0); } var radii=[10,20,30]; var areas=radii.map(areaOfCircle); console.log(areas);//[\"314\", \"1257\", \"2827\"] 6. reduce方法(Array) 对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供。。 语法: array1.reduce(callbackfn[, initialValue]) 参数: 参数 参数 定义 array1 必需。一个数组对象。 callbackfn 必需。一个接受最多四个参数的函数。对于数组中的每个元素,reduce 方法都会调用 callbackfn 函数一次。 initialValue 可选。如果指定 initialValue,则它将用作初始值来启动累积。第一次调用 callbackfn 函数会将此值作为参数而非数组值提供。 回调函数语法: function callbackfn(previousValue, currentValue, currentIndex, array1) 回调参数 定义 previousValue 通过上一次调用回调函数获得的值。如果向 reduce 方法提供 initialValue,则在首次调用函数时,previousValue 为 initialValue。 currentIndex 当前数组元素的数字索引。 array1 包含该元素的数组对象。 返回值: 通过最后一次调用回调函数获得的累积结果 function addRounded(previousValue,currentValue){ return previousValue+Math.round(currentValue); } var numbers=[10.9,15.4,0.5]; var result=numbers.reduce(addRounded,0); console.log(result);//27 6. reduceRight 方法 (Array) 上面方法的倒叙 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:07:47 "},"js/ES5数组归纳.html":{"url":"js/ES5数组归纳.html","title":"ES5 数组归纳","keywords":"","body":"一 、练习 1.通过下标删除数据 var array=[1,2,3,4,5,6]; var del=[3,5];// 通过下标删除数据 for(var i=0,len=del.length;i2.数组的深拷贝 基本烈性就是浅拷贝,引用类型就是深拷贝,如果要深拷贝一个数组和对象,可以用array.concat和array.slice函数 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中任何一个,然后其他的也会跟着改变,这就导致了问题的发生 var arr = [\"One\",\"Two\",\"Three\"]; var arrto = arr; arrto[1] = \"test\"; document.writeln(\"数组的原始值:\" + arr + \"\");//Export:数组的原始值:One,test,Three document.writeln(\"数组的新值:\" + arrto + \"\");//Export:数组的新值:One,test,Three 方法一:array的slice方法 对于array对象的slice函数, 返回一个数组的一段。(仍为数组) arrayObj.slice(start, [end]) 参数 arrayObj 必选项。一个 Array 对象。 start 必选项。arrayObj 中所指定的部分的开始元素是从零开始计算的下标。 end 可选项。arrayObj 中所指定的部分的结束元素是从零开始计算的下标。 说明 slice 方法返回一个 Array 对象,其中包含了 arrayObj 的指定部分。 slice 方法一直复制到 end 所指定的元素,但是不包括该元素。如果 start 为负,将它作为 length + start处理,此处 length 为数组的长度。如果 end 为负,就将它作为 length + end 处理,此处 length 为数组的长度。如果省略 end ,那么 slice 方法将一直复制到 arrayObj 的结尾。如果 end 出现在 start 之前,不复制任何元素到新数组中。 var arr = [\"One\",\"Two\",\"Three\"]; var arrtoo = arr.slice(0); arrtoo[1] = \"set Map\"; console.log(\"数组的原始值:\" + arr);//数组的原始值:One,Two,Three console.log(\"数组的新值:\" + arrtoo);//数组的新值:One,set Map,Three 方法二:array的concat方法 concat() 方法用于连接两个或多个数组。 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。 语法 arrayObject.concat(arrayX,arrayX,......,arrayX) 说明 返回一个新的数组。该数组是通过把所有 arrayX 参数添加到 arrayObject 中生成的。如果要进行 concat() 操作的参数是数组,那么添加的是数组中的元素,而不是数组。 var arr = [\"One\",\"Two\",\"Three\"]; var arrtooo = arr.concat(); arrtooo[1] = \"set Map To\"; console.log(\"数组的原始值:\" + arr );//数组的原始值:One,Two,Three console.log(\"数组的新值:\" + arrtooo);//数组的新值:One,set Map To,Three Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:09:10 "},"js/ES5数组详细操作方法及解析合集.html":{"url":"js/ES5数组详细操作方法及解析合集.html","title":"ES5 数组详细操作方法及解析合集","keywords":"","body":"参考 js 数组详细操作方法及解析合集 一、创建一个数组: 1.ES5创建 //字面量方式: //这个方法也是我们最常用的,在初始化数组的时候,相当方便 var a=[3,11,8];//[3,11,8] //构造器 //实际上 new Array===Array,加不加new 一点影响都没。 var a=Array();//[] var a=Array(3);//[,,] var a=Array(3,11,8);//[3,11,8] 2.ES6 Array.of()返回由所有参数值组成的数组 定义:返回由所有参数值组成的数组,如果没有参数,就返回一个空数组。 目的:Array.of()出现的目的是为了解决上诉构造器因参数个数不同,导致的行为有差异的问题。 var a=Array.of(3,11,8);//[3,11,8] var a=Array.of(3);//[3] 3.ES6 Array.from()将两类对象转为真正的数组 定义:用于将两类对象转为真正的数组(不改变原对象,返回新的数组)。 参数: 第一个参数(必选):要转化为真正数组的对象。 第二个参数(可选):类似数组的map方法,对每个元素进行处理,将处理后的值放入返回的数组。 第三个参数(可选):用来绑定this。 //1.对象拥有length属性 var obj={0:\"a\",1:\"b\",2:\"c\",length:3}; var arr=Array.from(obj); console.log(arr);//[a,b,c] //2.部署了Iterator接口的数据构造 比如:字符串、set、NodeList对象 var arr=Array.from('hello'); console.log(arr);//['h','e','l','l','o']; var arr=Array.from(new Set(['a','b','a'])); console.log(arr);//['a','b']; 二、方法总结 数组原型提供了非常多的方法,这里分为三类来讲,一类会改变原数组的值,一类是不会改变原数组,另一类是数组的边遍历方法 1.改变原数组的方法(9个): var a=[1,2,3]; ES5: a.splice() //删除/增加 返回被删除项目 a.pop() a.shift() //删除 返回被删除项目 a.push() a.unshift()//增加 返回新长度 a.sort() a.reverse()//排序 反转 返回新数组 ES6: a.copyWithin() a.fill()// 复制 填充 2.不改变原数组的方法(8个): var a=[1,2,3]; ES5: a.slice() a.join() a.toLocateString() a.toString()// 转字符串 a.concat //拼接 a.indexOf a.lastIndexOf //查找 indexOf()不能识别NaN ES7: a.includes() 3.遍历方法(12个): js中遍历数组并不会改变原始数组的方法总共有12个: ES5: a.forEach() a.map() a.every() a.some() a.filter() a.reduce() a.reduceRight() ES6: a.find() a.findIndex() a.keys() a.values() a.entries() 一、改变原数组的方法(9个): 对于这些能够改变原数组的方法,要注意避免在循环遍历中改变原数组的选项,比如:改变数组的长度,导致遍历的长度出现问题。 splice() 添加/删除数组元素 定义:splice()方法向/从数组中添加/删除项目,返回返回被删除的项目 语法:array.splice(index,howmany,item1,......,itemX) 参数: 1.index:必须。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 2.howmany:必须。要删除的项目数量。如果设置为0,则不会删除项目。 3.item1,...,itemX:可选,像数组添加的新项目。 返回值:如果有元素被删除,返回包含被删除项目的新数组。 eg1:删除元素 var a=[1,2,3,4,5,6,7]; //从数组下标0开始,删除3个元素 var item=a.splice(0,3); console.log(a);//[4,5,6,7]; console.log(item);//[1,2,3]; //从最后一个元素开始删除3个元素,因为最后一个元素,所以只删除了7 var item=a.splice(-1,3); cosnole.log(a);//[4,5,6] console.log(item);//[7] eg2:删除并添加 var a=[1,2,3,4,5,6,7]; var item=a.splice(0,3,'添加');//从数组下标0开始,删除3个元素,并添加元素'添加' console.log(item);//[1,2,3] console.log(a);//['添加',4,5,6] var b=[1,2,3,4,5,6,7]; var item=b.splice(-2,3,\"添加1\",\"添加2\");//从数组最后第二个元素开始删除3个元素,并添加两个元素\"添加1\",\"添加2\" console.log(b);//[1,2,3,4,5,\"添加1\",\"添加2\"] console.log(item);//[6,7] eg3:不删除只添加: var a=[1,2,3,4,5,6,7]; var item=a.splice(0,0,'添加1','添加2');//[]没有删除元素,返回空数组 console.log(item);//[] console.log(a);//['添加 ','添加2',1,2,3,4,5,6,7] var b=[1,2,3,4,5,6,7] var item=b.splice(-1,0,'添加1','添加2');//[]没有删除元素,返回空数组 console.log(b);//[1,2,3,4,5,6,'添加1','添加2',7] console.log(item);//[] 从上诉三个栗子可以得出: 数组如果元素不够,会删除到最后一个元素为止 操作的元素,包括开始的那个元素 可以添加很多元素 添加是在开始的元素前面添加的 pop()删除一个数组中的最后一个元素 定义:pop()方法删除一个数组中的最后的一个元素,并且返回这个元素。 参数:无。 var a=[1,2,3]; item =a.pop(); console.log(a);//[1,2] console.log(item);//3 shift()删除数组的第一个元素 定义:shift()方法删除数组的第一个元素,并返回这个元素。 参数:无。 var a=[1,2,3]; item =a.shift(); console.log(a);//[2,3] console.log(item);//1 push()向数组的末尾添加元素 定义:push()方法可向数组的末尾添加一个或多个元素,并返回新的长度。 参数:item1,item2...itemX,要添加到数组末尾的元素。 var a=[1,2,3]; var item=a.push('末尾'); console.log(item);//4 console.log(a);//[1,2,3,'末尾'] unshift()向数组的开头添加一个或更多个元素,并返回新的长度。 参数:item1,item2...itemX,要添加到数组开头的元素 var a=[1,2,3]; var item=a.unshift('开头'); console.log(a);//[\"开头\", 1, 2, 3] console.log(item);//4 sotr()数组排序 定义:sort()方法对数组元素进行排序,并返回这个数组。 参数可选:规定排序顺序的比较函数。 默认情况下sort()方法没有传比较函数的话,默认按字母升序,如果元素不是字符串的话,会调用toString()方法将元素转化为字符串的Unicode,然后再比较字符。 //字符串排列,看起来很正常 var a=[\"Banana\",\"Orange\",\"Apple\",\"Mango\"]; a.sort(); console.log(a);//[\"Apple\", \"Banana\", \"Mango\", \"Orange\"] //数字排序的时候,因为转换成Unicode字符串之后,有些数会乱,这显然不是我们想要的 var a=[10,1,3,20,25,8]; console.log(a);//[10, 1, 3, 20, 25, 8] 比较函数的两个参数: sort的比较函数有两个默认参数,要在函数中接收这两个参数,这两个参数是数组中两个要比较的元素,通常我们用a和b接收两个将要比较的元素: 若比较函数返回值 若比较函数返回值=0,那么a和b相对位置不变; 若比较函数返回值>0,那么b排在a的前面; 对于sort()方法更深层级的内部实现以及处理机制可以看一下这篇文章深入了解javascript的sort方法 sort排序常见用法: 1.数组元素为数字的升序、降序: var array=[10,1,3,4,20,4,25,8]; //升序a-b2.数组多条件排序 var array=[{id:10,age:2},{id:5,age:4},{id:6,age:10},{id:9,age:6},{id:2,age:8},{id:10,age:9},{id:10,age:2}]; array.sort(function(a,b){ if(a.id===b.id){//如果id的值相等,按照age的值升序 return a.age-b.age; }else{ return a.id-b.id; } }) console.log(array);// [{\"id\":2,\"age\":8},{\"id\":5,\"age\":4},{\"id\":6,\"age\":10},{\"id\":9,\"age\":6},{\"id\":10,\"age\":2},{\"id\":10,\"age\":9}] 3.自定义比较函数。 类似的:运用好返回值,我们可以写出任意符合自己需求的比较函数 var array=[{name:'koro1'},{name:'koro1'},{name:'OB'},{name:'koro1'},{name:'OB'},{name:'OB'}]; array.sort(function(a,b){ if(a.name==='koro1'){//如果name是‘koro1’返回-1,-1reverse()颠倒数组中元素的顺序 定义:reverse()用于颠倒数组中元素的顺序。 参数:无。 var a=[1,2,3]; a.reverse(); console.log(a);//[3,2,1]; ES6: copyWithin()指定位置的成员复制到其他位置 定义:在当前数组内部,将指定位置的成员复制到其他位置,并返回这个数组。 语法: array.copyWithin(target,start=0,end=this.length) 参数: 三个参数都是数值,如果不是,会自动转为数组。 target(必选):从该位置开始替换数据。如果为负值,表示倒数。 start(可选):从该位置开始读取数据,默认为0。如果为负值,表示倒数。 end(可选):到该位置前停止读取数据,默认等于数组长度。使用负数可以从数组结尾处规定位置。 浏览器兼容(MDN): chrome 45,Edge 12,Firefox32,Opera 32,Safari 9, IE 不支持 eg: //-2相当于3号位,-1相当于4号位 var x=[1,2,3,4,5].copyWithin(0,-2,-1) console.log(x);//[4, 2, 3, 4, 5] var a=[1,2,3,4,5,6,7,8,9,10] //2位置开始被替换,3位置开始读取要替换的 5位置前面停止替换 var y=a.copyWithin(2,3,4); console.log(y);//[1, 2, 4, 4, 5, 6, 7, 8, 9, 10] console.log(a);/[1, 2, 4, 4, 5, 6, 7, 8, 9, 10] 从上述栗子: 第一个参数是开始被替换的元素位置 2.要替换数据的位置范围:从第二个参数是开始读取的元素,在第三个参数前面一个元素停止读取 3.数组的长度不会改变 4.读了几个元素就从开始被替换的地方替换几个元素。 ES6:fill()填充数组 定义:使用给定值,填充一个数组。 参数: 第一个元素(必须):要填充数组的值 第二个元素(可选):填充的开始位置,默认为0 第三个元素(可选):填充的结束位置,默认是this.length ['a','b','c'].fill(7);//[7,7,7] ['a','b','c'].fill(7,1,2);//['a',7,'c'] 不改变原数组的方法(8个): var a=[1,2,3]; ES5: a.slice()/a.join()/a.toLocateString()/a.toString/a.concat/a.indexOf/a.lastIndexOf ES7: a.includes() slice()浅拷贝数组的元素 定义:方法范湖一个从开始到结束(不包含结束)选择的数组的一部分浅拷贝到一个新数组对象,且原数组不会被修改。 注意:字符串也有一个slice()方法是用来提取字符串的,不要弄混了。 语法: array.slice(begin,end); 参数: begin(可选):索引数值,接受负值,从该索引处开始提取原数组中的元素,默认值为0。 end(可选):索引数值(不包括),接受负值,在该索引前结束提取原数组元素,默认值为数组末尾(包括最后最后一个元素)。 var a=['hello','world']; var b=a.slice(0,1); console.log(b);//['hello'] a[0]='改变原数组'; console.log(a);//[\"改变原数组\", \"world\"] console.log(b);//['hello'] b[0]='改变拷贝的数组'; console.log(a);//[\"改变原数组\", \"world\"] console.log(b);//[\"改变拷贝的数组\"] 如上:新数组是浅拷贝,元素是简单数据类型,改变之后不会互相干扰。 如果是负载类型数据(对象,数组)的话,改变其中一个,另一个也会改变、 var a=[{name:'OBKoro1'}]; var b=a.slice(); console.log(b);//[{\"name\":\"OBKoro1\"}] a[0].anme='改变原数组'; console.log(a);//[{\"name\":\"改变原数组\"}] console.log(b);//[{\"name\":\"改变原数组\"}] b[0].name='改变拷贝数组',b[0].koro='改变拷贝数组'; console.log(a);//[{\"name\":\"改变拷贝数组\",\"koro\":\"改变拷贝数组\"}] console.log(b);//[{\"name\":\"改变拷贝数组\",\"koro\":\"改变拷贝数组\"}] 原因在定义上说过了:slice()是浅拷贝,对于复杂的数据类型浅拷贝,拷贝的只是指向原数组的指针,所以无论改变原数组,还是浅拷贝的数组,都是改变原数组的数据。 join()数组转字符串 定义:join方法用于把数组中的所有元素通过指定的分隔符进行分隔放入一个字符串,返回生成的字符串。 语法: array.join(str) 参数: str(可选):指定要使用的分隔符,默认使用逗号作为分隔符。 var a=['hello','world']; var str=a.join(); console.log(str);//hello,world var str2=a.join('+'); console.log(str2)//hello+world var str3=a.join(' '); console.log(str3)//hello world 使用join方法或者下文说到的toString方法时,当数组中的元素也是数组或者是对象时会出现什么情况? var a=[['hello','world'],'!']; var str1=a.join(); console.log(str1);//hello,world,! var b=[{name:'hello world',age:'2018','!'}] var str2=b.join(); console.log(str2);//[object Object],! //对象转字符串推荐JSON.stringify(obj); 所以:join()/toString()方法在数组元素是数组的时候,会将里面的数组也调用join()/toString(),如果是对象的话,对象会被转换为[object Object]字符串。 toLocaleString()数组转字符串 定义:返回一个表示数组元素的字符串。该字符串由数组中的每个元素的toLocalString()返回值经调用join()方法连接(由逗号隔开)组成。 语法: array.toLocalString() 参数:无 eg: var a=[{name:'OBKorol'},23,'abcd',new Date()]; var str=a.toLocaleString(); console.log(str);//[object Object],23,abcd,2018/6/4 下午4:43:17 如上述栗子:调用数组的toLocaleString方法,数组中的每个元素都会调用自身的toLocalString方法,对象调用对象的toLocaleString,Date调用Date的toLocalString。 toString()数组转字符串 不推荐 定义:toString()方法可把数组换换为由逗号连接起来的字符串。 语法: array.toString() 参数:无 该方法的效果和join方法一样,都是用于数组转字符串的,但是与join方法相比没有优势,也不能自定义字符串的分隔符,因此不推荐使用。 值得注意的是:当数组和字符串操作的时候,js会调用这个方法将数组自动转换为字符串 var b=['toString','演示'].toString(); console.log(b);//toString,演示 var a=['调用toString','连接在我后面']+'啦啦啦啦'; console.log(a);//调用toString,连接在我后面啦啦啦啦 concat 定义:方法用于合并两个或多个数组,返回一个新数组。 语法: var newArr=oldArray.concat(array1,array2...arrayn) 参数: array1(可选):改参数可以是具体的值,也可以是数组对象。可以是任意多个。 eg: var a=[1,2,3]; var b=[4,5,6]; //连接两个数组 var newVal=a.concat(b); console.log(newVal);//[1, 2, 3, 4, 5, 6] var c=[7,8,9]; var newVal2=a.concat(b,c); console.log(newVal2);//[1, 2, 3, 4, 5, 6, 7, 8, 9] //添加元素 var newVal3=a.concat('添加元素',b,c,'再加一个'); console.log(newVal3);//[1, 2, 3, \"添加元素\", 4, 5, 6, 7, 8, 9, \"再加一个\"] //合并嵌套数组,会浅拷贝嵌套数组 var d=[1,2]; var f=[3,[4]]; var newVal4=d.concat(f); console.log(newVal4);//[1, 2, 3, [4]] ES6扩展运算符...合并数组: 因为ES6的语法更简洁易懂,所以现在合并数组我大部分采用...来处理,...运算符可以实现concat的每个栗子,且更简洁和具有高度自定义数组元素位置的效果。 var a=[2,3,4,5]; var b=[4,...a,4,4]; console.log(b);//[4, 2, 3, 4, 5, 4, 4] console.log(a);//[2, 3, 4, 5] indexOf()查找数组是否存在某个元素,返回下标 定义:返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1. 语法: array.indexOf(searchElement,fromIndex) 参数: searchElement(必须):被查找的元素 fromIndex(可选):开始查找的位置(不能大于等于数组的长度,返回-1),接受负值,默认为0。 严格相等的搜索: 数组的indexOf搜素跟字符串的indexOf不一样,数组的indexOf使用严格相等===搜索元素,即数组元素要完全匹配才能搜索成功。 注意:indexOf()不能识别NaN eg: var a=['啦啦',2,4,24,NaN]; console.log(a.indexOf('啦'));//-1 console.log(a.indexOf('NaN'));//-1 console.log(a.indexOf('啦啦'));/0 使用场景: 数组去重 根据获取的数组下标执行操作,改变数组中的值等。 判断是否存在,执行操作。 lastIndexOf()查找指定元素在数组中的最后一个位置 定义:方法放回指定元素在数组中最后一个的索引,如果不存在则返回-1。(从数组后面往前查找) 语法: arr.lastIndexOf(searchElement,fromIndex) 参数: searchElement(必须):被查找的元素 fromIndex(可选):逆向查找开始位置,默认值为数组的长度-1,即查找整个数组。 关于fromIndex有三个规则: 正值。如果该值大于或等于数组的长度,则整个数组会被查找。 负值。将其视为从数组末尾向前的偏移。(比如-2,从数组倒数第二个元素开始往前查找) 负值。其绝对值大于数组长度,则方法返回-1,即数组不会被查找。 var a=['OB',4,'Koro1',1,2,'Koro1',3,4,5,'Koro1']; var b=a.lastIndexOf('Koro1',4); // 从下标4开始往前找 返回下标2 console.log(b);//2 var b=a.lastIndexOf('Koro1',100); // 大于或数组的长度 查找整个数组 返回9 console.log(b);//9 var b=a.lastIndexOf('Koro1',-11); // -1 数组不会被查找 console.log(b);//-1 var b=a.lastIndexOf('Koro1',-9); // 从第二个元素4往前查找,没有找到 返回-1 console.log(b);//-1 ES7 includes()查找数组是否包含某个元素 返回布尔 定义:返回一个布尔值,表示某个元素是否包含给定的值 语法: array.includes(searchElement,fromIndex=0) 参数: searchElement(必选):被查找的元素 fromIndex(可选):默认值为0,参数表示搜索的起始位置,接受负值。正值超过数组长度,数组不会被搜索,返回false。负值绝对值超过长数组长度,重置从0开始搜索。 includes方法是为了弥补indexOf方法的缺陷而出现的: indexOf方法不能识别NaN indexOf方法检查时候包含某个值不够语义化,需要判断是否不等于-1,表达不够直观。 eg var a=['OB','Koro1',1,NaN]; var b=a.includes(NaN); // true 识别NaN console.log(b);//true var b=a.includes('Koro1',100); // false 超过数组长度 不搜索 console.log(b);//false var b=a.includes('Koro1',-100); // true 负值绝对值超过数组长度,搜索整个数组 console.log(b);//true 遍历方法(12个): js中遍历数组并不会改变原始数组的方法总共有12个: ES5: forEach/every/some/filter/map/reduce/reduceRight ES6: find/findIndex/keys/values/entries 关于遍历: 关于遍历的效率,可以看一下这篇详解JS遍历 尽量不要在遍历的时候,修改后面要遍历的值 尽量不要在遍历的时候修改数组的长度(删除/添加) forEach 定义:按升序为数组中含有有效值的每一项执行一次回调函数。 语法 array.forEach(function(currentValue,index,arr){},thisValue) 参数: function(必选):数组中每个元素需要调用的函数。 //回调函数的参数 1. curentValue(必须),数组当前元素的值 2. index(可选),当前元素的索引值 3. arr(可选),数组对象本身 thisValue(可选):当执行回调函数时this绑定对象的值,默认为undefined 关于forEach()你要知道: 无法中途退出循环,只能用return退出本次回到,进行下一次回调。】 它总是返回undefined值,即使你return了一个值。 下面类似语法同样适用于这些规则 1. 对于空数组是不会执行回调函数的 2. 对于已在迭代过程中删除的元素,或者空元素会跳过回调函数 3. 遍历次数再一次循环前就会确定,再添加到数组中的元素不会被遍历。 4. 如果已经存在的值被改变,则传递给callback的值是遍历到他们那一刻的值。 eg: var a=[1,2,,3];//最后第二个元素是空的,不会遍历(undefined,null会遍历) var obj={name:'OBKoro1'}; var result=a.forEach(function(value,index,array){ console.log(array); a[3]='改变元素'; a.push('添加到尾端,不会遍历'); console.log(value,'forEach传递的第一个参数');//分别打印1,2改变元素 console.log(this.name);//OBKoro1打印三次this绑定在obj对象上 //break;//break会报错 return value;//return只能结束本次回调,会执行下次回调 console.log('不会执行,因为return会执行下一次循环回调') },obj); console.log(result);//即使return了一个值,也还是返回undefined every检测数组所有元素是否都符合判断条件 定义:方法用于检测数组所有元素是否都符合函数定义的条件 语法: array.every(function(currentValue,index,arr),thisValue) 参数:(则几个方法的参数,语法都类似) function(必须):数组中每个元素需要调用的函数。 //回调函数的参数 1.currentValue(必须),数组当前元素的值 2.index(可选),当前元素的索引值 3.arr(可选),数组对象本身 thisValue(可选):当执行回调函数时this绑定对象的值,默认值为undefined 方法返回值规则: 如果数组中检测到与一个元素不满足,则整个表达式返回false,且剩余的元素不会再进行检测。 2.如果所有元素都满足条件,则返回true。 eg: function isBigEnuough(element,index,array){ return element>=10;//判断数组中的所有元素是否都大于10 } var result=[12,5,8,130,44].every(isBigEnough);//false console.log(result);//false var result=[12,54,18,130,44].every(isBigEnough);//true console.log(result);//true //接受箭头函数写法 [12,5,8,130,44].every(x=>x>=10);//false [12,54,18,130,44].every(x=>x>=10);//true some数组中是否有满足判断条件的语句 定义:数组中是否有满足条件判断的元素 语法: array.some(function(currentValue,index,arr),thisValue) 参数:(这几个方法的参数,语法都类似) function(必须):数组中每个元素需要调用的函数。 //回调函数的参数 1. currentValue(必须),数组当前元素的值 2. index(可选),当前元素的索引值 3. arr(可选),数组对象本身 thisValue(可选):当执行回调函数时this绑定的值,默认为undefined 方法返回值规则: 如果有一个元素满足条件,则表达式返回true,剩余的元素不会再执行检测。 如果没有满足的条件,则返回false。 eg: function isBigEnough(element,index,arr){ return (element>=10);//数组中是否有一个元素大于10 } var result=[2,5,8,1,4].some(isBigEnough); console.log(result);//false var result=[12,5,8,1,4].some(isBigEnough); console.log(result);//true filter 过滤原始数组,返回新数组 定义:返回一个新数组,其包含通过所提供函数实现的测试的所有元素。 语法: var new_array=arr.filter(function(currentValue,index,arr),thisArg) 参数:(这几个方法的参数,语法都类似) function(必须):数组中每个元素需要调用的函数。 //回调函数的参数 1. currentValue(必须),数组当前元素的值 2. index(可选),当前元素的索引值 3. arr(可选),数组对象本身 thisArg(可选):当执行回调函数this绑定对象的值,默认值为undefined eg var a=[32,33,16,40]; var result=a.filter(function(value,index,arr){ return value>=18; }) console.log(result);//[32,33,40] map 对数组中的每个元素进行梳理,返回新的数组 定义:创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 语法: var new_array=arr.map(function(currentValue,index,arr),thisArg) 参数:(这几个方法的参数,语法都类似) function(必须):数组中每个元素需要调用的函数。 //回调函数的参数 1. currentValue(必须),数组当前元素的值 2. index(可选),当前元素的索引值 3. arr(可选),数组对象本身 thisArg(可选):当执行回调函数时this绑定对象的值,默认为undefined。 eg var a=['1','2','3','4','5']; var result=a.map(function(value,index,array){ return value+'新数组的新元素' }); console.log(a);//[\"1\", \"2\", \"3\", \"4\", \"5\"] console.log(result)[\"1新数组的新元素\", \"2新数组的新元素\", \"3新数组的新元素\", \"4新数组的新元素\", \"5新数组的新元素\"] reduce为数组提供累加器,合并为一个值 定义:reduce()方法对累加器和数组中的每个元素(从左到有,应用一个函数,最终合并为一个值。 语法: arry.reduce(function(total,currentValue,currentIndex,arr),initialvlue) 参数: function(必须):数组中每个元素需要调用的函数。 //回调函数的参数 1. total(必须),初始值,或者上一次调用回调返回的值 2. currentValue(必须),数组当前元素的值 3. index(可选),当前元素的索引值 4. arr(可选),数组对象本身 initialValue(可选):指定第一次回调的第一个参数 回调第一次执行时: 如果initialValue在调用reduce时被提供,那么第一个total将等于initialValue,此时currentValue等于数组中的第一个值。 如果initialValue未被提供,那么total等于数组中的第一个值,currentValue等于数组中的第二个值,此时如果数组为空,那么将抛出TypeError。 如果数组仅有一个元素,并且,没有提供initialValue,或提供了initialValue但数组为空,那么回调不会被执行,数组的唯一值将被返回。 eg: //数组求和 var sum=[0,1,2,3].reduce(function(a,b){ return a+b; },10); console.log(sum);//16 var flattened=[[0,1],[2,3],[4,5]].reduce((a,b)=>a.concat(b),[]) console.log(flattened);//[0, 1, 2, 3, 4, 5] reduceRight 从右至走累加 这个方法除了与reduce执行方向相反外,其他完全与其一致,请参考上述reduce方法介绍。 ES6: find()&findIndex()根据条件找到数组成员 find()定义:用于找到第一个符合条件的数组成员,并返回该成员,如果没有符合条件的成员,则返回undefined。 finderIndex()定义:返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。 语法: var new_array=arr.find(function(currentValue,index,arr),thisArg) var new_array=arr.findIndex(function(currentValue,index,arr),thisArg) 参数:(这几个方法的参数,语法都类似) function(必须):数组中每个元素需要调用的函数。 //回调函数的参数 1. currentValue(必须),数组当前元素的值 2. index(可选),当前元素的索引值 3. arr(可选),数组对象本身 thisArg(可选):当执行回调函数时this绑定对象的值,默认为undefined 这两个方法都可以识别NaN,弥补了indexOf的不足。 eg: //find var a=[1,2,-5,10].find((n)=>nObject.is(NaN,n)); console.log(b);//NaN //findIndex var a=[1,4,-5,10].findIndex((n)=>nObject.is(NaN,n)); console.log(b)//4 浏览器兼容(MDN):Chrome 45,Firefox 25,Opera 32, Safari 8, Edge yes, ES6 keys()&values()&entries()遍历键名、遍历键值、遍历键名+键值 定义:三个方法都返回一个新的Array Iterator对象,对象根据方法不同包含不同的值、 语法: array.keys(); array.values(); array.entries(); 参数:无。 eg: for( var index of ['a','b'].keys()){ console.log(index);//0 1 } for( var elem of ['a','b'].values()){ console.log(elem);//a b } for( var [index,elem] of ['a','b'].entries()){ console.log(index, elem);// 0 \"a\" 1 \"b\" } 在for...of中如果遍历中途要退出,可以使用break退出循环。 如果不使用for...of玄幻,可以是手动调用遍历器对象的next方法,进行遍历: var letter=['a','b','c']; var entries=letter.entries(); console.log(entries.next().value);//[0, 'a'] console.log(entries.next().value);//[1, 'b'] console.log(entries.next().value);//[2, 'c'] entries()浏览器兼容性(MDN):Chrome 38, Firefox 28,Opera 25,Safari 7.1 keys()浏览器兼容性(MDN):Chrome 38, Firefox 28,Opera 25,Safari 8, 注意:目前只有Safari 9支持,,其他浏览器未实现,babel转码器也还未实现 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:10:29 "},"js/ES6的了解.html":{"url":"js/ES6的了解.html","title":"ES6的了解","keywords":"","body":" 新增模板字符串(为JavaScript提供了简单的字符串插值功能) 箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs) for-of(用来遍历数据-例如数组中的值) arguments对象可被不定参数和默认参数完美替代。 ES6将promise对象纳入规范,提供了原生的Promise对象。 增加了let和const命令,用来声明变量。 增加了块级作用域,let命令实际上就增加了块级作用域。ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性;let命令,const命令,class命名声明的全局变量,不属于全部对象的属性 引入module模块的概念。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:02:14 "},"js/实现一个深克隆.html":{"url":"js/实现一个深克隆.html","title":"实现一个深克隆","keywords":"","body":"参考 面试官:请你实现一个深克隆 前言 实现一个深克隆是面试中常见的问题,可是绝大多数面试者的答案都不是完整的,甚至是错误的,这个时候面试不断追问,看看你到底理解不理解深克隆的原理,很多情况下一些一知半解的面试者就原型毕露了。 我们就开看一下如何实现一个深克隆,当然面试中没有让你完整实现的时候,但是你一定要搞清楚其中的坑在哪里,才可以轻松应对面试官的追问。 在要实现一个深克隆之前我们需要了解一下JavaScript中的基础类型 JavaScript中最基础类型 JavaScript原始类型:Undefined、Null、Boolean、Number、String、Symbol JavaScript引用类型:Object 二、进阶 基本类型就是浅拷贝,引用类型就是深拷贝,如果要深拷贝一个对象,可以用Object.assign()(浅拷贝),jQuery 的$.extend()方法。可以用object.create 1.对象的深浅拷贝 var a={name:'yy',age:26}; var b=new Object(); b.name=a.name; b.age=a.age; a.name='xx'; console.log(b);//Object { name=\"yy\", age=26} console.log(a);//Object { name=\"xx\", age=26} var deepCopy= function(source) { var result={}; for (var key in source) { result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key]; } return result; } 2.对象或数组的深拷贝 util.cloneObj=function (obj) { var objType = Object.prototype.toString.call(obj); if(objType === '[object Array]' || objType === '[object Object]') { var temp = (objType === '[object Array]') ? [] : {} ; for(var k in obj) { temp[k] = util.cloneObj(obj[k]); } return temp; } return obj; } 浅克隆 浅克隆之所以被称为浅克隆,是因为对象只会被克隆最外部的一层,至于更深层的对象,则依然是通过引用指向同一块堆内存。 //浅克隆 function shallowClone(o){ const obj={}; for(let i in o){ obj[i]=o[i]; } return obj; } //被克隆对象 const oldObj={ a:1, b:['e','f','g'], c:{h:{i:2}} } const newObj=shallowClone(oldObj); console.log(newObj.c.h,oldObj.c.h);//{i: 2} {i: 2} console.log(oldObj.c.h===newObj.c.h);//true 我们可以看到,很明显虽然oldObj.c.h被克隆了,但是它还是与oldObj.c.h相等,这表明他们依然指向同一段堆内存,这就造成了如果对newObj.c.h进行修改,也会影响oldObj.c.h这就不是一版好的克隆。 newObj.c.h.i='change'; console.log(newObj.c.h,oldObj.c.h);//{i: \"change\"} {i: \"change\"} 我们改变了newObj.c.h.i的值,oldObj.c.h.i也被改变了,这就是浅克隆的问题所在。 当然有一个新的apiObject.assign()也可以实现浅复制,但是效果跟上面没有差别,不再细讲。 2.深克隆 2.1 JSON.parse方法 前几年微博上流传着一个传说中最便捷实现深克隆的方法,JSON对象parse方法可以将JSON字符串反序列化成JS对象,stringify方法可以将JS对象序列化成JSON字符串,这两个方法结合起来就能产生一个便捷的深克隆。 const newObj=JSON.parse(JSON.stringify(oldObj)); 我们依然用上一节的列子进行测试 const oldObj={ a:1, b:['e','f','g'], c:{h:{i:2}} }; const newObj=JSON.parse(JSON.stringify(oldObj)); console.log(newObj.c.h,oldObj.c.h);//{i: 2} {i: 2} console.log(oldObj.c.h===newObj.c.h);//false newObj.c.h.i='change'; console.log(newObj.c.h,oldObj.c.h);//{i: \"change\"} {i: 2} 果然,这是一个实现深克隆的好方法,但是这个解决方法是不是太过简单了。 确实,这个方法可以解决绝大部分使用场景,但是却有很多坑。 他无法实现对函数,RegExp等特殊对象的克隆 会抛弃对象的constructor,所有的构造函数会指向Object 对象有循环引用,会报错 主要的坑就是以上几点,我们一一测试下。 //构造函数 function person(pname){ this.name=pname; } const Messi=new person('Mession'); //函数 function say(){ console.log('hi'); } const oldObj={ a:say, b:new Array(1), c:new RegExp('ab+c','i'), d:Messi } const newObj=JSON.parse(JSON.stringify(oldObj)); //无法复制函数 console.log(newObj.a,oldObj.a);//undefined ƒ say(){ console.log('hi');} //稀疏数组复制错误 cosnole.log(newObj.b[0],oldObj.b[0]);//null undefined //无法复制正则对象 console.log(newObj.c,oldObj.c);//{} /ab+c/i //构造函数指向错误 console.log(newObj.d.constructor,oldObj.d.constructor);//ƒ Object() } 我们可以看到在对函数、正则对象、稀疏数组等对象克隆时会反生意外,构造函数指向也会反生错误。 const oldObj={}; oldObj.a=oldObj; const newObj=JSON.parse(JSON.stringify(oldObj));//Converting circular structure to JSON cosnole.log(newObj.a,oldObj.a); 对象的循环引用会抛出错误。 2.2 构造一个深克隆函数 我们知道要想实现一个靠谱的深克隆方法,上一节提到的序列/反序列是不可能了,而通常教程里提到的方法是不靠谱的,他们存在的问题跟上一节序列反序列操作中凸显的问题是一致的。 function isArray(arr){ return Object.prototype.toString.call(arr)==='[object Array]'; } //深度克隆 function deepClone(obj){ if(typeof obj!='object'&&typeof!=='function'){ return obj;//原始类型直接返回 } } Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:36:53 "},"js/闭包.html":{"url":"js/闭包.html","title":"闭包","keywords":"","body":"参考链接:学习Javascript闭包(Closure) 详解js闭包 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念。 闭包有三个特性: 函数嵌套函数 函数内部可以引用外部的参数和变量 参数和变量不会被垃圾回收机制回收 1.闭包的概念 闭包就是能够读取其他函数内部函数的函数。 可以把闭包简单理解成“定义在一个函数内部的函数” 2.闭包的用途 1)可以读取函数内部的变量2)让这些变量的值始终保存在内存中。 function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000 3.使用闭包的注意点 1) 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。2) 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当做对象(object)使用,把闭包当做的它的公用方法(public Method),把内部变量当做它的私有属性(private value),这时一定要小心,不要随便改变父函数内部的值。 4. 思考题 题1 var name = \"The Window\"; var object = { name : \"My Object\", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); 题2 var name = \"The Window\"; var object = { name : \"My Object\", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()()); 例子: var data = []; for (var k = 0; k var data = []; for (var k = 0; k 经典闭包例子 ``` function createFuns(){ var result = new Array(); for(var i = 0;i /* result[i] = function(arg){ return function(){ return arg; } }(i);//此处匿名函数立即执行的()可以省略,因为function在等号右边出现,不存在歧义(一般形式是(function(){})()) */ } return result; } 闭包,有一个老生常谈的话题,可以用一句话对之概括:有权访问另一个函数作用域内变量的函数都是闭包。例如 function outer(){ var a=0; function inner(){ console.log(a++); } return inner; } var closure=outer(); closure();//1 closure();//2 ``` 这里返回的inner函数就是能够访问outer函数中变量的闭包,除inner函数之外的外部作用域都无法访问outer函数中的变量a。 闭包特性: 函数返回嵌套的函数形成闭包 闭包内部可以访问外部的参数和变量 外包参数和变量在被闭包引用时不会被垃圾回收机制回收 闭包优点: 可避免变量对全局的污染 允许函数私有成员的存在 允许变量常驻内存 闭包缺点: 由于变量常驻内存,增大内存使用量,使用不当很容易造成内存泄露。 闭包应用场景: 采用函数引用方式的setTimeout函数 将函数关联到对象的实例方法 封装相关的功能集 JS垃圾回收机制原理 JavaScript中的垃圾回收,主要是一种针对程序执行环境中内存的管理机制,该机制最大限度的又花了JS程序对操作系统内存的使用。垃圾回收机制也同样非常容易理解:就是利用垃圾收集器,周期性的回收哪些程序中,不被其他引用所指向的变量的内存资源。不被其他引用所执向的变量就是程序中不会在用到的变量,也就是生命周期结束的变量,这种变量多为局部变量,而全局变量只有在关闭浏览器或终止当前运行环境的情况下其生命周期才会结束。所以此时垃圾收集器所要做的就是周期性的检索程序中处于结束状态的变量,同时回收它们所占的内存资源。 而闭包的使用则无疑会增加程序对内存资源的占用,因为在闭包中存储着对外部变量的引用,所以只要闭包中存储的外部引用未停止使用,那么外部变量就永远存在,且其所占的内存无法被垃圾回收机制所释放。因此合理的使用闭包,能优化程序的执行效率及降低程序的资源占有率。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:05:49 "},"js/事件循环.html":{"url":"js/事件循环.html","title":"事件循环","keywords":"","body":"参考网址 -JavaScript中的事件循环 Event Loop 例1 async function async1(){ console.log('async1 start') await async2() console.log('async1 end') } async function async2(){ console.log('async2') } console.log('script start') setTimeout(function(){ console.log('setTimeout') },0) async1(); new Promise(function(resolve){ console.log('promise1') resolve(); }).then(function(){ console.log('promise2') }) console.log('script end') 例2 console.log('script start'); setTimeout(function() { console.log('timeout1'); }, 10); new Promise(resolve => { console.log('promise1'); resolve(); setTimeout(() => console.log('timeout2'), 10); }).then(function() { console.log('then1') }) console.log('script end'); 解析 console.log('script start'); //同步输出——1 setTimeout(function() { console.log('timeout1'); //异步宏任务,推入事件队列——5 }, 10); new Promise(resolve => { console.log('promise1'); //同步输出——2 resolve(); //同步执行 setTimeout(() => console.log('timeout2'), 10); //异步宏任务,推入事件队列——6 }).then(function() { console.log('then1') //异步微任务, 在执行队列之后,事件队列之前执行——4 }) console.log('script end'); //同步输出——3 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:30:36 "},"js/基本类型,判断方法.html":{"url":"js/基本类型,判断方法.html","title":"基本类型,判断方法","keywords":"","body":"一、六种数据类型 原始类型(基本类型):按值访问,可以操作保存在变量中实际的值。 Number,String,Boolean,Undefined,Null 原始数据类型中Null和Undefined比较特殊 引用类型:引用类型的值是白村在内存中的对象。object(function,array,date...) 与其他语言不同的是,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是操作对象的引用而不是实际的对象。所以引用类型的值是按引用访问的。 二、隐式转换 1、+和- 巧用+和-规则转换类型把变量转成数字:num-0; 把变量转成字符串:num+'';s \"1\"- -\"1\"//2 \"1\"- -\"1\"+\"1\"//\"21\" 2、a==b 类型相同,同===类型不同,尝试类型转换和比较; NaN==NaN//false new Object==new Object 3、 a===b 类型不同,返回false 类型相同: null===null//true undefined===undefined//true NaN===NaN//false new Object===new Object//false 三、包装对象 基本类型中的number,string和boolean都有对应的包装类型。 把一个基本类型尝试用对象的方式使用它的时候,比如访问length属性,或者增加一些属性的操作时,JavaScript会把这些基本类型转换为对应的包装类型对象。 str,number和true都有包装类型,所以可以把数字用括号括起来调用toString()方法 四、类型检测 JavaScript中类型检测方法有很多: typeofinstanceofObject.prototype.toStringconstructorduck type 1. typeof 最常见的就是typeof: typeof 100 \"number\" typeof true \"boolean\" typeof function(){} \"object\" typeof undefined \"undefined\" typeof new Object() \"object\" typeof [1,3] \"object\" typeof NaN \"number\" typeof null \"object\" 比较特殊的是typeof null 返回\"object\"typeof 对基本类型和函数对象很方便,但是其他类型就没办法了。判断一个对象是不是数组?用typeof返回\"object\"。对对象的判断通常用instanceof instanceof 基于原型链操作。obj instanceof Object左操作数未对象,不是就返回false,右操作数必须是函数对象或者函数构造器,不是就返回typeError异常。原理:判断左边的左操作数的对象的原型链上是否有右边这个构造函数的prototype属性。 任何一个构造函数都有一个prototype对象属性,这个对象属性将用作new出来的对象的原型。 instanceof在判断对象是不是数组,Data,正则等时很好用。 instanceof 坑:不同window或iframe之间的对象类型检测不能使用instanceof Object.prototype.toString 需要注意的是IE6/7/8中,Object.prototype.apply(null)返回\"[object Object]\"\" 4、 constructor Student.prototype.construct==Student//true 任何对象都有constructor属性,继承自原型的,constructor会指向构造这个对象的构造器或构造函数。 constructor可以被改写,多以要小心 5. duck type 比如不知道一个对象是不是数组,可以判断它的length是不是数字,它是不是join,push这样一些数组的方法。通过一些特征判断对象是否属于某些类型,这个有时候也常用 Object.prototype.toString.apply([1,2])//\"[object Array]\" Object.prototype.toString.apply(\"123\")//\"[object String]\" Object.prototype.toString.apply(123)//\"[object Number]\" Object.prototype.toString.apply(true)//\"[object Boolean]\" Object.prototype.toString.apply(null)//\"[object Null]\" Object.prototype.toString.apply(undefined)//\"[object Undefined]\" Object.prototype.toString.apply(function(){})//\"[object Function]\" Object.prototype.toString.apply({})//\"[object Object]\" 6.如何检测一个变量是字符串 有另外一种方法,将变量和空字符串拼接后再和原来变量做全等判断 var str=\"hello\"; var temp=str+\"\"; temp===str//true 7.类型检测小结 typeof 适合基本类型及服function检测,遇到null失效。 class 通过{}.toString拿到,适合内置对象和基本类型,遇到null和undefined会失效(IE6,7,8等返回[object Object]). instanceof 适合自定义对象,也可以用来检测原生对象,在不同的iframe和window间检测失效。 ECMAScript的基本数据类型有5种:Undefined、Null、Boolean、Number、string。 其中Boolean、Number、String属于原始类型、Undefined、Null属于原始值。 原始类型代表了各自类型的所有成员,原始值则代表了各自特殊类型的唯一成员。 ECMAScript的复合类型有1种:Object(对象类型)。 Object是一种复合值,它将很多值(原始类型/值或者其他对象)聚合在一起,通过属性的形式进行访问。 ECMAScript的特殊对象类型:Array、Function、Math、Date、JSON、RegExp、Error,每种类型都各自代表一种独立的类,不同的类实例拥有不同的类特性以及对应的操作方式。 null和undefined的区别? null是一个表示\"无\"的对象,转为数值时为0;undefined是一个表示\"无\"的原始值,转为数值时为NaN。 当声明的变量还未被初始化时,变量的默认值为undefined。 null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。 undefined表示\"缺少值\",就是此处应该有一个值,但是还没有定义。典型用法是: 变量被声明了,但没有赋值时,就等于undefined。 应该提供的参数没有提供,该参数等于undefined。 对象没有赋值的属性,该属性的值为undefined。 函数没有返回值时,默认返回undefined。 null 表示\"没有对象\",即该处不应该有值。典型用法是: 作为函数的参数,表示该函数的参数不是对象。 作为对象原型链的终点。 ECMAScript常见的数据类型划分方式: 原始类型(Boolean,Number、String、undefined、null)、对象类型 值类型(undefined、number、string、boolean)、引用类型(函数、数组、对象、null、new Number) 可变类型、不可变类型 可拥有方法类型、不可拥有方法类型 精准区分数据类型的判断方法:Object.prototype.toString.call(); Object.prototype.toString.apply([1,2])//\"[object Array]\" Object.prototype.toString.apply(\"123\")//\"[object String]\" Object.prototype.toString.apply(123)//\"[object Number]\" Object.prototype.toString.apply(true)//\"[object Boolean]\" Object.prototype.toString.apply(null)//\"[object Null]\" Object.prototype.toString.apply(undefined)//\"[object Undefined]\" Object.prototype.toString.apply(function(){})//\"[object Function]\" Object.prototype.toString.apply({})//\"[object Object]\" 值类型的类型判断用typeof,引用类型的类型判断用instanceof,两者皆为操作符 function show(x) { console.log(typeof x); // undefined console.log(typeof 10); // number console.log(typeof 'abc'); // string console.log(typeof true); // boolean console.log(typeof function () {}); //function console.log(typeof [1, 'a', true]); //object console.log(typeof { a: 10, b: 20 }); //object console.log(typeof null); //object console.log(typeof new Number(10)); //object console.log(typeof (Object));//function console.log(typeof (Array));//function console.log(typeof function x(){})//function console.log(typeof {});//object console.log(typeof Object)//function console.log(typeof Function)//function console.log(typeof [1,2,3]);// object console.log(typeof Array) //function console.log(typeof Array());//object console.log(Object instanceof Function);//true console.log(Function instanceof Object);//true console.log(Function instanceof Function);//true } show(); 判断一个变量是否是数组 var a = []; // 1.基于instanceof a instanceof Array; // 2.基于constructor a.constructor === Array; // 3.基于Object.prototype.isPrototypeOf Array.prototype.isPrototypeOf(a); // 4.基于getPrototypeOf Object.getPrototypeOf(a) === Array.prototype; // 5.基于Object.prototype.toString Object.prototype.toString.apply(a) === '[object Array]'; // 6.Array.isArray Array.isArray([]); // true 以上,除了Object.prototype.toString外,其它方法都不能正确判断变量的类型。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:25:24 "},"js/VOAO.html":{"url":"js/VOAO.html","title":"VO AO","keywords":"","body":"深入理解JavaScript系列(12):变量对象(Variable Object) 深入理解JavaScript系列(13):This? Yes,this! 看不懂 VO 变量对象 AO 活动对象 alert(x); // function var x = 10; alert(x); // 10 x = 20; function x() {}; alert(x); // 20 为什么第一个alert “x” 的返回值是function,而且它还是在“x” 声明之前访问的“x” 的?为什么不是10或20呢?因为,根据规范函数声明是在当进入上下文时填入的; 同意周期,在进入上下文的时候还有一个变量声明“x”,那么正如我们在上一个阶段所说,变量声明在顺序上跟在函数声明和形式参数声明之后,而且在这个进入上下文阶段,变量声明不会干扰VO中已经存在的同名函数声明或形式参数声明,因此,在进入上下文时,VO的结构如下: VO = {}; VO['x'] = // 找到var x = 10; // 如果function \"x\"没有已经声明的话 // 这时候\"x\"的值应该是undefined // 但是这个case里变量声明没有影响同名的function的值 VO['x'] = 紧接着,在执行代码阶段,VO做如下修改: VO['x'] = 10; VO['x'] = 20; 参考网址 前端基础进阶(三):变量对象详解 在介绍变量对象与活动对象前,首先我们需要更深入的理解执行上文的声明周期,执行上下文的声明周期分为两个阶段: 第一个阶段是创建阶段,每当JS引擎在执行一段可执行代码时,都会先进入创建阶段。该阶段会分别创建变量对象,建立作用域链,以及确定this的指向。作用域链和this指向会在后文阐述。 所谓变量对象就是用于存储在执行上下文中定义的变量和函数声明,在当前上下文中每找到一个变量声明,就会在变量对象中建立一个同名的属性,每找到一个函数声明,就会建立一个以函数名命名的属性,属性值则为指向该函数所在内存地址的引用。这些预先建立好的属性以及属性值,存储着该上下文所有的变量数据,为后续代码的执行奠定基础。 第二个阶段是执行阶段,当变量对象、作用域链、this指向都建立之后,执行上下文会进入到执行阶段。在该阶段中变量对象会转换为活动对象,此时活动对象中的属性都允许被访问,并且可以执行其他数据性的操作。 两者区别: 执行上下文处于创建阶段时,变量对象中的属性是不允许被访问的的。但是在进入到执行阶段后,变量对象转化为活动对象,并且里面的属性都允许被外界访问。其实两者都属于同一个对象,只是处于执行上下文的不同生命周期而已 console.log(foo); // function foo function foo() { console.log('function foo') } var foo = 20; // 上例的执行顺序为 // 首先将所有函数声明放入变量对象中 function foo() { console.log('function foo') } // 其次将所有变量声明放入变量对象中,但是因为foo已经存在同名函数,因此此时会跳过undefined的赋值 // var foo = undefined; // 然后开始执行阶段代码的执行 console.log(foo); // function foo foo = 20; 变量对象和活动对象有什么区别:他们其实都是同一个对象,只是处于执行上下文的不同生命周期。不过只有处于函数调用栈栈顶的执行上下文中的变量对象,才会变成活动对象。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:48:41 "},"js/执行上下文.html":{"url":"js/执行上下文.html","title":"执行上下文","keywords":"","body":" 执行上下文环境中有如何数据: 变量、函数表达式一一变量声明,默认赋值为undefined; this一一赋值 函数声明一一赋值 js的执行上下文可以理解为当前代码的执行环境,在执行结束程序时,没遇到一段JS可执行代码,都会创建一个可执行上下文。 JS当中可执行代码分为三种:全局代码、函数代码、eval代码。所以一段JS程序必定会产生多个执行上下文,而JavaScript引擎则是以堆栈的形式来对齐进行管理,也就是常说的函数调用栈。 栈底是全局上下文,栈顶则是当前正在执行的上下文。例如 var global=\"globalStack\"; function threeStack(){ var three=\"threeStack\"; function twoStack(){ var two=\"twoStack\"; eval(console.log(\"oneStack\")); console.log(two); } twoStack(); console.log(three); } threeStack(); 执行上下文在函数调用栈中的顺序为(自底向上):globalStack=》threeStack=》twoStack=》oneStack 特性 1.单线程 2.同步执行,只有栈顶的上下文处于执行执行中,其他上下文需要等待 全局上下文只有唯一的一个,它在浏览器关闭时出栈 4.函数的执行上下文的个数没有限制 5.每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:46:42 "},"js/Json对象与Json字符串互转.html":{"url":"js/Json对象与Json字符串互转.html","title":"Json对象与Json字符串互转","keywords":"","body":"1.jQuery插件支持的转换方式: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象 2.浏览器支持的转换方式(Firefox,chrome,opera,safari,ie9,ie8)等浏览器: JSON.parse(jsonstr); //可以将json字符串转换成json对象 JSON.stringify(jsonobj); //可以将json对象转换成json对符串 注:ie8(兼容模式),ie7和ie6没有JSON对象,推荐采用JSON官方的方式,引入json.js。 3.Javascript支持的转换方式: eval('(' + jsonstr + ')'); //可以将json字符串转换成json对象,注意需要在json字符外包裹一对小括号 注:ie8(兼容模式),ie7和ie6也可以使用eval()将字符串转为JSON对象,但不推荐这些方式,这种方式不安全eval会执行json串中的表达式。 4.JSON官方的转换方式: http://www.json.org/提供了一个json.js,这样ie8(兼容模式),ie7和ie6就可以支持JSON对象以及其stringify()和parse()方法; 可以在https://github.com/douglascrockford/JSON-js上获取到这个js,一般现在用json2.js。 PS:这里再为大家提供几款功能十分强大的json解析、转换与格式化工具供大家选择使用,相信对于大家接下来的json格式数据处理会有所帮助: 在线JSON代码检验、检验、美化、格式化工具: http://tools.jb51.net/code/json 在线XML/JSON互相转换: http://tools.jb51.net/code/xmljson json代码在线格式化/美化/压缩/编辑/转换工具: http://tools.jb51.net/code/jsoncodeformat C语言风格/HTML/CSS/json代码格式化美化工具: http://tools.jb51.net/code/ccode_html_css_json Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:51:05 "},"js/JavaScript中函数声明优先于变量声明.html":{"url":"js/JavaScript中函数声明优先于变量声明.html","title":"JavaScript中函数声明优先于变量声明","keywords":"","body":"同一个标识符,先后用var和function声明它,最后是什么呢? var a;//声明一个变量,标识符为a function a(){//声明一个函数,标识符也为a } console.log(typeof a);//function 显示的是“function”,即function的优先级高于var。 有人觉得这是代码顺序执行的原因,即a被后执行的function覆盖了。好,将它们调换下。 function a(){//声明一个函数,标识符也为a } var a;//声明一个变量,标识符为a console.log(typeof a);//function 结果仍然显示的是“function”而非“undefined”。即函数声明优先于变量声明。 我们把代码稍作修改,声明a同时赋值。 function a(){//声明一个函数,标识符也为a } var a=2;//声明一个变量,标识符为a console.log(typeof a);//number 这时显示的是“number”却不是function了,这相当于 function a(){//声明一个函数,标识符也为a } var a; a=2;//声明一个变量,标识符为a console.log(typeof a);//number 即把“var a=1”拆分为两步,a被重新赋值了,自然是最后的那个值。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:52:05 "},"js/this指向.html":{"url":"js/this指向.html","title":"this指向","keywords":"","body":" 嗨,你真的懂this吗 this的指向是由它所在函数调用的上下文决定的,而不是由它所在函数定义的上下文决定的 this的指向问题无疑是JavaScript语言中必须掌握的核心概念。上文提到,在执行上下文创建的阶段,就会创建this执向。而更细致的说,this的指向,是在函数被调用的时候确认的。 下面是this执行的4种场景: 1.如果一个函数中有this,但是它没有以对象方法的形式调用,而是以函数名的形式执行,那么this指向的就是全局对象。 funtion test(){ console.log(this); } test()//window 2.如果一个函数中有this,并且这个函数是以对象方法的形式调用,那么this指向就是调用该方法的对象。 var obj={ test:function(){ console.log(this); } } obj.test()//obj 3.如果一个函数中有this,并且包含该函数的对象也同时被两一个对象所包含的,尽管这个函数是被最外层的对象所调用。this指向的也只是它上一级的对象。 var obj={ test:{ fun:function(){ console.log(this); } } } obj.test.fun();//test 4.如果一个构造函数或类方法中有this,那么它指向由该构造函数或类创建出来的实例对象。 class Test{ constructor(){ this.test=\"test\";//类实例 } option(){ console.log(this);//类实例 } } Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-04-26 17:39:51 "},"js/创建ajax的过程.html":{"url":"js/创建ajax的过程.html","title":"创建ajax的过程","keywords":"","body":" 创建XMLHttpRequest对象,也就是创建一个异步调用对象。 创建一个新的HTTP请求,并指定该HTTP请求的方法,URL及验证信息。 设置相应HTTP请求状态变化的函数。 发送HTTP请求。 获取异步调用返回的数据。 使用JavaScript和DoM实现局部刷新。 var xmlHttp=new XMLHttpRequest(); xmlHttp.open('GET','demo.php',true) xmlHttp.send() xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState===4&&xmlHttp.status==200){ } } 详情:[JavaScript学习总结(七)Ajax和Http状态](https://segmentfault.com/a/1190000000691919) Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-05-06 16:07:04 "},"js/函数式编程.html":{"url":"js/函数式编程.html","title":"函数式编程","keywords":"","body":"JavaScript并不是专门的函数式编程语言,但却能够应用函数式编程技术,像对象一样去操控函数。下面就列举一些JS函数式编程的典型应用: 使用非函数式的方式计算数组中元素的平均值和标准差 var data=[1,2,3,5,5];//待处理数组 var total=0; for (var i=0;i使用函数式的编程方式 var sum=function(x,y){ return x+y; } var square=function(x){ return x*y; } var data=[1,1,3,5,5]; var mean=data.reduce(sum)/data.length; var deviations=data.map(function(x){ return x-mean; }) var stddev=Math.sqrt(deviations.map(square).reduce(sum)/(data.length-1)); Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:03:52 "},"js/类和模块.html":{"url":"js/类和模块.html","title":"类和模块","keywords":"","body":"类的概念 JavaScript是一种弱类型语言,其本身并不像Java等语言那样对数据具有很强的类型区分,所以为了能够具有面向对象的编码风格,以其独有的方式实现了类的机制。在JavaScript中,类的实现是基于原型(prototype)继承机制的,如果两个实例都从同一个原型对象上继承了属性,可以说它们是属于同一个类的实例。类让每一个成员对象都共享某些属性,这种属性共享的方式在编程中占有举足轻重的地位。 ES5中的类:在ES5中,类是由函数来定义的,定义类的函数陈志伟构造函数。一般这类函数会以首字符大写的形式出现,普通的函数和方法都是以小写字母开头,对象实例化时通过new关键字来调用构造函数。构造函数上挂载着一个prototype属性,该属性存放的是当前类的原型对象,原型对象是类的核心,用于为每一个实例对象提供公有属性。原型对象中还拥有一个constructor属性,用于指向当前类的构造函数。构造函数是类的“公共标识”,而原型对象是类的“唯一标识”。以下是一个类,用于表示点的坐标: function Point(x,y){ this.xlocation=x; this.ylocation=y; } Point.prototype={ xtranslation:function(x){ this.xlocation=this.xlocation+x; }, ytranslation:function(y){ this.ylocation=this.ylocation+y; }, toString:function(){ return \"(\"+this.xlocation+\",\"+this.ylocation+\")\"; } } ES6中的类:在ES6中,类的表示就更具语义化,写法上更类似与传统的面向对象语言,它引入了class关键字作为类的标识,并将ES5中的prototype的constructor属性直接作为其内部的构造函数,并且在定义类方法时不需要添加function关键字,类方法之间也不需要用逗号进行分隔。类中的静态方法和静态属性用static关键字标识,一旦类函数和类属性用static关键字标记后,实例对象将不会继承这些属性和方法,只能通过类本身来调用。同样用ES6中的类来表示上述的例子: class Point{ constructor(x,y){ this.xlocation=x; this.ylocation=y; } static func(){ console.log(\"point static function!!!\") } xtranslation(x){ this.xlocation=this.xlocation+x; } ytranslation(y){ this.ylocation=this.ylocation+y; } toString(){ return \"(\"+this.xlocation+\",\"+this.ylocation+\")\"; } } 模块化 JavaScript模块化的历史由来已久,也并非小编用几行的篇幅就能一语带过,在和仅对它的特性及应用场景进行笼统的说明,如有对其原委感兴趣的读者,可以搜索其他更详细的相关资料。 先来说CommonJS,CommonJS模块化规范主要应用于服务器编程,加载模块的方式属于同步加载,只有在加载完成之后才能执行后续操作。一个.js文件就是一个CommonJS模块,在服务器端的模块文件一般都保存在本地硬盘,所以加载速度较快。每一个模块都有自己的作用域,里面定义的变量、函数、类都是私有的,对其他文件不可见。NodeJs、webpack就是以CommonJS规范的形式来实现的。 CommonJs模块特点: 所有代码都运行在模块作用域,不会污染全局作用域。 模块可以多次加载,但是只会在第一次加载运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。想要让模块再次运行,必须清除缓存。 模块加载的顺序,按照其在代码中出现的顺序。 在浏览器环境中,对于模块的下载很大程序上取决于网速的快慢,因此极有可能出现长时间等待现象,从未阻塞浏览器的渲染。所以就必须采用异步模式(AMD,CMD)。AMD模块规范采用异步加载方式,主要用于客户端浏览器环境下,但即可用于浏览器端也可用于服务端,CMD则专注于浏览器的模块化开发。 AMD和CMD的区别:两者的区别在于对模块的加载和执行方式不同,AMD会在加载完模块的同时去执行模块,从未拥有延迟低、效率高的特性;CMD则是加载完所有依赖模块后,再进入程序,遇到需要执行的模块才会执行相应的操作。 RequireJS是基于AMD规范实现的模块加载器 seaJS是基于CMD规范实现的模块加载器 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:05:06 "},"js/模块化.html":{"url":"js/模块化.html","title":"模块化","keywords":"","body":"说说你对AMD和commonjs的理解 commonJS是服务器端模块的规范,nodejs采用了这个规范。commonJS规范加载模块时同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。 AMD推荐的风格通过返回一个对象作为模块对象,commonJS的风格通过对module.exports或exports的属性赋值来达到暴露模块对象的目的。 详情:也谈webpack及其开发模式 说说你对MVC和MVVC的理解 MVC view 传送指令到controller Controller 完成业务逻辑后,要求model改变状态 model将新的数据发送到view,用户得到反馈 所有的通信都是单向的。 angular它采用双向绑定(data-binding:view的变动,自动反映在viewModel,反之亦然) 组成部分Model、view、viewModel view:UI界面 viewModel:它是view的抽象,负责view与model之间信息的转换,将view的command传送到model; model:数据访问层 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:19:01 "},"js/js延迟加载的方式有哪些.html":{"url":"js/js延迟加载的方式有哪些.html","title":"js延迟加载的方式有哪些","keywords":"","body":" defer和async 动态创建DOM方式(创建sript,插入到DOM中,加载完毕后callBack) 按需异步载入js 1.异步加载的方案: 动态插入script标签 2.通过ajax去获取js代码,然后通过eval执行 3.script标签上添加defer或者async属性 4.创建并插入iframe,让它异步执行js 5.延迟加载:有些 js 代码并不是页面初始化的时候就立刻需要的,而稍后的某些情况才需要的。 defer并行加载js文件,会按照页面上script标签的顺序执行 async并行加载js文件,下载完成立即执行,不会按照页面上script标签的顺序执行 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-04-30 14:49:48 "},"js/你觉得jQuery或Zepto源码有哪些写的好的地方.html":{"url":"js/你觉得jQuery或Zepto源码有哪些写的好的地方.html","title":"你觉得jQuery或Zepto源码有哪些写的好的地方","keywords":"","body":"jQuery源码封装在一个匿名函数的自执行环境中,有助于防止变量的全局污染,然后通过传入window对象参数,可以实window对象作为局部变量使用,好处是当jQuery中访问window对象的时候,就不用将作用域链退回到顶层作用域了,从而可以更快的访问window对象。同样,传入undefined参数,可以缩短查找undefined时的作用域链。 (function( window, undefined ) { //用一个函数域包起来,就是所谓的沙箱 //在这里边var定义的变量,属于这个函数域内的局部变量,避免污染全局 //把当前沙箱需要的外部变量通过函数参数引入进来 //只要保证参数对内提供的接口的一致性,你还可以随意替换传进来的这个参数 window.jQuery = window.$ = jQuery; })( window ); jQuery 将一些原型属性和方法封装在了jQuery.prototype中,为了缩短名称,又赋值给了jquery.fn,这是很形象的写法。 有一些数组或对象的方法经常能使用到,jQuery将其保存为局部变量以提高访问速度。 jQuery实现的链式调用可以节约代码,所返回的都是同一个对象,可以提高代码效率。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:35:12 "},"js/快速排序的思想并实现一个.html":{"url":"js/快速排序的思想并实现一个.html","title":"快速排序的思想并实现一个","keywords":"","body":"“快速排序”的思想很简单,整个排序过程只需要三步: 在数据集之中,找一个基准点 建立两个数组,分别存储左边和右边的数组 利用递归进行下次比较 function quickSort(arr){ if(arr.lengthCopyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:35:59 "},"js/用过哪些设计模式.html":{"url":"js/用过哪些设计模式.html","title":"用过哪些设计模式","keywords":"","body":" 工厂模式: 主要好处就是可以消除对象间的耦合,通过使用工程方法而不是new关键字。将所有实例化的代码集中在一个位置当值代码重复。 工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。 function createObject(name,age,profession){//集中实例化的函数var obj = new Object(); obj.name = name; obj.age = age; obj.profession = profession; obj.move = function () { return this.name + ' at ' + this.age + ' engaged in ' + this.profession; }; return obj; } var test1 = createObject('trigkit4',22,'programmer');//第一个实例var test2 = createObject('mike',25,'engineer');//第二个实例 构造函数模式 使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题,该模式与工厂模式的不同之处在于: 构造函数方法没有显示的创建对象(new Object()); 直接将属性和方法赋值给this对象; 没有return语句。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-21 10:47:33 "},"js/Flash、ajax各自的优缺点,在使用中如何取舍.html":{"url":"js/Flash、ajax各自的优缺点,在使用中如何取舍.html","title":"Flash、ajax各自的优缺点,在使用中如何取舍","keywords":"","body":" flash适合处理多媒体、矢量图形、访问机器;对css、处理文本上不足。不容易被搜索。 Ajax对css,文本支持很好,支持搜索;多媒体,矢量图形,机器访问不足。 共同点:与服务器的无刷新传递消息,用户离线和在线状态,操作DOM Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-21 10:48:37 "},"js/JS页面性能类.html":{"url":"js/JS页面性能类.html","title":"页面性能类","keywords":"","body":"JS页面性能类 一、问题 题目: 1.提升页面性能的方法有哪些? 2.和缓存相关的http头有哪些?能写出来几个? 二、 回答 1.提升页面性能的方法有哪些? 1)资源压缩合并,减少HTTP请求(资源传输的过程变小) 2)非核心的代码异步加载 3)利用浏览器缓存 4)使用CDN 5)预解析DNS 1). 资源压缩合并,减少HTTP请求(资源传输的过程变小); 2).非核心的代码异步加载—异步加载的方式—异步加载的区别; - 异步加载的方式: 1.动态脚本加载 js动态创建一个标签,把标签最后加到body或者head上去(追加到文档中实现加载) var loadScript=document.createElement('script'); loadScript.setAttribute(\"type\",\"text/javascript\"); loadScript.setAttribute('src',loadUrl); console.log(loadUrl) document.getElementsByTagName(\"head\")[0].appendChild(loadScript); 2.defer 3.async - 异步加载的区别 1.defer是在HTML解析完之后才会执行,如果是多个,按照加载顺序依次执行; 2.async是在加载完成之后立即执行,如果是多个,执行顺序和加载顺序无关; - 异步加载原理:任何一个时刻都只能做一件事 1.defer:新加载的,在HTML解析完之前,是不会执行的,defer能保证按你的加载顺序依次执行; 2.async:哪个先回来,哪个先执行,和加载顺序无关; 3).利用浏览器缓存-缓存的分类-缓存的原理; 1.缓存的分类 (强缓存与协商缓存) 缓存:对应文件在浏览器中存在的备份,把请求的东西缓存到本地了(本地磁盘中),浏览器下次请求相当于从本地磁盘读取文件,不需要去服务端获取。 1.强缓存 http协议头: Expires Expires:Thu,21 Jan 2017 23:39:02 GMT Cache-Control Cahe-Control : Max-age=3600 强缓存:在强缓存的时间范围内,不与服务端进行通信,直接获取本地资源渲染。Expires为绝对时间,为服务端的时间,传到客户端来,可能导致两边时间不一致,Cache-Control为相对时间,从取到资源的那一秒开始计算,在多少秒内不再去服务端请求资源。 HTTP协议头: 在请求一个文件的时候,http头上(响应头上)会带两个东西(有可能是2个,也有可能是1个,根据服务器配置); 响应头中会有key,value Expires 过期时间; value值表示的是绝对时间(服务器的绝对时间,这个时间是服务器下发的) 判断客户端当前的时候是不是这个时间,比较的时候是按浏览器本地的时间做比较,下发的是服务器端的时间,会有偏差; 缺点:有可能客户端和服务器的时间不一致。 Cache-Control value值 Max-age=3600(相对时间) 不管客户端和服务器时间是否一致,它最后是以客户端相对时间为止,时间单位是秒(拿到资源之后再3600s之内不会再去请求服务器,在这个时间之内直接去浏览器拿缓存) *如果服务器两个时间都下发了,依哪个时间为准呢? 以后者相对时间为准(这个规定) 2.协商缓存 Last-Modified If-Modified-Since Last-Modified:Wed,26 Jan 2017 00:35:11 GMT Etag If-None-Match 协商缓存:浏览器发现本地有这个副本,但是又不确定用不用他,去服务端问一下这个文件是否可用(浏览器与服务端协商) Last-Modified: Last-Modified(服务器下发的上次修改的时间) 在拿到这个文件的时候,浏览器会给这个资源文件的http响应头中加一个Last-Modified,value值就是时间; If-Modified-Since:(请求中给服务器带的,服务器要对比,所以一来一回,两个东西) 当强缓存失效(过期了),浏览器在这个时间之外又开始请求了,不确定这个东西有没有变化,要携带上次给的时间是哪一个,请求的时候会以携带这个字段的时间。(拿到新资源文件,会通过Last-Modified下发一个时间,当下次请求问服务器这个资源有没有发生变化,是用http请求 头中加If-Modified-Since(key值),他们两个值是一个) *缺点:虽然hash值变了,内容并没有变化,完全可以从副本拿,Etag就是解决这个问题的。 Etag: Etag(哈希值): 服务器给你这个资源的时候会给一个Etag值,当过了强缓存的时间,浏览器在问服务器请求问它这个资源可不可以在用的时候, 会通过这个http中加一个key值(If-None-Math)一个value,那么value就是发的那个Etag值。 If-None-Match 4)使用CDN(网络优化,CDN加载资源非常快); CDN可以让客户以最快的时间把资源请求过来;(让网络库快速到达服务器端把文件下载下来;) 当页面第一次打开的时候,浏览器缓存是起不了作用的,使用CDN效果是非常明显的 5)预解析DNS 页面中所有的a标签,在一些高级浏览器中默认打开了DNS预解析的(不加这句话,a标签也是可以做到DNS预解析的,这是浏览器的一个功能);但是如果你的页面https协议头的,很多浏览器默认关闭DNS预解析的。这句话是强制打开a标签的DNS预解析。 怎么使用预解析DNS呢 从浏览器输入一个url到页面真正的渲染中间发生了哪些环节/ 从输入 URL 到页面加载完成的过程中都发生了什么事情? 2.和缓存相关的http头有哪些?能写出来几个? Expires Cache-Control Last-Modified Etag If-None-Match 参考 无 其他 无 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-04 18:39:40 "},"html/":{"url":"html/","title":"html","keywords":"","body":"网上资源 chrome开发者工具各种骚技巧 Chrome控制台实用指南 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-04-22 11:28:36 "},"html/安全类.html":{"url":"html/安全类.html","title":"安全类","keywords":"","body":"安全类 问题 什么是CSRF 什么是XSS sql注入 回答 前端安全:随着前端技术的发展,安全问题已经从服务器悄然来到了每一个用户的面前,盗取用户数据,制造恶意的可以自我复制的蠕虫代码,让病毒在用户间传播,使服务器当掉,更有甚者可能会在用户不知觉得情况下,让用户成为攻击者,这绝对不是骇人听闻。富客户端的应用越来越广,前端的安全问题随之增多。常见的攻击方法有CSRF、XSS和SQL注入 1.CSRF 1)基本概念和缩写 -- 跨站点请求伪造:Cross-Site Request Forgery 缩写CSRF 2)攻击原理 用户是网站A的注册用户,通过身份验证登录网站A,登录之后网站A核查身份是否正确,如果正确就下发cookie,这个cookie保存到用户浏览器当中,这就是完成了一次身份认证的过程。 用户又访问了网站B,网站B会给用户下发用户页面的时候,会存在引诱的一个点击,这个点击往往是一个连接,就是指向网站A的一个API接口,接口是GET类型的,比如:www.xxx.com/hack,指向存在漏洞的接口,当用户经不住引诱点击了这个东西,这个点击就访问了A网站,访问A网站这个连接的时候,浏览器会自动上传Cookie,上传之后网站A觉得A这个cookie拿过来之后对身份重新认证,发现是合法用户,就执行了这个接口的动作。 重点:用户在注册网站登录过,没有登录会提示登录; CSRF能够造成攻击的原理:(实现CSRF攻击不可缺失的两个因素) 网站中某一个接口存在漏洞 这个用户在注册网站确实登录过 3)防御措施 加Token验证 访问接口的时候,浏览器自动上传cookie,但是没有手动上传一个Token,这个Token是你注册成功之后,或者没有注册,只有你访问了这个网站,服务器会自动向你本地存储一个Token,在你访问各种接口的时候,如果没有带Token,就不能帮你通过验证,如果只是点击了引诱连接,这个指挥自动携带cookie,不会自动携带Token,所以就避免了那个攻击。 Referer验证 Referer指的是页面来源,如果服务器判断页面来的是否是该站点下面的页面,如果是就执行操作,不是就拦截 隐藏令牌 和Token有点像,做法:隐藏在http的head头中,不会放在链接上,这样就做的比较隐蔽。本质上没有太大的区别。只是使用方式有一点差别。 2. XSS 1)基本概念和缩写 -- 跨域脚本攻击:Cross-Site Scripting 缩写XSS 2)攻击原理及类型 原理 攻击者往web页面里插入恶意html标签或者JavaScript代码。比如,攻击者在论坛里放一个看似安全的链接,骗取用户点击后,窃取cookie中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点。 类型 XSS反射型攻击:恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。 XSS存储型攻击:恶意代码被保存到目标网站的服务器中,这种攻击具有较强的稳定性和持久性,比较常见场景是在博客,论坛等社交网站上,但OA系统,和CRM系统上也能看到它身影 攻击能做些什么 .窃取cookies,读取目标网站的cookie发送到黑客的服务器上 读取用户未公开的资料,如果:邮件列表或者内容、系统的客户资料,联系人列表等等 增加安全性 首先,避免直接在cookie中泄露用户隐私,例如email、密码等。 其次,避免使用cookie和系统ip绑定来降低cookie泄露后的危险。这样攻击者得到的cookie没有实际价值,不可能拿来重放。 如果网站不需要在浏览器端对cookie进行操作,可以在set-cookie末尾加上httpOnly来防止JavaScript代码直接获取cookie。 尽量采用POST而非get提交表单 http://www.immoc.com/learn/812 3)防御措施 在表单提交或者url参数传递前,对需要的参数进行过滤,请看如下XSS过滤工具类代码 过滤用户输入的 检查用户输入的内容中是否有非法内容。如<>(尖括号)、”(引号)、 ‘(单引号)、%(百分比符号)、;(分号)、()(括号)、&(& 符号)、+(加号)等。、严格控制输出 任何内容写到页面之前都必须加以encode,避免不小心把HTML tag弄出来 http://www.immoc.com/learn/812 4)和CSRF的区别 XSS不需要做任何的登录认证,核心原理向你页面注入脚本; eg:比如评论区:如果评论区注入XSS最好的方式可以在你提交区里面写上script标签,img标签上加事件,总之,它的方法利用你合法的渠道向你页面注入js,这是XSS攻击原理。 XSS是向你页面注入js运行,然后js函数体里面做它想做的事情。 CSRF利用你本身的漏洞,去帮你自动执行哪些接口。 --- 这两种方式是不一样的,CSRF要依赖用户,要登录网站。 5)总结 关于名称要把中文意思说出来 原理说清楚 防御措施 3.sql注入原理 就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命名 总的来说有以下几点: 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双“-”进行转换等。 永远不要使用动态拼接SQL。可以使用参数化的SQL或直接使用存储过程进行数据查询存取。 永远不要使用管理员权限的数据库连接,为每个应用单独的权限有限的数据库连接。 不要把机密信息明文存放,请加密或hash掉密码和敏感的信息。 延伸 哪些会造成内存泄漏 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-08 18:28:56 "},"html/通信类.html":{"url":"html/通信类.html","title":"通信类","keywords":"","body":"通信类 问题 什么是同源策略及限制 前后端如何通信 如何创建Ajax 跨域通信的几种方式 回答 1. 什么是同源策略及限制 同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互。(这是一个用于隔离潜在恶意文件的关键的安全机制。) 一个源包括:协议、域名、端口 限制:不是一个源的文档没有权利去操作另一个源的文档 主要限制在几个方面: Cookie、LocalStorage和IndexDB 无法读取 -- 操作不了Cookie、LocalStorage、IndexDB DOM 无法获得 -- 无法获取和操作另一个资源的DOM Ajax请求不能发送 -- Ajax只适合同源的通信(跨域的不支持) 2. 前后端如何通信 1.Ajax -- 同源下的通信方式 Web Socket -- 不受同源策略的限制 CORS -- 支持跨域通信,也支持同源通信 3. 如何创建Ajax XMLHttpRequest对象的工作流程 兼容性处理 事件的触发条件 事件的触发顺序 function ajx(){ //1.创建一个对象(兼容IE6写法) var xhr=XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject('Mircrosoft.XMLHTTP'); //2.连接服务器,确定对象的发送方式:xhr.open(type,url,true); //3.发送请求 xhr.send(); //4.接受服务器返回(响应) xhr.onreadyStateChange=function(){ if(xhr.readyState==4){//完成 //如果加载媒体资源需要再加上xhr.statue===206 (媒体资源特别大,不是一次性返回过来的,是资源的一部分; 服务端给你下发的http状态码是206,这个地方不加206,是收不到响应的) if(xhr.status===200||xhr.status=304){ //处理成功 }else{ //失败处理 } } } } 4. 跨域通信的几种方式 1)JSONP 在什么时候用: -- 在出现postMessage、CORS之前一直用JSONP做跨域通信的; 怎么做到的: -- 利用script标签的异步加载来实现的; (script加载不受跨域限制)-- 这就是JSONP能够实现的一个最初的基本原理; 怎么实现的: -- 需要给服务端传递一个回调的名,这个回调的名就是我用加载script标签的方式发出一个请求去,你给我返回一块内容,这个内容是一个js块也就是scrip的块,这个块中有回调名加在代码就能运行了 原理 -- 利用script标签发出请求,告诉服务端callback的的名称,将来作为函数名来返回的,既然是函数名,要创建一个函数,所以在调用jsonp的时候,本地必须有一个jsonp的这个全局函数,后面才能把给的数据能执行出来,当函数来运行。 callback后面名字叫什么都可以 -- 告诉它一个回调的名称,而且要在window注册一个全局的一个函数,然后下面的createScript就是要动态创建一个script标签,最后返回这个东西。最后script.onload是监听脚本的加载事件,如果响应完了也会响应onload,然后判断onload是不是成功,成功了以后看能不能拿到那个数据。最后不要忘记删除这个函数变量window[callbackName]=null;最后往html中增加script标签目的就是把这个请求发送出去。 服务器给你下发的是一个script内容,利用回调的东西,执行了后面的代码 box({ data:{ } }) jsonp.js box({name:'xxx'}); function createJs(sUrl){ var oScript=document.createElment('script'); oScript.type=\"text/javascript\"; oScript.src=sUrl; document.getElementByTagName('head')[0].appendChild(oScript); } createJs('jsonp.js?callback=box'); function box(json){ alert(json.name); } 2) Hash(url地址中#后面的东西) -- Hash的变动页面不会刷新 url中?后面的叫search:search的改变是会刷新页面的;所有search不能做跨域通信; //利用hash,场景是当前页面A通过iframe或frame嵌入了跨域的页面B,跨域给B发消息 //在A中伪代码如下 var B=document.getElementsByTagName('iframe'); B.src=B.src+\"#\"+'data'; //在B 中的伪代码如下 window.onhashchange=function(){ var data=window.location.hash; } 跨域给B发送消息: 先拿到B这个窗口的地址src,然后通过hash的方式后面发送一段字符串,这个字符串可以是通过完成的json,最后通过json.stringify()把json转成字符串发送给B,你是发出去了,B能不能接受到,需要在B自己的代码中增加一个window.onhashchange,这个事件是用来监听你当前页面的hash有没有改变,之前的页面是src,现在的页面加一个hash,所以对B来说,B的url的hash变化了,就可以拿到了。拿到以后通过window.location.hah就能拿到hash的具体内容了。 window.localtion.hash可不是拿到一个,如果hash后面等于data除了A发送过来的东西还有别的拼接,回来要特殊处理一下。 3)postMessage(html5新增加的处理跨域通信的) 同源策略的目标就是限制跨域通信,但是实际业务中又需要跨域通信; html5中出现了这个标准postMessage,用这个实现跨域通信; //窗口A(http:A.com)向跨域的窗口B(http:B.com)发送消息 Awindow.postMessage('data','http://B.com'); //在窗口B中监听 Bwindow.addEventListener('message',function(evebt){ console.log(event.origin); console.log(event.source); console.log(event.data); },false); 怎么发送 在A窗口,给谁发送,要选中哪个窗口,调用postMessage这个API,第一个参数是发送的数据部分,在这里推荐使用字符串格式;第二个是接受方式哪个源,*是可以给任何窗口发送(很多窗口都能接受到你的信息,这个是不安全的),推荐的一个做法是加上一个源; 发送方怎么接受: B窗口要做哪些事情呢?就是要监听message事件, window.addEventListener('message',响应函数,true/false指定捕获还是冒泡); 要拿的就是下面这三个参数 //来判断发送者的源,在你的响应程序中,你要选择性的接收;比如我只接收来自A.com的信息,其他的一律不接收,那么就通过event.origin这个属性来判断 console.log(event.origin); console.log(event.source);//引用A窗口的对象 console.log(event.data);//发送的消息通过event.data拿到数据 4)WebSocket(不受同源策略限制,拿来跨域通信正合适) 【参考资料】http://www.ruanyifeng.com/blog/2017/05/websocket.html 声明一个webScocket对象,这个地方有两种,ws,wss区别是一个加密,一个非加密,后面指向服务器的一个地址,这个样就相当于建立了一个JS对象来管理这个链接。 var ws=new WebSocket('wss://echo.websocket.org'); 请求发送出去 ws.onopen=function(evt){ console.log('Connectio open ...'); ws.send('Hello WebScokets'); } 对方给消息怎么接受,通过这个参数的data来拿到 ws.onmessage=function(evt){ console.log('Received Message:',evt.data); ws.close(); } 最后这个链接不用了,中断了,监听onclose来确定是不是关闭了 ws.onclose=function(){ console.log('Connection closed'); } 5)CORS -- Ajax一个变种,fetch实现CORS通信的--新出的通信标准,可以理解为支持跨域通信的Ajax 【参考资料】http://www.ruanyifeng.com/blog/2016/04/cors.html Ajax是不能发送跨域通信的,浏览器在识别你用Ajax发送了一个跨域请求的时候,它会在你http头中加上一个origin,来允许跨域通信。如果不加这个头,就是一个普通的AJax,遇到跨域通信,浏览器就会拦截(非法的不允许请求)。 // url(必选),options(可选),then就是回调成功,回调类似ES6的promise的写法; catch就是捕获错误。 fetch('/some/url/', { method: 'get', }).then(function (response) { }).catch(function (err) { // 出错了,等价于 then 的第二个参数,但这样更好用更直观 }); *CROS为什么就能支持跨域的这种通信? 浏览器会拦截ajax请求,如果它觉得这个ajax请求是跨域的,它会在http请求中,加一个origin 参考链接 前端常见跨域解决方案 Cookie、sessionStorage、localStorage的区别 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-08 16:11:25 "},"html/HTTP协议.html":{"url":"html/HTTP协议.html","title":"HTTP协议","keywords":"","body":"HTTP协议 问题 HTTP协议的主要特点 HTTP报文的组成部分 HTTP方法 POST和GET的区别 HTTP状态码 HTTP持久连接 什么是管线化 HTTPS HTTP2.0 常见HTTP首部字段 HTTP1.1和HTTP1.0的区别? HTTP与TCP如何协同工作的,TCP怎么确保HTTP传输的稳定有序 ? 回答 1. HTTP协议的主要特点 1.简单快捷 每个资源url都是固定的,一个页面地址一张图片叫做统一资源符,这个是固定的,所以在http协议中处理也是非常简单的。我想访问这个一个地址,只要输入这一个url就可以了。 2.灵活 在http协议中有的头部会有一个数据类型,通过一个http协议就可以完成不同数据类型的传输。 3.无连接 连接一次它就会掉,不会保持连接; 4.无状态 客户端和服务端是两种身份,客户端需要向服务端请求一个图片,那么http协议建立连接,帮你中间传输。这次任务完成以后,连接就要断开了,下次客户端再过来服务端是没法区分上一次连接和这一次连接是不是同一个身份。因为服务端是没有记住你的状态的。但从http协议上是不能区分两次连者的身份的。 2. HTTP报文的组成部分 浏览器向服务器要一个html文档或者一个图片时,输入xxxx.com,相当于客户端发出的请求报文;发出去了,服务端接受到了以后做出响应,要不要给你这份文档的内容,这个就是响应报文; 请求报文: 请求行(GET/HTTP/1.1) 包含:http方法、页面地址、http协议、版本 请求头 key、value值来告诉服务端要哪些内容,注意哪些类型 空行 当遇到空行就知道不是在请求头部分了,就改当请求体来解析了 请求体 响应报文: 状态行(HTTP/1.1 200 ok --http状态码) 响应头 key、value值来告诉服务端要哪些内容,主要哪些类型 空行 响应体 比如返回的图片 3. HTTP方法 GET------获取资源 POST-----传输资源 PUT------修改资源 DELETE---删除资源(一般业务是不删除资源的,标记) HEAD-----获取报文首部 GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器 POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。 PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。 HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效。 DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件。 OPTIONS:查询相应URI支持的HTTP方法。 4. POST和GET的区别 1.GET在浏览器回退时是无害的,而POST会再次提交请求 2.GET产生的URL地址可以被收藏,而POST不可以 3.GET请求会被浏览器主动缓存,而POST不会,除非手动设置 4.GET请求只能进行URL编码,而POST支持多种编码方式 5.GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留 -- 想把参数留在浏览器历史记录里用GET,为了防止crsf攻击,大部分get改为POSt 如果业务需要把参数留在浏览器历史记录中,记得把POST改为GET。 6.GET请求在URL中传送的参数是有长度限制的(2kb),而post没有限制 如果用的是GET请求,拼接的URL不要太长,否则会被浏览器截断,因为http协议对这个长度是有限制的。 发布出去,导致截断这种情况,一段被截断,你的服务器拿不到正确的地址,获取不到资源的。 7.对参数的数据类型,GET只接受ASCII字符,而post没有限制 8.GET比POST更不安全,因为蚕食直接暴露在URL上,所以不嫩用来传递敏感信息 9.GET参数通过URL传递,POST放在Request body中 5. HTTP状态码 1XX :提示信息--表示请求已接受,继续处理 2xx:成功--表示请求已经被成功接受 200 ok:客户端请求成功 204:请求被受理但没有资源可以返回 206 Partial Content:客户端发送了一个带有Range(范围)头的GET请求,服务器完成了它 (客户端请求一部分内容,在http head头中有一个range范围,请求0-10000字节,服务器就 返回一个206,服务器的文件是完整的,这个时候看到range头,按照range头从整个文件中截取一部分响应 给你,你响应体中只有你range头中指定的内容)使用video播放视频地址,audio播放音频地址,当视频文件、音频文件很大的时候基本都是返回的206; 3xx:重定向--要完成请求必须进行更进一步的操作 301 Moved Permanently:(永久重定向)所请求的页面已经转移至新的URL 302 Found:(临时重定向)所请求的页面已经临时转移至新的URL 303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上 304 Not Modified:客户端有缓冲的文档并发出一个条件下的请求,服务器告诉客户端,原来缓存的文档还可以继续使用。 (服务器告诉浏览器已经有缓存了,可以直接从缓存中去取文档用,不用去服务器取了) 304缓存的原理 服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该几号传回服务器要求服务器验证其(客户端)缓存。 304是HTTP状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到这个状态码后,会使用浏览器已缓存的文件 客户端请求一个页面(A)。服务端返回页面A,并在A加上一个ETag。客户端展现该页面,并将页面连同ETag一起缓存,客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上课客户端请求之后还未被修改。直接返回响应304(未修改——not modified)好一个空的响应体 307:临时重定向,与302类似,只是强制要求使用POST方法 4xx:客户端错误-- 请求有语法错误或请求无法实现 400 Bad Request:客户端请求有语法错误,不能被服务器所理解; 401 Unauthorized:请求未经授权,这个状态码必须和WWW-Authenticate报头域一起使用; 403 Forbidde:对被请求页面的访问被禁止(资源禁止被访问) (看到一个页面中一个地址,这个地址真的访问又不允许直接访问,只能通过服务器去访问;) 404 Not Found:请求资源不存在; 5xx:服务器错误--服务器未能实现合法的请求 500 Internal Server Error:服务器发生不可预期的错误,原来缓存的文档还可以继续使用; 503 Server Unavailable:请求未完成,服务器临时过载或宕机,一段时间后可能恢复正常。 6. HTTP持久连接 HTTP是支持持久连接的,1.1版本才支持,1.0版本支持 非持久连接: HTTP 协议采用“请求-应答”模式,当使用普通模式,即非Keep-Alive(持久连接)模式时,每个请求/应答客户端和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议) 持久连接 当使用Keep-Alive模式(持久连接,连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后续请求时,Keep-Alive功能避免了建立或者重新建立连接。 HTTP1.1版本新特性 a、默认持久连接节省通信量,只要客户端服务端任意一端没有明确提出断开TCP连接,就一直保持连接,可以发送多次HTTP请求 b、管线化,客户端可以同时发出多个HTTP请求,而不用一个个等待响应 c、断点续传原理 7. 什么是管线化 请求和响应共用一个通道,这个通道是持久建立的,不是我请求一次你响应一次,而是把请求打包一次传输过去,你也打包一次响应过来 在使用持久连接的情况下,某个连接上消息的传递类似于: --请求1-->响应1-->请求2-->响应2-->请求3-->响应3(表示整个连接没有中断过) 某个连接上的消息变成了类似这样:(持久连接情况下完成的管线化) 请求1-->请求2-->请求3-->响应1-->响应2-->响应3 管线化机制通过持久连接完成,仅HTTP/1.1支持此技术; 只有GET和HEAD请求可以进行管线化,而POST则有所限制; 初次建立连接时不会启动管线机制,因为对方(服务器)不一定支持HTTP/1.1版本的协议; 管线化不会影响响应到来的顺序,返回的顺序不会改变 HTTP/1.1要求服务器端支持管线化,但并不要求服务器端也会响应进行管线化处理,只是要求对于管线化的请求不失败即可; 由于上面提到的服务器问题,开启管线化很可能并不会带来大幅度的性能提升,而且很多服务器端和代理程序对管线化的支持并不好,因此现代浏览器如Chrome和Firefox默认未开启管线化支持。 总结:1. 工作原理:将请求响应打包回来(通过持久连接完成,需要HTTP/1.1支持); 2.只有GET和HEAD请求可以进行管线化,POST有所限制 3.连接的时候不要启动管线限制,因为对方可能不支持(初次连接的时候)。 8. HTTPS HTTP的缺点 a、通信使用明文不加密,内容可能被窃听 -b、不验证通信方身份,可能遭到伪装- c、无法验证报文完整性,可能被篡改 HTTPS HTTP协议通常承载于TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL和TSL),这个时候,就成了 我们常说的HTTPS。 默认HTTP的端口号是80.HTTPS的端口号是443 为什么HTTPS安全 因为网络请求需要中间有很多的服务器路由器的转发。中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有。HTTPS之所以比http安全,是因为他利用ssl/tls协议传输。它包含证书,卸载,流量转发,负载均衡,页面适配,浏览器适配,refer传递等。保障了传输过程的安全性 9.HTTP2.0 HTTP/2引入了“服务端推(server push)”的概念,它允许服务端在客户需要数据之前就主动将数据发送到客户缓存中,从而提高性能 HTTP/2提供更多的加密支持 HTTP/2使用多路技术,允许多个消息在一个连接上同时交差。 它增加了头压缩(head compression),因此即使非常小的请求,其请求和响应的header都只会占很小比例的贷款。 10.常见HTTP首部字段 a、通用首部字段(请求报文与响应报文都会使用的首部字段) Date:创建报文时间 Connection:连接的管理 Cache-Control:缓存的控制Transfer-Encoding:报文主体的传输编码方式 b、请求首部字段(请求报文会使用的首部字段) Host:请求资源所在服务器 Accept:可处理的媒体类型 Accept-Charset:可接收的字符集 Accept-Encoding:可接受的内容编码 Accept-Language:可接受的自然语言 c、响应首部字段(响应报文会使用的首部字段) Accept-Ranges:可接受的字节范围 Location:令客户端重新定向到的URI Server:HTTP服务器的安装信息 d、实体首部字段(请求报文与响应报文的的实体部分使用的首部字段) Allow:资源可支持的HTTP方法 Content-Type:实体主类的类型 Content-Encoding:实体主体适用的编码方式 Content-Language:实体主体的自然语言 Content-Length:实体主体的的字节数 Content-Range:实体主体的位置范围,一般用于发出部分请求时使用 11. HTTP1.1和HTTP1.0的区别? 在同一个tcp的连接中可以传送多个HTTP请求和响应. 多个请求和响应可以重叠,多个请求和响应可以同时进行. 更加多的请求头和响应头(比如HTTP1.0没有host的字段). 总之,在 HTTP/1.0 中,大多实现为每个请求/响应交换使用新的连接。在 HTTP/1.1 中,一个连接可用于一次或多次请求/响应交换,尽管连接可能由于各种原因被关闭.这是他们之间最大区别 TCP 有一个特性叫做 slow start,其含义可以大致这样解释:TCP 连接要求发送端发送一定数量的网络包之后接收端就要回一个“我收到”的网络包,而且网络包在经过每个路由器的时候包头都要被重写,所以在网络不丢包的情况 下网络包越大网络的效率就越高。TCP 连接寻找最优网络包大小的方法是,在 TCP 连接建立的初期,网络包的大小是很小的,根据网络状况,两端的程序才会逐步增大网络包的大小以适应带宽提高网络传输的效率。所以浏览器给服务器发请求,如 果每发一个请求就关闭连接的话,那这个连接的数据传输很难达到带宽所能承载的速度。 HTTP1.1 提出了持久连接(persistent connection)的概念,也就是说同一条 HTTP 连接,可以同时处理多个请求,同时用一定的机制保证各个请求之间的分离性。具体的操作过程是:服务器给浏览器发送回应之后,并不马上关闭连接;浏览器判断 上一个请求的回应已经收完的情况下,可以在这同一个连接上发第二个请求。这种运作模式大大减少了网络包,实验也表明这种做法很有效。但是,由于服务器上保 持连接要占用一定的资源,所以一般服务器不会永久保持持久连接,而且也不推荐浏览器和服务器之间建立过多的持久连接。 12.HTTP与TCP如何协同工作的,TCP怎么确保HTTP传输的稳定有序 ? HTTP/1.0和HTTP/1.1都把TCP作为底层的传输协议。HTTP客户首先发起建立与服务器TCP连接。一旦建立连接,浏览器进程和服务器进 程就可以通过各自的套接字来访问TCP。如前所述,客户端套接字是客户进程和TCP连接之间的“门”,服务器端套接字是服务器进程和同一TCP连接之间的 “门”。客户往自己的套接字发送HTTP请求消息,也从自己的套接字接收HTTP响应消息。类似地,服务器从自己的套接字接收HTTP请求消息,也往自己 的套接字发送HTTP响应消息。客户或服务器一旦把某个消息送入各自的套接字,这个消息就完全落入TCP的控制之中。TCP给HTTP提供一个可靠的数据 传输服务;这意味着由客户发出的每个HTTP请求消息最终将无损地到达服务器,由服务器发出的每个HTTP响应消息最终也将无损地到达客户。我们可从中看 到分层网络体系结构的一个明显优势——HTTP不必担心数据会丢失,也无需关心TCP如何从数据的丢失和错序中恢复出来的细节。这些是TCP和协议栈中更 低协议层的任务。 TCP还使用一个拥塞控制机制。该机制迫使每个新的TCP连接一开始以相对缓慢的速率传输数据,然而只要网络不拥塞,每个连接可以迅速上升到相对较高的速率。这个慢速传输的初始阶段称为缓启动(slow start)。 需要注意的是,在向客户发送所请求文件的同时,服务器并没有存储关于该客户的任何状态信息。即便某个客户在几秒钟内再次请求同一个对象,服务器也不会响 应说:自己刚刚给它发送了这个对象。相反,服务器重新发送这个对象,因为它已经彻底忘记早先做过什么。既然HTTP服务器不维护客户的状态信息,我们于是 说HTTP是一个无状态的协议(stateless protocol)。 参考 从输入 URL 到页面加载完成的过程中都发生了什么事情? OSI七层模型与TCP/IP五层模型 说说网络分层里七层模型是哪七层 TCP和UDP的区别 从输入 URL 到页面加载完成发生了什么事 浏览器渲染原理及流程 TCP三次握手及四次挥手详解及常见面试题 http全过程 前端常见跨域解决方案 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-08 15:31:34 "},"html/渲染机制.html":{"url":"html/渲染机制.html","title":"渲染机制","keywords":"","body":"渲染机制 问题 1.什么是DOCTYPE及作用? 2.常用的DOCTYPE有哪些? 3.浏览器的渲染过程 4.重排Reflow与重绘Repain 回答 1.什么是DOCTYPE及作用? DTD(document type definition,文档类型定义) DTD是一系列的语法规则,用来定义XML或HTML的文件类型。浏览器会使用它来判断文档类型,决定使用何种协议来解析,以及切换浏览器模式。(DTD就是告诉浏览器我是什么文档类型,浏览器根据这个判断用什么引擎来解析和渲染它) DOCTYPE DOCTYPE是用来声明文档类型和DTD规范的,一个主要的用途便是文件的合法性验证。如果文件代码不合法,那么浏览器解析时便会出一些差错;(DOCTYPE就是直接告诉浏览器什么是DTD的,通知浏览器告诉当前的文档包含的是哪个DTD,也就是哪个文档类型。) Doctype作用?严格模式和混杂模式如何区分?它们有何意义? 声明位于文档中的最前面,处于标签之前。告知浏览器以何种模式来渲染文档。 严格模式的排版和js运作模式以该浏览器支持的最高标准运行。 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。 DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。 你知道多少种DocType文档类型? 该标签可声明三种DTD类型,分别表示严格版本、过渡版本以及基于框架的HTML文档。 HTML4.01规定了三种文档类型:Strict,Transitional以及Frameset。 XHTML1.0规定了三种XML文档类型:Strict,Transitional以及frameset Standards(标准)模式(也就是严格呈现模式)用于呈现遵循最新标准的网页,而Quirks(兼容)模式(也就是松散呈现模式或者兼容模式)用于呈现为传统浏览器而设计的网页。 HTML5为什么只需要写? HTML5不基于SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照他们应该的方式来运行); 而HTML4基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。 2.常用的DOCTYPE有哪些? HTML5 HTML 4.01 Strict(严格模式) (该DTD包含所有HTML元素和属性,但不包括展示性的和弃用的元素--比如:font) HTML 4.01 Transitional(传统模式--宽松模式) (该DTD包含所有HTML元素和属性,包括展示性的和弃用的元素--比如font) 3.浏览器的渲染过程 html css js三个都会影响页面最后的呈现形式(浏览器拿到了html,css之后要干什么?) 把html经过HTMl Parser也就是DOM Parser转成DOM Tree(dom树); css按照css规则和css解析器转成css Rules(css) 两个树一整合Attachment,就形成了一个Render Tree (告诉浏览器我这个地方要渲染一颗树的一个结构),Render Tree不包含html具体内容,也不知道位置什么(layout之前Render Tree不知道某一个元素具体应该画在什么位置),通过layout就能精确的计算要显示的DOM真正的位置,宽高,颜色,都在Render Tree呈现出来,最后开始Painting(浏览器通过DUI开始画图了)把我们的内容基本呈现出来。 eg:在浏览器中输入一个url,发生了哪些事情? --会有一个DNS解析,发送给服务器,服务器响应,响应过来到客户端浏览器这边就开始了渲染过程。 从输入 URL 到页面加载完成的过程中都发生了什么事情? 4.重排Reflow与重绘Repain 重排Reflow 定义: DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow。 触发: 当你增加、删除、修改DOM节点时,会导致Reflow和Repaint; 当你移动DOM的位置,或者动画的时候; 当你修改css样式的时候(宽高,位置等); 当你Resize窗口的时候(移动端没有这个问题),或者滚动的时候; 当你修改网页的默认字体时(节点宽高会改变); css伪类激活 如何尽量避免触发reflow 尽量避免上述操作 重绘Repaint 定义: 发生在元素的可见性发生变化时,比如背景色、前景色等 触发: DOM改动 CSS改动 如何避免最小程度的repaint? repaint是无法避免的,可以最大程度降低repaint; 避免逐项更改样式。最好一次性更改style属性,或者将样式列表定义为class并一次性更改class属性。 避免循环操作DOM。创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。 避免循环读取offsetLeft等属性。在循环之前把它们存起来。 绝对定位具有复杂动画的元素。绝对定位使它脱离文档刘,否则会引起父元素及后续元素大量的回流。 重绘不一定重排,重排一定重绘 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-05 18:17:11 "},"html/HTML和XHTML的区别.html":{"url":"html/HTML和XHTML的区别.html","title":"HTML和XHTML的区别","keywords":"","body":"区别: 所有的标记都必须要有一个相应的结束标记 所有标签的元素和属性的名字都必须使用小写 所有的XML标记都必须合理嵌套 所有的属性必须用引号\"\"\"括起来 把所有的 给所有属性赋一个值 不要在注释内容中使\"--\" 图片必须有说明文字 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-05 18:01:14 "},"html/html.html":{"url":"html/html.html","title":"htmlkk","keywords":"","body":"html5新特性 HTMl5现在已经不是SGML的子集,主要是关于图像,位置,存储,多任务等功能的增加。 拖拽释放(Drag and Drop)API 语义化更好的内容标签(header,nav,footer,aside,article,section) 音频、视频API(audio,video) 画布(Canvas)API 地理(GEOlocation)API 本地离线存储localstorage长期存储数据,浏览器关闭后数据不丢失;sesseionStorage的数据在浏览器关闭后自动删除 表单控件:calendar,data,time,email,URL,search 新的技术webworker,websocket,Geoloation 移除的元素 纯表现的元素:basefont,big,center,font,s,strike,tt,u; 对可用性产生负面影响的元素:frame,frameset,noframe; 支持HTML5新标签: IE8/IE7/IE6支持通过document.createElement方法产生的标签, 可以利用这一特性让这些浏览器支持HTML5新标签, 当然最好的方式是直接使用成熟的框架、使用最多的是html5shim框架 src=\"http://html5shim.googlecode.com/svn/trunk/html5.js\" 如何区分: DOCTYPE声明\\新增的结构元素\\功能元素可以利用这一特性让这些浏览器支持HTML5的新标签, 当然最好的方式是直接使用成熟的框架,使用最多的是html5shim框架 1. 怎么区分html和html5?html5有哪些新特性?兼容性怎么样?如何处理兼容 (Q1) HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。 绘画 canvas; 用于媒介回放的 video 和 audio 元素; 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失; sessionStorage 的数据在浏览器关闭后自动删除; 语意化更好的内容元素,比如 article、footer、header、nav、section; 表单控件,calendar、date、time、email、url、search; 新的技术webworker, websocket, Geolocation; (Q2) IE8/IE7/IE6支持通过document.createElement方法产生的标签, 可以利用这一特性让这些浏览器支持HTML5新标签, 浏览器支持新标签后,还需要添加标签默认的样式。 当然也可以直接使用成熟的框架、比如html5shim, 行内元素有哪些?块级元素有哪些?空(void)元素有哪些? 首先:CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认display值,如div的display默认值是\"block\",则为”块级“元素;span默认为display属性值为”inline“,是”行内“元素。 行内元素有:a b span img input select strong 块级元素有:div ul li ol dl dd p h1 常见的空元素有: 鲜为人知的是: 页面导入样式时,使用link和@import有什么区别 1.link属于XHTML标签,除了加载CSS外,还能用于定义RSS,定义rel链接属性等作用;而@import是CSS提供的,只能用于加载CSS 2.页面被加载的时候,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载 3.import是css2.1提出的,只有IE5以上才能被识别,而link是XHTML标签,无兼容问题; 介绍一下你对浏览器内核的理解? 主要分为两部分:渲染引擎和js引擎 渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入css等),以计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。 js引擎:解释和执行javascript来实现网页的动态效果。 最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。 常见的浏览器内核有哪些? Trident内核:IE,MaxThon,TT,The Word,360,搜狗,等 Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等 Presto内核:Opera7及以上. [Opera内核原为:Presto,现为:Blink;] Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)] html5有哪些新特性、移除了那些元素?如何处理HTMl5新标签的浏览器兼容问题?r如何区分HTML和HTML5? HTML5现在已经不是SGML的子集,主要是关于图像,位置,存储,多任务等功能的增加 新特性 1.绘画canvas; 2.用于媒介回放的video和audio元素; 3.本地离线存储localStorage长期存储数据。浏览器关闭后数据不丢失; 4.sessionStorage的元素在浏览器关闭后自动删除; 5.语义化更好的元素内容:比如 article,footer,header,nav,section; 6.表单控件,calendar,data,time,email,url,search 7.新的技术webworker,websocket,Geolocation; 移除的元素 1.纯表现的元素:base,font,big,center,font,s,strike,tt,u; 2.对可用性产生负面影响的元素:frame,frameset,noframes; 支持HTML5新标签 1.IE8/IE7/IE6支持通过document.createElement方法产生的标签; 2.可以利用这一特性让这些浏览器支持HTML5新标签 3.浏览器支持新标签后,还需要添加标签默认的样式。 4.当然也可以直接用成熟的框架,比如html5shim; src=\"http://html5shim.googlecode.com/svn/trunk/html5.js\" 如何区分HTMl5 DOCTYPE声明\\新增的结构元素\\功能元素 简述以下你对HTML语义化的理解? 1.用正确的标签做正确的事情; 2.html语义化让页面的内容结构化,结构更清晰,便于浏览器,搜索引擎解析; 3.即使在没有样式css情况下也以一种文档格式显示,并且是容易阅读的; 4.搜索引擎的爬虫也依赖于HTML标记俩确定上下文和各个关键字的权重,利于SEO; 5.使阅读源代码的人对网站更容易将网站分块,便于阅读和维护理解。 HTML5的离线存储怎么使用,工作原理能不能解释一下? 在用户没有与因特网链接时,可以正常访问站点或应用,在用户与因特网链接时,更新用户机器上的缓存文件 原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会向cookie一样被存储了下来。之后当网络处于离线状态时,浏览器会通过离线存储的数据进行页面展示。 如何使用: 1、页面头部像下面一样加入一个manifest的属性; 2、在cache.manifest文件的编写离线存储的资源; CACHE MANIFEST #v0.11 CACHE: js/app.js css/style.css NETWORK: resourse/logo.png FALLBACK: / /offline.html 3、在离线状态时,操作window.applicationCache进行需求实现。 浏览器是怎么对HTMl5的离线存储资源进行管理和加载的呢? 在线的情况下:浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相关的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会从新下载文件中的资源并进行离线存储。 离线的情况下:浏览器就直接使用离线存储的资源。 请描述一下cookies,sessionStorage和localStorage的区别? cookie是网站为了表示用户身份而存储在用户本地终端(client side)上的数据(通常经过加密)。 cookie数据始终在同源的http请求中携带(即使不需要),在浏览器和服务器间来回传递。 sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。 存储大小: cookie数据大小不能超过4K. sessionStorage和localStorage虽然也有存储大小限制,但比cookie大很多,可以达到5M或更大。 有效时间: localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; sessionStorage 数据在当前浏览器窗口关闭后自动删除。 cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭 iframe有哪些缺点? 1.iframe会阻塞主页面的onload事件 2.搜索引擎的检索程序无法解读这种页面,不利于SEO; 3.iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载 4.使用iframe之前需要考虑这两个缺点,如果需要使用iframe,最好是通过javascript动态给iframe添加src属性值,这样可以绕开以上两个问题 label的作用是什么?是怎么用的? label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。 Number: Date: HTML5的form如何关闭自动完成功能? 给不想要提示的form或者某个input设置为autocomplete=off。 如何实现浏览器内多个标签页的通信? WebSocket、ShareWorker; 也可以调用localStorage、cookie等本地存储方式; localsStorage另一个浏览上下文被添加、修改或删除时,它都会触发一个事件,我们通过监听事件,控制它的值来进行页面信息通信; 注意quirks:Safari在无痕模式下设置localStorage值时会抛出QuotaExceededError的异常 webSocket如何兼容低浏览器 Adobe Flash Socket 、 ActiveX HTMLFile (IE) 、 基于 multipart 编码发送 XHR 、 基于长轮询的 XHR 页面可见性(Page Visibility API) 可以有哪些用途? 通过 visibilityState 的值检测页面当前是否可见,以及打开网页的时间等; 在页面被切换到其他后台进程的时候,自动暂停音乐或视频的播放; 如何在页面上实现一个原型的可点击区域? 1、map+area或者svg 2、border-radius 3、纯js实现 需要求一个点在不在圆上简单算法、获取鼠标坐标等等 实现不使用border画出1px高的线,在不同浏览器的标准模式与怪异模式下都能保持一致的效果 网页验证码是干嘛的,是为了解决什么安全问题。 区分用户是计算机还是人的公共全自动程序。可以防止恶意破解密码、刷票、论坛灌水 有效防止黑客堆某一特定注册用户用特定程序暴力破解方式进行不断的登录尝试 title与h1的区别、b与strong的区别、i与em的区别? title属性没有明确意义只表示是个标题,h1则表示层次明确的标题,对页面信息的抓取也有很大的影响; strong是标明重点内容,有语气加强的含义,使用阅读设备阅读网络时,会重度,而是展示强调内容 i内容展示为斜体,em表示强调的文本; Physical Style Elements -- 自然样式标签 b, i, u, s, pre Semantic Style Elements -- 语义样式标签 strong, em, ins, del, code 应该准确使用语义样式标签, 但不能滥用, 如果不能确定时首选使用自然样式标签 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-05 18:17:20 "},"html/一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么?.html":{"url":"html/一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么?.html","title":"一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么?","keywords":"","body":"参考 从输入 URL 到页面加载完成的过程中都发生了什么事情? 从输入 URL 到页面加载完成发生了什么事 浏览器渲染原理及流程 TCP三次握手及四次挥手详解及常见面试题 http全过程 基础概念 分为4个步骤: 当发送一个URL请求时,不管这个URL是Web页面还是web页面上每个资源的URL,浏览器都会开启一个线程来处理这个请求,同时在远程DNS服务器上启动一个DNS查询。这能使浏览器获得请求对应的IP地址 浏览器与远程'web'服务器通过TCP三次握手协商来建立一个TCP/IP连接,该握手包括一个同步报文,一个同步应答报文和一个应答报文,这三个报文在浏览器和服务器之间传递,该握手首先由客户端尝试建立通信,而后服务器应答并接受客户端的请求,最后有客户端发出该请求已经被接受的报文 一旦TCP/IP连接建立,浏览器会通过该连接向远程服务器发送“http”的get请求。远程服务器找到资源并使用HTTP相应返回该资源,值为200的HTTP相应状态表示一个正确的响应。 此时,“web”服务器提供资源服务,客户端开始下载资源。 请求返回后,便进入了我们关注的前端模块简单来说,浏览器会解析HTML生成DOM Tree,其次会根据CSS生成css Rule Tree而JavaScript又可以根据DOM API操作DOM Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-04 14:26:38 "},"html/前端常见跨域解决方案.html":{"url":"html/前端常见跨域解决方案.html","title":"前端常见跨域解决方案","keywords":"","body":"什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。 广义的跨域 : 1.) 资源跳转: A链接、重定向、表单提交 2.) 资源嵌入: 、、、等dom标签,还有样式中background:url()、@font-face()等文件外链 3.) 脚本请求: js发起的ajax请求、dom和js对象的跨域操作等 其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。 什么是同源策略? 同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指\"协议+域名+端口\"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。 同源策略限制以下几种行为: 1.) Cookie、LocalStorage 和 IndexDB 无法读取 2.) DOM 和 Js对象无法获得 3.) AJAX 请求不能发送 常见跨域场景 URL 说明 是否允许通信 http://www.domain.com/a.js http://www.domain.com/b.js 同一域名,不同文件或路径 允许 http://www.domain.com/lab/c.js http://www.domain.com:8000/a.js http://www.domain.com/b.js 同一域名,不同端口 不允许 http://www.domain.com/a.js https://www.domain.com/b.js 同一域名,不同协议 不允许 http://www.domain.com/a.js http://192.168.4.12/b.js 域名和域名对应相同ip 不允许 http://www.domain.com/a.js http://x.domain.com/b.js 主域相同,子域不同 不允许 http://domain.com/c.js http://www.domain1.com/a.js http://www.domain2.com/b.js 不同域名 不允许 跨域解决方案 1、 通过jsonp跨域2、 document.domain + iframe跨域3、 location.hash + iframe4、 window.name + iframe跨域5、 postMessage跨域6、 跨域资源共享(CORS)7、 nginx代理跨域8、 nodejs中间件代理跨域9、 WebSocket协议跨域 一、 通过jsonp跨域 通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。 1.)原生实现: var script = document.createElement('script'); script.type = 'text/javascript'; // 传参并指定回调执行函数为onBack script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack'; document.head.appendChild(script); // 回调执行函数 function onBack(res) { alert(JSON.stringify(res)); } 服务端返回如下(返回时即执行全局函数): onBack({\"status\": true, \"user\": \"admin\"}) 2.)jquery ajax: $.ajax({ url: 'http://www.domain2.com:8080/login', type: 'get', dataType: 'jsonp', // 请求方式为jsonp jsonpCallback: \"onBack\", // 自定义回调函数名 data: {} }); 3.)vue.js: this.$http.jsonp('http://www.domain2.com:8080/login', { params: {}, jsonp: 'onBack' }).then((res) => { console.log(res); }) 后端node.js代码示例: var querystring = require('querystring'); var http = require('http'); var server = http.createServer(); server.on('request', function(req, res) { var params = qs.parse(req.url.split('?')[1]); var fn = params.callback; // jsonp返回设置 res.writeHead(200, { 'Content-Type': 'text/javascript' }); res.write(fn + '(' + JSON.stringify(params) + ')'); res.end(); }); server.listen('8080'); console.log('Server is running at port 8080...'); jsonp缺点:只能实现get一种请求。 二、 document.domain + iframe跨域 此方案仅限主域相同,子域不同的跨域应用场景。 实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。 1.)父窗口:(http://www.domain.com/a.html) document.domain = 'domain.com'; var user = 'admin'; 2.)子窗口:(http://child.domain.com/b.html) document.domain = 'domain.com'; // 获取父窗口中变量 alert('get js data from parent ---> ' + window.parent.user); 三、 location.hash + iframe跨域 实现原理: a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。 具体实现:A域:a.html -> B域:b.html -> A域:c.html,a与b不同域只能通过hash值单向通信,b与c也不同域也只能单向通信,但c与a同域,所以c可通过parent.parent访问a页面所有对象。 1.)a.html:(http://www.domain1.com/a.html) var iframe = document.getElementById('iframe'); // 向b.html传hash值 setTimeout(function() { iframe.src = iframe.src + '#user=admin'; }, 1000); // 开放给同域c.html的回调方法 function onCallback(res) { alert('data from c.html ---> ' + res); } 2.)b.html:(http://www.domain2.com/b.html) var iframe = document.getElementById('iframe'); // 监听a.html传来的hash值,再传给c.html window.onhashchange = function () { iframe.src = iframe.src + location.hash; }; 3.)c.html:(http://www.domain1.com/c.html) // 监听b.html传来的hash值 window.onhashchange = function () { // 再通过操作同域a.html的js回调,将结果传回 window.parent.parent.onCallback('hello: ' + location.hash.replace('#user=', '')); }; 四、 window.name + iframe跨域 window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。 1.)a.html:(http://www.domain1.com/a.html) var proxy = function(url, callback) { var state = 0; var iframe = document.createElement('iframe'); // 加载跨域页面 iframe.src = url; // onload事件会触发2次,第1次加载跨域页,并留存数据于window.name iframe.onload = function() { if (state === 1) { // 第2次onload(同域proxy页)成功后,读取同域window.name中数据 callback(iframe.contentWindow.name); destoryFrame(); } else if (state === 0) { // 第1次onload(跨域页)成功后,切换到同域代理页面 iframe.contentWindow.location = 'http://www.domain1.com/proxy.html'; state = 1; } }; document.body.appendChild(iframe); // 获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问) function destoryFrame() { iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); } }; // 请求跨域b页面数据 proxy('http://www.domain2.com/b.html', function(data){ alert(data); }); 2.)proxy.html:(http://www.domain1.com/proxy.... 中间代理页,与a.html同域,内容为空即可。 3.)b.html:(http://www.domain2.com/b.html) window.name = 'This is domain2 data!'; 总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。 五、 postMessage跨域 postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:a.) 页面和其打开的新窗口的数据传递b.) 多窗口之间消息传递c.) 页面与嵌套的iframe消息传递d.) 上面三个场景的跨域数据传递 用法:postMessage(data,origin)方法接受两个参数 data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。 origin: 协议+主机+端口号,也可以设置为\"*\",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为\"/\"。 1.)a.html:(http://www.domain1.com/a.html) var iframe = document.getElementById('iframe'); iframe.onload = function() { var data = { name: 'aym' }; // 向domain2传送跨域数据 iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com'); }; // 接受domain2返回数据 window.addEventListener('message', function(e) { alert('data from domain2 ---> ' + e.data); }, false); 2.)b.html:(http://www.domain2.com/b.html) // 接收domain1的数据 window.addEventListener('message', function(e) { alert('data from domain1 ---> ' + e.data); var data = JSON.parse(e.data); if (data) { data.number = 16; // 处理后再发回domain1 window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com'); } }, false); 六、 跨域资源共享(CORS) 普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。 需注意的是:由于同源策略的限制,所读取的cookie为跨域请求接口所在域的cookie,而非当前页。如果想实现当前页cookie的写入,可参考下文:七、nginx反向代理中设置proxy_cookie_domain 和 八、NodeJs中间件代理中cookieDomainRewrite参数的设置。 目前,所有浏览器都支持该功能(IE8+:IE8/9需要使用XDomainRequest对象来支持CORS)),CORS也已经成为主流的跨域解决方案。 1、 前端设置: 1.)原生ajax // 前端设置是否带cookie xhr.withCredentials = true; 示例代码: var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容 // 前端设置是否带cookie xhr.withCredentials = true; xhr.open('post', 'http://www.domain2.com:8080/login', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=admin'); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } }; 2.)jQuery ajax $.ajax({ ... xhrFields: { withCredentials: true // 前端设置是否带cookie }, crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie ... }); 3.)vue框架 在vue-resource封装的ajax组件中加入以下代码: Vue.http.options.credentials = true 2、 服务端设置: 若后端设置成功,前端浏览器控制台则不会出现跨域报错信息,反之,说明没设成功。 1.)Java后台: /* * 导入包:import javax.servlet.http.HttpServletResponse; * 接口参数中定义:HttpServletResponse response */ response.setHeader(\"Access-Control-Allow-Origin\", \"http://www.domain1.com\"); // 若有端口需写全(协议+域名+端口) response.setHeader(\"Access-Control-Allow-Credentials\", \"true\"); 2.)Nodejs后台示例: var http = require('http'); var server = http.createServer(); var qs = require('querystring'); server.on('request', function(req, res) { var postData = ''; // 数据块接收中 req.addListener('data', function(chunk) { postData += chunk; }); // 数据接收完毕 req.addListener('end', function() { postData = qs.parse(postData); // 跨域后台设置 res.writeHead(200, { 'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie 'Access-Control-Allow-Origin': 'http://www.domain1.com', // 允许访问的域(协议+域名+端口) 'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本无法读取cookie }); res.write(JSON.stringify(postData)); res.end(); }); }); server.listen('8080'); console.log('Server is running at port 8080...'); 七、 nginx代理跨域 1、 nginx配置解决iconfont跨域 浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。 location / { add_header Access-Control-Allow-Origin *; } 2、 nginx反向代理接口跨域 跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。 实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。 nginx具体配置: proxy服务器 server { listen 81; server_name www.domain1.com; location / { proxy_pass http://www.domain2.com:8080; #反向代理 proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名 index index.html index.htm; # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用 add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为* add_header Access-Control-Allow-Credentials true; } } 1.) 前端代码示例: var xhr = new XMLHttpRequest(); // 前端开关:浏览器是否读写cookie xhr.withCredentials = true; // 访问nginx中的代理服务器 xhr.open('get', 'http://www.domain1.com:81/?user=admin', true); xhr.send(); 2.) Nodejs后台示例: var http = require('http'); var server = http.createServer(); var qs = require('querystring'); server.on('request', function(req, res) { var params = qs.parse(req.url.substring(2)); // 向前台写cookie res.writeHead(200, { 'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本无法读取 }); res.write(JSON.stringify(params)); res.end(); }); server.listen('8080'); console.log('Server is running at port 8080...'); 八、 Nodejs中间件代理跨域 node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证。 1、 非vue框架的跨域(2次跨域) 利用node + express + http-proxy-middleware搭建一个proxy服务器。 1.)前端代码示例: var xhr = new XMLHttpRequest(); // 前端开关:浏览器是否读写cookie xhr.withCredentials = true; // 访问http-proxy-middleware代理服务器 xhr.open('get', 'http://www.domain1.com:3000/login?user=admin', true); xhr.send(); 2.)中间件服务器: var express = require('express'); var proxy = require('http-proxy-middleware'); var app = express(); app.use('/', proxy({ // 代理跨域目标接口 target: 'http://www.domain2.com:8080', changeOrigin: true, // 修改响应头信息,实现跨域并允许带cookie onProxyRes: function(proxyRes, req, res) { res.header('Access-Control-Allow-Origin', 'http://www.domain1.com'); res.header('Access-Control-Allow-Credentials', 'true'); }, // 修改响应信息中的cookie域名 cookieDomainRewrite: 'www.domain1.com' // 可以为false,表示不修改 })); app.listen(3000); console.log('Proxy server is listen at port 3000...'); 3.)Nodejs后台同(六:nginx) 2、 vue框架的跨域(1次跨域) 利用node + webpack + webpack-dev-server代理接口跨域。在开发环境下,由于vue渲染服务和接口代理服务都是webpack-dev-server同一个,所以页面与代理接口之间不再跨域,无须设置headers跨域信息了。 webpack.config.js部分配置: module.exports = { entry: {}, module: {}, ... devServer: { historyApiFallback: true, proxy: [{ context: '/login', target: 'http://www.domain2.com:8080', // 代理跨域目标接口 changeOrigin: true, cookieDomainRewrite: 'www.domain1.com' // 可以为false,表示不修改 }], noInfo: true } } 九、 WebSocket协议跨域 WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。 原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。 1.)前端代码: user input: var socket = io('http://www.domain2.com:8080'); // 连接成功处理 socket.on('connect', function() { // 监听服务端消息 socket.on('message', function(msg) { console.log('data from server: ---> ' + msg); }); // 监听服务端关闭 socket.on('disconnect', function() { console.log('Server socket has closed.'); }); }); document.getElementsByTagName('input')[0].onblur = function() { socket.send(this.value); }; 2.)Nodejs socket后台: var http = require('http'); var socket = require('socket.io'); // 启http服务 var server = http.createServer(function(req, res) { res.writeHead(200, { 'Content-type': 'text/html' }); res.end(); }); server.listen('8080'); console.log('Server is running at port 8080...'); // 监听socket连接 socket.listen(server).on('connection', function(client) { // 接收信息 client.on('message', function(msg) { client.send('hello:' + msg); console.log('data from client: ---> ' + msg); }); // 断开处理 client.on('disconnect', function() { console.log('Client socket has closed.'); }); }); Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-08 16:36:49 "},"html/XML和JSON的区别?.html":{"url":"html/XML和JSON的区别?.html","title":"XML和JSON的区别?","keywords":"","body":" 数据体积方面 JSON相对于XML来说,数据的体积小,传递的速度更快些。 数据交互方面 JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。 数据描述方面 JSON 对数据的描述性比XML较差。 传输速度方面 JSON的速度要远远快于XML Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:31:33 "},"html/Cookie、sessionStorage、localStorage的区别.html":{"url":"html/Cookie、sessionStorage、localStorage的区别.html","title":"Cookie、sessionStorage、localStorage的区别","keywords":"","body":"Cookie cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的。 第一:每个特定的域名下最多生成20个cookie 1.IE6或更低版本最多20个cookie 2.IE7和之后的版本最后可以有50个cookie。 3.Firefox最多50个cookie 4.chrome和Safari没有做硬性限制 IE和Opera会清理近期最少使用的cookie,Firefox会随机清理cookie。 cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节 IE提供了一种存储可以持久化用户数据,叫做userdata,从IE5.0就开始支持,每个数据最多128K,每个域名下最多1M。这个持久化数据放在缓存中,如果缓存没有清理,那么会一直存在。 有点:极高的扩展性和可用性 通过良好的编程,控制保存在cookie中session对象的大小。 通过加密和安全技术(SSL),减少cookie被破解的可能性。 只在cookie中存放不敏感数据,即使被盗也不会有重大损失。 控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。 缺点: cookie数据和长度的限制,每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。 安全性问题,如果cookie被人截下了,那人就可以取得所有的session信息,即使加密也于事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。 有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。 Cookie、session的区别 cookie数据存放在客户的浏览器上,session数据放在服务器上。 cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。 session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到 Cookie、sessionStorage、localStorage的区别 sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据。有了本地数据,就可以避免数据在浏览器和服务器间不必要地来回传递。 sessionStorage、localStorage、cookie都是在浏览器端存储的数据,其中sessionStorage的概念很特别,引入了一个“浏览器窗口”的概念。sessionStorage是在同源的同窗口(或tab)中,始终存在的数据。也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一页面,数据仍然存在。关闭窗口后,sessionStorage即被销毁。同时“独立”打开的不同窗口,即使是同一页面,sessionStorage对象也是不同的。 Web Storage带来的好处: 减少网络流量:一旦数据保存在本地后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数据在浏览器和服务器间不必要地来回传递。 快速显示数据:性能好,从本地读数据比通过网络从服务器获得数据快得多,本地数据可以即时获得。再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示。 临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage非常方便。 浏览器本地存储与服务器端存储之间的区别 其实数据既可以在浏览器本地存储,也可以在服务器端存储。 浏览器端可以保存一些数据,需要的时候直接从本地获取,sessionStorage、localStorage和cookie都由浏览器存储在本地的数据。 服务器端也可以保存所有用户的所有数据,但需要的时候浏览器要向服务器请求数据。 1.服务器端可以保存用户的持久数据,如数据库和云存储将用户的大量数据保存在服务器端。 2.服务器端也可以保存用户的临时会话数据。服务器端的session机制,如jsp的 session 对象,数据保存在服务器上。实现上,服务器和浏览器之间仅需传递session id即可,服务器根据session id找到对应用户的session对象。会话数据仅在一段时间内有效,这个时间就是server端设置的session有效期。 服务器端保存所有的用户的数据,所以服务器端的开销较大,而浏览器端保存则把不同用户需要的数据分布保存在用户各自的浏览器中。 浏览器端一般只用来存储小数据,而服务器可以存储大数据或小数据。 服务器存储数据安全一些,浏览器只适合存储一般数据。 sessionStorage 、localStorage 和 cookie 之间的区别 共同点:都是保存在浏览器端,且同源的。 区别: cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。 Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。 Web Storage 的 api 接口使用更方便。 sessionStorage 和 localStorage 之间的区别 见上面的区别3、4 sessionStorage与页面 js 数据对象的区别 页面中一般的 js 对象或数据的生存期是仅在当前页面有效,因此刷新页面或转到另一页面这样的重新加载页面的情况,数据就不存在了。 而sessionStorage 只要同源的同窗口(或tab)中,刷新页面或进入同源的不同页面,数据始终存在。也就是说只要这个浏览器窗口没有关闭,加载新页面或重新加载,数据仍然存在。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:00:30 "},"html/哪些会造成内存泄漏.html":{"url":"html/哪些会造成内存泄漏.html","title":"哪些会造成内存泄漏","keywords":"","body":"内存泄露指任何对象在您不再拥有或需要它之后仍然存在。垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如一个对象的引用数量为0(没有其他对象引用过该对象),或对该对象的唯一引用的循环的,那么该该对象的内存即可回收。setTimeout的第一个参数使用字符串而非函数的话,会引发内存泄露。闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)详见:详解js变量、作用域及内存 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:34:07 "},"html/说说网络分层里七层模型是哪七层.html":{"url":"html/说说网络分层里七层模型是哪七层.html","title":"说说网络分层里七层模型是哪七层","keywords":"","body":" 应用层: 表示层: 会话层: 传输层(TCP和UDP) 网络层(IP) 物理和数据链路层(以太网) 每一层的作用如下: 物理层:通过媒介传输比特,确定机械及电气规范(比特Bit) 数据链路层:将比特组装成帧和点到点的传递(帧Frame) 网络层:负责数据包从源到宿的传递和网际互联(包Packet) 传输层:提供端到端的可靠报文传递和错误恢复(段Segment) 会话层:建立、管理和终止会话(会话协议数据单元SPUD) 表示层:对数据进行翻译、加密和压缩(表示协议数据单元PPDU) 应用层:允许访问OSI环境的手段(应用协议数据单元APDU) 各种协议 ICMP:因特网控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。 FTP协议:是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂,开销不大的文件传输服务。 HTTP协议:超文本传输协议,是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。DHC协议:动态主机配置协议,是一种让系统得以连接到网络上,并获取所需要的配置参数手段。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:37:51 "},"html/TCP和UDP的区别.html":{"url":"html/TCP和UDP的区别.html","title":"TCP和UDP的区别","keywords":"","body":"TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式发送数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来 UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:41:44 "},"html/常用浏览器及浏览器内核.html":{"url":"html/常用浏览器及浏览器内核.html","title":"常用浏览器及浏览器内核","keywords":"","body":"事件、IE与火狐的事件机制有什么区别? 如何阻止冒泡? 我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为。 事件处理机制:IE是事件冒泡、firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件。; ev.stopPropagation();注意旧ie的方法 ev.cancelBubble = true; 1.常用什么浏览器测试,分别是什么内核 答: 1.Trident(IE内核) IE6、IE7、IE8(Trident 4.0)、IE9(Trident 5.0)、IE10(Trident 6.0); 360安全浏览器、360极速浏览器(采用Chrome+IE内核)、百度浏览器(早期版本)、世界之窗浏览器 2.Gecko(Firefox内核) Netscape6开始采用的内核,后来的Mozilla FireFox (火狐浏览器) 也采用了该内核,K-Meleon浏览器也是使用这种内核; 3.Webkit(Safari内核,Chrome内核原型,开源) Webkit:它是苹果公司自己的内核,也是苹果的Safari浏览器使用的内核, 谷歌chrome浏览器最先开发或使用,也叫谷歌内核,2013年分道扬镳了。 WebKit内核常见的浏览器:Apple Safari (Win/Mac/iPhone/iPad)、Symbian手机浏览器、Android 默认浏览器, 4.Presto(Opera前内核) (已废弃) 以前只有Opera浏览器采用该内核,后面用webKit,Opera宣布将跟随Google,放弃WebKit,支持Blink浏览器引擎 5.Blink(Google的最新内核) 2013年4月3日,谷歌在Chromium Blog上发表博客,称将与苹果的开源浏览器核心Webkit分道扬镳,在Chromium项目中自主研发Blink渲染引擎(即浏览器核心),内置于Chrome浏览器之中。 重点:Blink内核和Webkit内核有什么区别 Chrome浏览器基于开源引擎WebKit中WebCore元件的一个分支--Blink 6.常用浏览器内核 Opera浏览器: (2013年以前Presto内核,2013年以后Google Chrome的WebKit内核) 搜狗高速浏览器:使用高速(webkit)和兼容(Trident)双浏览模式; QQ浏览器6.11:使用极速(Webkit)和普通(Trident)双浏览模式; 360安全浏览器:Trident内核; 360极速浏览器:Webkit+Trident双内核; 360游戏浏览器:Trident内核; IE:Trident内核; Chrome:2013年4月年以前Webkit内核,2013年4月以后,自主研发的Webkit内核; Firefox:Gecko内核; 猎豹浏览器:采用Trident和WebKit双核 列举IE和其他浏览器不一样的特性 IE支持currentStyle,FIrefox使用getComputStyle IE 使用innerText,Firefox使用textContent 滤镜方面:IE:filter:alpha(opacity= num);Firefox:-moz-opacity:num 事件方面:IE:attachEvent:火狐是addEventListener 鼠标位置:IE是event.clientX;火狐是event.pageX IE使用event.srcElement;Firefox使用event.target IE中消除list的原点仅需margin:0即可达到最终效果;FIrefox需要设置margin:0;padding:0以及list-style:none CSS圆角:ie7以下不支持圆角 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:23:07 "},"html/常见web安全及防护原理.html":{"url":"html/常见web安全及防护原理.html","title":"常见web安全及防护原理","keywords":"","body":" XSS 原理及防范 XSS(cross-site scripting)攻击指的是攻击者往web页面里插入恶意html标签或者JavaScript代码。比如,攻击者在论坛里放一个看似安全的链接,骗取用户点击后,窃取cookie中的用户私密信息;或者攻击者在论坛中加一个恶意表单, 当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点。 XSS 防范方法 首先代码里对用户输入的地方和变量都需要仔细检查长度和对“\",\"\",''等字符做过滤,其次任何内容写到页面之前都必须加以encode,避免不小心把HTML tag弄出来。这一个层面做好,至少可以堵住超过一半的xss攻击。 首先,避免直接在cookie中泄露用户隐私,例如email、密码等。 其次,避免使用cookie和系统ip绑定来降低cookie泄露后的危险。这样攻击者得到的cookie没有实际价值,不可能拿来重放。 如果网站不需要在浏览器端对cookie进行操作,可以在set-cookie末尾加上httpOnly来防止JavaScript代码直接获取cookie。 尽量采用POST而非get提交表单 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-08 18:20:24 "},"html/渐进增强和优雅降级.html":{"url":"html/渐进增强和优雅降级.html","title":"渐进增强和优雅降级","keywords":"","body":"渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。 优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-21 10:49:24 "},"html/webworker和webSocket.html":{"url":"html/webworker和webSocket.html","title":"web worker和webSocket","keywords":"","body":" worker主线程: 通过worker=new Worker(url)记在一个js文件来创建一个worker,同时返回一个worker实例。 通过worker.postMessage(data)方法来向worker发送数据。 绑定worker.onmessage方法来接受worker发送过来的数据。 可以使用worker.terminate()来终止一个worker的执行。 WebSocket时Web应用程序的传输协议,它提供了双向的,按序到达的数据流。他是一个HTML5协议,WebSocket的连接是持久的,他通过在客户端和服务器之间保持双工连接,服务器的更新可以被及时推送给客户端,而不需要客户端以一定时间间隔去轮询。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-03-14 11:03:25 "},"code/":{"url":"code/","title":"常用代码","keywords":"","body":"hello world Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-04-22 11:29:03 "},"code/js常用的代码.html":{"url":"code/js常用的代码.html","title":"js常用的代码","keywords":"","body":"js常用代码 解析cookie util.getcookie=function(objname){//获取指定名称的cookie的值 var arrstr = document.cookie.split(\"; \"); for(var i = 0;i json转Obj,Obj转json JSON字符串转换为JSON对象 ``` var obj = str.parseJSON(); //由JSON字符串转换为JSON对象 var obj = JSON.parse(str); //由JSON字符串转换为JSON对象 > 可以使用toJSONString()或者全局方法JSON.stringify()将JSON对象转化为JSON字符串。 var last=obj.toJSONString(); //将JSON对象转化为JSON字符 var last=JSON.stringify(obj); //将JSON对象转化为JSON字符 ### 如果要通过json字符串传输 $.ajax({ type: \"PUT\", url: PATH + \"/p/api/v1/leapid/\" + id, data: para, dataType: \"json\",//重点 contentType: \"application/json;//重点 charset=utf-8\", success: function (data) { }.bind(this), error: function (error) { } }) #### 获取cookie util.getcookie=function(objname){//获取指定名称的cookie的值 var arrstr = document.cookie.split(\"; \"); for(var i = 0;i ### 去掉字符的前后空格 String.prototype.trim=function() { return this.replace(/(^\\s*)|(\\s*$)/g,''); } ### bits转换为B,k,M,G util.parseUsage=function (number) { var number=parseInt(number); if(number } ### 正则 //email util.emailExp=/[\\w!#$%&'+/=?^_`{|}~-]+(?:.[\\w!#$%&'+/=?^_`{|}~-]+)@(?:[\\w](?:[\\w-][\\w])?.)+\\w?/ig; //phone util.phoneExp=/^1[3|4|5|7|8][0-9]\\d{8}$/ig; ### 冒泡排序 var examplearr=[3,2,1,3,5,6,7,38,77,5,34,2,99]; function sortArray(arr){ for(var i=0;iarr[j+1]){ var max=arr[j1]; arr[j]=arr[j+1]; arr[j+1]=max } } } } ### promise var url = 'https://hq.tigerbrokers.com/fundamental/finance_calendar/getType/2017-02-26/2017-06-10'; function getJSON(url){ return new Promise(function(resolved,reject){ var XHR= new XMLHttpRequest() XHR.open('GET',url,true); XHR.send(); XHR.onreadystatechange=function(){ if(XHR.readyState==4){ if(XHR.status==200){ try{ var response=JSON.parse(XHR.responseText); resolved(response); }catch(e){ reject(e); } }else{ reject(new Error(XHR.statusText)); } } } }) } var url = 'https://hq.tigerbrokers.com/fundamental/finance_calendar/getType/2017-02-26/2017-06-10'; var url1 = 'https://hq.tigerbrokers.com/fundamental/finance_calendar/getType/2017-03-26/2017-06-10'; function renderRace() { return Promise.race([getJSON(url), getJSON(url1)]); } renderRace().then(function(value) { console.log(value); }) ### 获取cookie function getcookie(objname){//获取指定名称的cookie的值 var arrstr = document.cookie.split(\"; \"); for(var i = 0;i ### 对象深拷贝 function cloneObj (obj) { var objType = Object.prototype.toString.call(obj); if(objType === '[object Array]' || objType === '[object Object]') { var temp = (objType === '[object Array]') ? [] : {} ; for(var k in obj) { temp[k] = cloneObj(obj[k]); } return temp; } return obj; } ### 利用filter,去重数组 var r, arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry']; r = arr.filter(function (element, index, self) { return self.indexOf(element) === index; }); ``` Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:45:58 "},"code/css常用代码.html":{"url":"code/css常用代码.html","title":"css常用代码","keywords":"","body":"强制英文换行 word-break: break-all; word-wrap: break-word 显示一行,超过长度显示省略号 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; 显示三角符号 方向向右 border-top: 8px solid transparent; border-left: 10px solid rgb(255, 255, 255); border-bottom: 8px solid transparent; 图片显示 background-size: cover;//把背景图像扩展至足够大,以使背景图像完全覆盖背景区域 background-size: contain;//把图像图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域。 border-image: url(./src/imgs/changan/borderImg2.png) 25 fill / 1 / 0 stretch; Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-05-07 15:14:38 "},"interview/":{"url":"interview/","title":"面试","keywords":"","body":"面试 寒冬求职季之你必须要懂的原生JS(上) 寒冬求职季之你必须要懂的原生JS(中) 一年半经验,百度、有赞、阿里前端面试总结 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-04-22 13:55:37 "},"css/css面试题.html":{"url":"css/css面试题.html","title":"css面试题","keywords":"","body":"1.清除浮动的方式有那些?那种方式你觉得最好 操作 对父级设置适合CSS高度 结尾处加空div标签 clear:both 父级div定义 伪类:after 和 zoom 父级div定义 overflow:hidden 原理 父级div手动定义height,就解决了父级div无法自动获取到高度的问题。 添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度 IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题 因为overflow:hidden属性相当于是让父级紧贴内容,这样即可紧贴其对象内内容(包括使用float的div盒子),从而实现了清除浮动。【注意:必须定义width或zoom:1,同时不能定义height】 优点 简单,代码少,容易掌握 简单,代码少,浏览器支持好 简单,代码少,浏览器支持好,不容易出现怪问题 浏览器支持好,不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等) 缺点 只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题 不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不爽 代码多,不少初学者不理解原理,要两句代码结合使用,才能让主流浏览器都支持。 不能和position配合使用,因为超出的尺寸的会被隐藏。 建议 不推荐使用,只建议高度固定的布局时使用 不推荐使用,但此方法是以前主要使用的一种清除浮动方法 推荐使用,建议定义公共类,以减少CSS代码。 推荐没有使用position或对overflow:hidden理解比较深的情况使用 评分 2颗星 3颗星 4颗星 3颗星 介绍下一标准的CSS的盒子模型?低版本IE和盒子模型有什么不同? 1.有两种,IE盒子模型,W3C盒子模型;2.盒子模型:内容(content)、填充(padding)、边界(margin)、边框(border);3.区别:IE的content部分把border和padding计算了进去; CSS选择符有哪些?有哪些属性可以继承? 1.id选择器(#myid)2.类选择器(.myClassName)3.标签选择器(div,h1,p)4.相邻选择器(h1+p)5.子选择器(ul>li)6.后代选择器(li a)7.通配符选择器(*)8.属性选择器(a[rel=\"external\"])9.伪类选择器(a:hover,li:nth-child) 可继承的样式:font-size 、font-family、color、ul li 不可继承样式:border padding margin width height CSS优先级算法如何计算 优先级就近原则,同权重情况下样式定义最近者为准;载入样式以最后载入的定位为准; 优先级为:!important>id>class>tagimportant比内联优先级高 CSS3新增伪类有哪些? 举例:p:first-of-type 选择属于其父类的首个元素的每个元素p:last-of-type 选择属于其父类的最后元素的每个元素; p:only-of-type 选择属于其父类的唯一元素的每个元素p:only-child 选择属于其父类的唯一子元素的每个元素p:nth-child(2) 选择属于其父类的第二个子元素的每个元素 :after 在元素之前添加内容,也可以用来做清除浮动 :before 在元素之后添加内容:enabled:disabled 控制表单控件的禁用状态:checked 单选框或复选框被选中 如何居中div?如何居中一个浮动元素?如何让绝对定位的div居中? 给div设置一个宽度,然后添加margin:0 auto属性 div{ width:200px; margin:0 auto } 居中一个浮动元素 确定容器的宽高 宽500 高300的层设置层的外边距 div{ width:500px; height:300px;//高度可以不设 margin:-150px 0 0 250px; position:relative;//相对定位 background-color:pink;//方便看效果 left:50%; top:50%; } 让绝对定位的div居中 div{ position:absolute; width:1200px; background:pink; margin:0 auto; top:0; left:0; bottom:0; right:0; } display有哪些值?说明他们的作用 block 像块类型元素一样显示。none 不显示inline 像行内元素一样显示,inline-block 像行内元素一样显示,但其内容像块类型元素一样显示。list-item 像块类型元素一样显示,并添加样式列表标记table 此元素会作为块级表格来显示inherit 规定应该从父元素继承display属性的值 position的值relative和absolute定位原点是? absolute 生成绝对定位的元素,相对于值不为static的第一个父元素进行定位。 fixed(老IE不支持)生成绝对定位的元素,相对于浏览器窗口进行定位。 relative 生成相对定位的元素,相对于其正常位置进行定位 static默认值。没有定位,元素出现在正常的流中(忽略top,bottom,left,right,z-index) inherit规定从父元素继承position属性的值。 CSS3有哪些新特性? 新增各种CSS选择器 (:not(.input):所有class不是input的节点)圆角 (border-radius)多列布局 (multi-column layout)阴影和反射 (shadow\\reflect)文字特效 (text-shadow)文字渲染(text-decoration)线性渐变 (gradient)旋转(transform)增加了旋转,缩放,定位,倾斜,动画,多背景 transform:\\scale(0.85,0.90)\\ translate(0px,-30px)\\ skew(-9deg,0deg)\\Animation: 用纯CSS创建一个三角形的原理是什么? 把上、左右、三条边隐藏掉(颜色为transparent) div{ width:0; height:0; border-width:20px; border-style:solid; border-color:transparent transparent red transparent; } 一个满屏 品 字布局如何设计 简单方式 上面的div宽100%下面的两个div分别宽50%然后用float或者inline使其不换行即可 经常遇到的浏览器的兼容行有哪些?原因,解决方法是什么,常用hack的技巧? 1.png24位的图片在IE6上出现背景,解决方法是做成png82.浏览器默认的margin和padding不同,解决方案是加一个全局的*{margin:0,padding 0}来统一3.IE6双边距bug:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置大,浮动IE产生的双倍距离,解决方案是在float的标签样式控制中加入-display:inline,将其转换为行内属性(这个符号渐进识别的方法,从总体中逐渐排除局部) 首先,巧妙的使用“\\9”这一标记,将IE游览器从所有情况中分离出来。 接着,再次使用“+”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。 css .bb{ background-color:#f1ee18;/*所有识别*/ .background-color:#00deff\\9; /*IE6、7、8识别*/ +background-color:#a200ff;/*IE6、7识别*/ _background-color:#1e0bd1;/*IE6识别*/ } 4.在IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性,FF中,只能通过getAttribute()获取自定义属性。解决方法:统一用getAttribute()获取自定义属性。5.IE下,event对象有x,y属性,但是没有pageX,pageY属性;FF中,刚好相反6.chrome中文界面下默认会将小于12px的文本强制按照12px显示,可以通过加入CSS属性-webkit-text-size-adjust:none解决。7.超链接访问过后hover样式就不出现了,被点击访问过的超链接样式不存在hover和active了解决方法是改变css属性的排列顺序L-V-H-A : a:link {} a:visited {} a:hover {} a:active {} li和li之间看不见的空白间隔是什么原因引起的?有什么解决方法? 行框的排列会受到中间空白(回车\\空格)等的影响,因为空格也属于字符,这些空白也会应用样式,占据空间,所以会有间隔,把字符大小设为0,就没有空格了。 为什么要初始化CSS样式 因为浏览器的兼容性问题,不同浏览器对所有标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。 absolute的containing block(容器块)计算方式和正常流有什么不同? 无论属于那种,都要找到其祖先元素中最近的position值不为static的元素,然后再判断 若此元素为inline元素,则containing block为能够包含这个元素生成的第一个和最后一个inline box的padding box(除margin,border外的区域)的最小矩形;否则,则由这个祖先元素的paddingbox构成。如果都找不到,则为initial containing block。 补充1.static(默认)/relative:简单来说就是它的父元素的内容框(即去掉padding的部分)2.absolute:向上找最近的定位为absolute/relative的元素3.fixed:她的containing block 一律为根元素(html/body),根元素也是initial containing block 什么是css预处理器/后处理器 预处理器例如 LESS Sass Stylus用来预编译Sass或less,增强css代码的复用性。还有层级、mixin、变量、循环、函数等,具有很方便的UI组件模块化开发能力,极大的提高工作效率 后处理器:PostCSS,通常被视为在完成的样式中根据css规范处理css,让其更有效,目前最常做的的是给CSS属性添加浏览器私有前缀,实现跨浏览器兼容性的问题。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-05 18:19:14 "},"css/css面试题2.html":{"url":"css/css面试题2.html","title":"css面试题2","keywords":"","body":"display:none和visibility:hidden的区别? dispaly:none 隐藏对应的元素,在文档不居中不再给它分配空间,它各边的元素会合拢,就当他从来不存在。visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间。 css中link和@import的区别是? 1.link属于html标签,而@import是css提供的;2 页面被加载时,link会同时被加载,而@import被引入的css会等到引用它的css文件被加载完后再加载;3 import只在IE5以上才能识别,而link是HTML标签,无兼容问题;4 link方式的样式的权重,高于@import的权重 position:absolute和float属性的异同 共同点:对内联元素设置float和absolute属性,可以让元素脱离文档流,并且可以设置其宽高。 不同点:float仍会占据位置,absolute会覆盖文档流中的其他元素。 介绍一下box-sizing属性? box-sizing属性主要用来控制元素的盒模型的解析模式。默认值是content-box。 content-box:让元素维持W3C的标准盒模型。元素的宽度/高度由border+padding+content的宽度/高度决定,设置width/height属性指的是content部分的宽/高 border-box:让元素维持IE传统盒模型(IE6以下版本和IE6-7的怪异模式)。设置width/height属性指的是border+padding+content 标准浏览器下,按照W3C规范对盒模型解析,一旦修改了元素的边框或内距,就会影响元素的盒子尺寸,就不得不重新计算元素的盒子尺寸,从而影响这个页面的布局。 CSS选择符有哪些?哪些属性能继承?优先级算法如何计算?CSS3新增伪类有哪些? id选择器(#myid) 类选择器(.myclassname) 标签选择器(div,h1,p) 相邻选择器(h1+p) 子选择器(ul>li) 后代选择器(li a) 通配符选择器(*) 属性选择器(a[rel=\"external\"]) 伪类选择器(a:hover,li:nth-child) 优先级为: !important>id>class>tag important比内联优先级高,但内联比id要高 css3新增伪类举例? p:first-of-type 选择属于父元素的首个元素的每个元素。 p:last-of-type 选择属于其父元素的最后元素的每个元素。 p:only-of-type 选择属于父元素唯一的元素的每个元素。 p:only-child 选择属于父元素的唯一子元素的每个元素。 p:nth-child(2) 选择属于父元素的第二个子元素的每个元素 :enabled :disabled控制表单控件的禁用状态。 :checked 单选框或复选框被选中。 css3有哪些新特性? css3实现圆角(border-radius),阴影(box-shadow), 对文字加特效(text-shadow),线性渐变(gradient),旋转(transform) transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);//旋转,缩放,定位,倾斜 增加了更多的css选择器,多背景 rgba 在css3中唯一引入的伪元素是::selection 媒体查询,多栏布局 border-image css3中新增了一种盒模型计算方式:box-siziing。盒模型默认的值是content-box,新增的值是padding-box和border-box,几种盒模型计算元素宽高的区别如下: content-box(默认) 布局所占宽度Width: Width=width+padding-left+padding-right+border-left+border-right 布局所占高度Height: Height=height+padding-top+padding-bottom+border-top+border-bottom padding-box: 布局所占宽度Width: Width=width(包含padding-left+padding-right)+border-left+border-right 布局所占高度Height: Height=height(包含padding-top+padding-bottom)+border-top+border-bottom border-box 布局所占宽度Width: Width=width(包含padding-left+padding-right+border-left+border-right) 布局所占高度Height: Height=height(包含padding-top+padding-bottom+border-top+border-bottom) 对BFC规范的理解? BFC,块级格式化上下文,一个创建了新的BFC的盒子是独立布局的,盒子里面的子元素的样式不会影响到外面的元素。在同一个BFC的两个毗邻的块级盒在垂直方向(和布局方向有关系)的margin会发生折叠。 W3c CSS 2.1规范中的一个概念,它决定了元素如何对其内容进行布局,以及其他元素的关系和相互作用。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:58:09 "},"interview/面试地址.html":{"url":"interview/面试地址.html","title":"面试地址","keywords":"","body":" 2016各大互联网公司前端面试题汇总 2016-嘀嘀打车 2016-360篇 2016-网易互联网 2016-美团前端 2016-腾讯篇 2016-阿里巴巴篇 2016-百度篇 2017-6-26 公司面试题 面试-Javascript题 js面试题1 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 14:51:30 "},"interview/面试须知.html":{"url":"interview/面试须知.html","title":"面试须知","keywords":"","body":"1. 上班时间 2. 加班比例及措施 3. 社保基础 4. 公积金基数和比例 5. 是否有餐补,如果有是多少一天 6. 是否有生日补助 7. 是否有节假日补助 8. 是否有年终奖 9. 年终奖发放时间及比例及时间范围 10. 工资组成 11. 事假工资 12. 婚假工资 13. 丧假工资 14. 生育假工资 15. 病假工资 16. 可以补缴社保和公积金吗 17. 公积金和社保是入职当月开始购买(15号前),还是下月 18. 员工体检要求(满一年,满2年) Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 14:51:43 "},"interview/2017-6-26公司面试题.html":{"url":"interview/2017-6-26公司面试题.html","title":"2017-6-26 公司面试题","keywords":"","body":"HTML 部分 1.HTML doctype作用 告知浏览器文档使用哪种 HTML 或 XHTML 规范 2.HTML与XHTML有何不同 以下是 XHTML 相对 HTML 的几大区别: XHTML 要求正确嵌套 XHTML 所有元素必须关闭 XHTML 区分大小写 XHTML 属性值要用双引号 XHTML 用 id 属性代替 name 属性 XHTML 特殊字符的处理 3.HTML data-*属性的作用 使用data-* 属性来嵌入自定义数据 4.描述,,的不同 没有defer或async属性,浏览器会立即加载并执行相应的脚本。也就是说在渲染script标签之后的文档之前,不等待后续加载的文档元素,读到就开始加载和执行,此举会阻塞后续文档的加载; 有了async属性,表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行; 有了defer属性,加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前。 defer 和 async 的共同点是都是可以并行加载JS文件,不会阻塞页面的加载,不同点是 defer的加载完成之后,JS会等待整个页面全部加载完成了再执行,而async是加载完成之后,会马上执行JS,所以假如对JS的执行有严格顺序的话,那么建议用 defer加载。 5.使用过哪些模板引擎,可描述一下相关优缺点。 CSS部分 1.简述一下Float元素原理机制 浮动出现的意义其实只是用来让文字环绕图片而已,仅此而已 1. 设置了float的元素不会脱离文档流,会导致其父元素出现“坍塌”的现象,不错,这就是它的破坏性 display:inline-block 2.块级元素如果不设置float,它默认会撑满整个屏幕,而如果设置了float,则只会包裹住其内容,直接上例子吧。 3.float还有一个很有用的特性,就是清除空格 2.inine、inline-block的不同 display:block 1.block元素会独占一行,多个block元素会各自新起一行。默认情况下,block元素宽度自动填满其父元素宽度。 2.block元素可以设置width,height属性。块级元素即使设置了宽度,仍然是独占一行。 3.block元素可以设置margin和padding属性。 4.和是块元素的列子 display:inline 1.inline元素不会独占一行,多个相邻的行内元素会排列在同一行里,直到一行排列不下,才会新换一行,其宽度随元素的内容而变化。 2.inline元素设置width,height属性无效。 3.inline元素的margin和padding属性,水平方向都产生边距效果,但竖直方向不会产生边距效果 4.和是inline元素的例子 display:inline-block 1.简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现。之后的内联对象会被排列在同一行内。比如我们可以给一个link(a元素)inline-block属性值,使其既具有block的宽度高度特性又有inline的同行特性。 3.Class,ID选择器的不同 1.相同的class属性值,可以在html中出现多次。id属性值在页面中只能出现一次。 2.一个class的属性可以有多个值,也就是说一个标签可以有多个类,但是能有一个id 3.id的优先级比class要高 注意: ID属性和类名不要以数字开头,否则无法在Mozilla或Firefox中起作用 4.解析一下你理解的盒子模型一级如何在不同的盒子模型下渲染页面 盒子模型份范围包括margin、border、padding、content这4部分 盒子模型分为两类:W3C标准盒子模型(content-box)和IE盒子模型(border-box)eg:box-sizing:border-box 这两者的关键差别就在于: W3C盒子模型——属性高(height)和属性宽(width)这两个值不包含填充(padding)和边框(border)即width=content_width IE盒子模型——属性高(height)和属性宽(width)这两个值包含填充(padding)和边框(border)即width=content_width+padding_left+padding_right+border_left+border_right 那应该选择哪种盒子模型呢?一般选择“标准w3c盒子模型” 怎么样才算选择了\"\"标准w3c盒子模型呢\"?很简单,就是在网页的顶部加上doctype声明。 5.列出使用过的css框架?如果优化(SEO)经验可以举例说明。 Bootstrap 首先,你要确定你要优化的主要关键词,还有一些长尾的关键词。 其次,把你确定好的关键词设置到你网站的标题、关键词、描述里面。 然后,就多在网站内部更新相关资讯(新闻)最好是跟行业相关的,里面放点优化的关键词也是可以的。 最后,多去外面的博客、论坛发文章,必须是带链接的文章。增加网站外链。 JavaScript部分 1.javascript中的this是如何工作的 1. this 永远指向函数运行时所在的对象,而不是函数被创建时所在的对象。 2.匿名函数或不处于任何对象中的函数指向 window 3.如果是call,apply,with,指定的this是谁,就是谁 2.JavaScript中的变量、函数声明执行机制?变量声明与和与函数声明哪个优先级更高(可举例说明) 变量声明>函数声明>变量赋值 1.函数声明优先级高于变量声明 2.变量和赋值语句一起书写,在js引擎解析时,会将其拆成声明和赋值2部分,声明置顶,赋值保留在原来位置 3.function Person(){},var andy=Person(),var jack=new Person(),请说明andy与jack有和不同? 1.andy只是一个返回值 2.jack是Person的实例 4.JavaScript实现继承的方式有哪些?请简要写出示例代码(至少一个示例支持多重继承),并分别说明他们的优缺点 1.原型链 2.借用构造函数 3.组合继承 4.原型式继承 5.寄生式继承 6.寄生组合式继承 5.请列举熟悉的js框架 jQuery Angular React vue Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:04:06 "},"interview/2016-360篇.html":{"url":"interview/2016-360篇.html","title":"2016-360篇 公司面试题","keywords":"","body":"一、问题 1 下面代码的输出值是: alert(1&&2) 答案:2 参考: 解析 2 正则表达式匹配,开头为11N, 12N或1NNN,后面是-7-8个数字的电话号码 答案: ^(11N||12N||1NNN)-\\d{7,8} 3 写出下面代码的输出值 var obj = { a: 1, b: function () {console.log(this.a)} }; var a = 2; var objb = obj.b; obj.b(); objb(); obj.b.call(window); 答案:1,2,2 4 写出下列代码在各个浏览器中的颜色值? background: red; _background: green; *background: blue; background: black\\9; 答案: 5 输出下面的值: var a = 1; function b() { var a = 2; function c() { console.log(a); } return c; } b()(); 答案:2 6 简述在IE下mouseover和mouseenter的区别? mouseover与mouseenter 不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件。 只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件。 mouseout与mouseleave 不论鼠标指针离开被选元素还是任何子元素,都会触发 mouseout 事件。 只有在鼠标指针离开被选元素时,才会触发 mouseleave 事件。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:05:13 "},"interview/2016-嘀嘀打车.html":{"url":"interview/2016-嘀嘀打车.html","title":"2016-嘀嘀打车","keywords":"","body":"一、问题 1 location.replace/loation.asign的区别? 2 对于浮动的理解,清除浮动的方法及原理? 3 前后端分离及前后端协同开发方案 4 angular数据绑定采用什么机制?远离是什么? 5 ng-if与ng-show/hide的区别[Angular方面]? 6 从前公司学到了那些优秀经验 7 常用浏览器及内核,对于渲染引擎与js解释引擎的区分 8 如何判断不同的浏览器 9 transform 都可以有哪些值? 10 css3怎么实现花瓣飘落效果? Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:06:05 "},"interview/2016-网易互联网.html":{"url":"interview/2016-网易互联网.html","title":"2016-网易互联网","keywords":"","body":"一、问题 1 给出设计图实现HTML/CSS/js 实现表单ajax提交并刷新页面? 2 给Object扩展一个方法clone,实现深度克隆对象 3 输入两个数字,输出这两个数字的最大公约数。如16,4输出4 4 说说 React 中的virtual dom原理? 5 css实现超出字体内容出现 ... 6 css position 中有哪些值可以使用? Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:06:57 "},"interview/2016-阿里巴巴篇.html":{"url":"interview/2016-阿里巴巴篇.html","title":"2016-阿里巴巴篇","keywords":"","body":"一、问题 1 创建一个1-100的数组,按顺序递增 2 说说前端跨域的解决方式 3 JavaScript实现继承的常用方法有哪些?你推荐的是哪一种? 4 在项目开发完成之后,根据雅虎性能优化规则,需要对html,JS,CSS,图片需要做出怎样的处理?是否可以借助构建工具实现自动化? 5 说说前端中的事件流? 6 JS 中的原型链是什么? 7 有一个长度为100的数组,请以优雅的方式求出该数组的前10个元素之和 8 了解过flex布局吗?说说它和传统布局的有何不同? 9 移动端的图片优化实践方式有哪些? 10 请编写一个JavaScript函数 parseQueryString,它的用途是把URL参数解析为一个对象 11 xss和csrf分别是什么? 12 说说前端如何解决异步回调地狱? 13 淘宝那里的商品项,如图片,滚动到了才加载,你知道怎么实现么 14 实现1px 像素线条 15 你知道什么是CSS reset么? Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:10:03 "},"interview/2016-腾讯篇.html":{"url":"interview/2016-腾讯篇.html","title":"2016-腾讯篇","keywords":"","body":"一、问题 1 说出前端link和import的区别 2 让你设计一个web站点,假如只有你一个人设计实现,前端后端都让你一个人负责,具体你要怎么做? 3 你用原生的js多么,原生js发送ajax请求一般要经过哪些步骤 4 你能讲讲304缓存的原理吗? 5 你有经常使用CSS吧,水平垂直居中怎么实现? 6 Javascript是一种弱类型语言,它分别有什么优点和缺点? 7 在js里call()与apply()有什么相同和不同? 8 你用JS实现过一些基本的数据结构吗? 9 node.js用过么?主要用它来做些什么? Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:10:50 "},"interview/2016-百度篇.html":{"url":"interview/2016-百度篇.html","title":"2016-百度篇","keywords":"","body":"一、问题 1 写出javascript运行结果: for(var i=0; i2 Cookie、sessionStorage、localStorage的区别 3 JSONP原理 4 简述css盒模型 5 说说get和post请求的区别 6 运行结果 var a = {n: 1}var b = a;a.x = a = {n: 2}console.log(a.x);console.log(b.x) 7 说说类的创建、继承和闭包。 8 是否有设计过通用的组件? 请设计一个 Dialog(弹出层) / Suggestion(自动完成) / Slider(图片轮播) 等组件,你会提供什么接口?调用过程是怎样的?可能会遇到什么细节问题? 9 一个页面从输入 URL 到页面加载完的过程中都发生了什么事情?越详细越好(考察知识广度) 10 什么是 “use strict”? 使用它的好处和坏处是什么? 二、解答 1 写出javascript运行结果: for(var i=0; i答案:10 知识点:块级作用域的问题,JavaScript没有这个概念,所以i在for循环之外依然存在 2 Cookie、sessionStorage、localStorage的区别 答案 3 JSONP原理 4 简述css盒模型 css 盒子模型理解 5 说说get和post请求的区别 HTTP 方法:GET 对比 POST 6 运行结果 var a = {n: 1} var b = a; a.x = a = {n: 2} console.log(a.x); console.log(b.x) 答案:undefined 、{n:1} 参考解析:百度知道、博客园 知识点:引用类型赋值,“.”操作符的优先级 7 说说类的创建、继承和闭包。 8 是否有设计过通用的组件? 请设计一个 Dialog(弹出层) / Suggestion(自动完成) / Slider(图片轮播) 等组件,你会提供什么接口?调用过程是怎样的?可能会遇到什么细节问题? 9 一个页面从输入 URL 到页面加载完的过程中都发生了什么事情?越详细越好(考察知识广度) 输入地址 浏览器查找域名的 IP 地址 这一步包括 DNS 具体的查找过程,包括:浏览器缓存->系统缓存->路由器缓存... 浏览器向 web 服务器发送一个 HTTP 请求 服务器的永久重定向响应(从 http://example.com 到 http://www.example.com) 浏览器跟踪重定向地址 服务器处理请求 服务器返回一个 HTTP 响应 浏览器显示 HTML 浏览器发送请求获取嵌入在 HTML中的资源(如图片、音频、视频、CSS、JS等等) 浏览器发送异步请求 10 什么是 “use strict”? 使用它的好处和坏处是什么? Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:11:41 "},"interview/谈谈性能优化的问题.html":{"url":"interview/谈谈性能优化的问题.html","title":"谈谈性能优化的问题","keywords":"","body":"谈谈性能优化的问题 代码层面:避免使用css表达式,避免使用高级选择器,通配选择器。 缓存利用:缓存Ajax,使用CDN,使用外部js和css文件以便缓存,添加Expires头,服务端配置Etag,减少DNS查找等 请求数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。 请求贷款:压缩文件,开启GZIP 代码层面的优化 用hash-table来优化查找 少用全局变量 用innerHTML代替DOM操作,减少DOM操作次数,优化JavaScript性能 用setTimeout来避免页面失去响应 缓存DOM节点查找的结果 避免使用css Expression 避免全局查询 避免使用with(with会创建自己的作用域,会增加作用域链长度) 多个变量声明合并 避免图片和iFrame等的空Src。空Src会重新加载当前页面,影响速度和效率 尽量避免写在HTML标签中写style属性 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:28:57 "},"interview/Javascript面试题.html":{"url":"interview/Javascript面试题.html","title":"Javascript面试题","keywords":"","body":" 介绍js的基本数据类型 Undefined、Null、Boolean、Number、String 介绍js有哪些内置对象 Object 是JavaScript中所有对象的父对象数据封装类对象:Object、Array、Boolean、Number和String其他对象:Function、Argument、Math、Date、RegExp、Error 说几条写javascript的基本规范? 1.不要在同一行声明多个变量2.请使用===/!==来比较true/false或者数值3.使用对象字面量替代new Array这种形式4.不要使用全部函数5.Switch语句必须带有default分支6.函数不应该有时候有返回值,有时候没有返回值7.For 循环必须使用大括号8.If语句必须使用大括号9.for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染 JavaScript原型,原型链?有什么特点? 每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时说的原型链的概念。 特点: JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。 当我们需要一个属性时,JavaScript引擎会先看当前对象中是否有这个属性,如果没有的话,就会查找他的prototype对象是否有这个属性,如此递推下去,一直检索到Object内建对象 function Func(){} Func.prototype.name=\"Sean\"; Func.prototype.getInfo=function(){ return this.name; } var person=new Func();//现在可以参考var person=Object.create(oldObject); console.log(person.getInfo()); //\"Sean\" console.log(Func.prototype);//Func { name=\"Sean\", getInfo=function()} JavaScript中有几种类型的值?能画一下他们的内存图吗? 栈: 原始数据类型(Undefined,Null,Boolean,Number,String)堆: 引用数据类型(对象、数组和函数)两种类型的区别::存储位置不同 原始数据直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储; 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当 解释器寻找引用指时,会首先检索其在栈中的地址,取得地址后从堆中获得实体 JavaScript如何实现继承 1.构造继承2.原型继承3.实例继承4.拷贝继承 原型prototype机制或applay和call方法去实现交简单,建议使用构造函数和原型混合方式。 function Parent(){ this.name='Wang'; } function Child(){ this.age=28; } Child.prototype=new Parent();//继承Parent,通过原型 var demo=new Child(); console.log(demo.age); console.log(demo.name);//得到被继承的属性 JavaScript继承的几种方式实现? 参考:构造函数的继承,非构造函数的继承; JavaScript创建对象的几种方式? JavaScript创建对象简单来说,无非就是使用内置对象或者各自自定义对象,当然还可以用json;但写法有很多种,也能混合使用。 1.对象字面量的方式 person={firstname:\"mark\",lastname:\"yun\"}; 2.用function来模拟无参数的构造函数 function Person(){ var person=new Person();//定义一个function,如果使用new\"实例化\",该function可以看做是一个Class person.name='Mark'; person.age=25; person.work=function(){ console.log(person.name+'hello '); } } person.work(); 3.用function来模拟有参数的构造函数来实现(用this关键字定义构造的上下文属性) function Pet(name,age,hobby){ this.name=name; this.age=age; this.hobby=hobby; this.eat=function(){ console.log(\"我叫\"+this.name+\",我喜欢\"+this.hobby+\",是个程序员\"); } } var maidou=new Pet(\"麦兜\",25,\"coding\");//实例化、创建对象 maidou.eat();//调用eat方法 4.用工厂方式来创建(内置对象) var wcDog=new Object(); wcDog.name=\"旺财\"; wcDog.age=3; wcDog.work=function(){ console.log(\"我是\"+wcDog.name+',汪汪汪...') } wcDog.work(); 5.用原型方式来创建 function Dog(){} Dog.prototype.name=\"旺财\"; Dog.prototype.eat=function(){ console.log(this.name+\"是个吃货\"); } var wangcai=new Dog(); wangcai.eat(); 6.用混合方式来创建 function Car(name,price){ this.name=name; this.price=price; } Car.prototype.sell=function(){ console.log(\"我是\"+this.name+\",我现在卖\"+this.price+\"万元\") } var camry=new Car(\"凯美瑞\",27); camry.sell(); javascript作用域链 全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找,直至全局函数,这种组织形式就是作用域链。 谈谈This对象的理解 1.this总是指向函数的直接调用者(而非间接调用者);2.如果有new关键字,this指向new出来的那个对象;3.在事件中,this指向触发这个事件的对象,特殊的是,IS中的attachEvent中的this总是指向全局对象window; eval是做什么的? 它的功能是把对应的字符串解析成js代码并执行应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。由json字符串转换为JSon对象的时候可以用eval,var obj=eval('('+str+')'); 什么是window 对象?什么是document 对象? 简单来说,document是window的一个对象属性。Window对象表示浏览器中打开的窗口。如果文档包含框架(frame或iframe标签),浏览器会为html文档创建一个window对象,并为每个框架创建一个额外的window对象。所有的全局函数和对象都属于window对象的属性和方法。 document对Document的只读引用 null,undefined的区别 null是一个表示\"无\"的对象,转为数值的时候为0;undefined是一个表示\"无\"的原始值,转换为数值时为NaN undefined1.变量被生命了,但是没有赋值时,等于undefined。2.调用函数时,应该提供的参数没有提供,该参数为undefined。3.对象没有赋值的属性,该属性为undefined4.函数没有返回值时,默认返回undefined5.typeof undefined//undefined null1.作为函数的蚕食,表示该函数的参数不是对象。2.作为对象原型链的重点。3.typeof null//object 注意:在验证null时,一定要用===,因为==无法分别null和undefined call()和apply()的区别和作用 apply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。如何上下文是null,则使用全局对象代替。如:function.apply(this,[1,2,3]); call()的第一个参数是上下文,后续是实例传入的参数序列。如:function.call(this,1,2,3); JSON的了解 JSON(javascript Object Notation)是一种轻量级的数据交换格式。它是基于javascript的一个子集。数据格式简单,易于读写,占用带宽小。格式:采用键值对,例如:{\"age\":\"12\",\"name\":\"back\"}; JSON字符串转换为JSON对象: var obj =eval('('+ str +')'); var obj = str.parseJSON(); var obj = JSON.parse(str); JSON对象转换为JSON字符串: var last=obj.toJSONString(); var last=JSON.stringify(obj); new操作符具体干了什么呢? 1.创建一个空对象,并且this变量引用该变量,同时还继承了该函数的原型。2.属性和方法被加入到this引用的对象中。3.新创建的对象由this所引用,并且最后返回隐式的this。 {'age':'12','name':'back'} DOM怎样添加、移除、移动、赋值、创建和查找节点 写一个通用的事件侦听器函数。 [\"1\",\"2\",\"3\"].map(parseInt)答案是多少? [1,NaN,NaN]因为parseInt需要两个参数(val,radix) 其中radix表示解析时用的基数。map传了三个(element,index,array),对应的radix不合法导致解析失败。 事件是?IE和火狐的事件机制有什么区别?如何阻止冒泡? 我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被javascript侦测到的行为。 事件处理机制:IE是事件冒泡、Firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件。 ev.stopPropagation();(旧ie的方法ev。cancelBubble=true) 什么是闭包(closure),为什么要用它 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数 闭包的特性1.函数内再嵌套函数2.内部函数可以引用外层的参数和变量3.参数和变量不会被垃圾回收机制回收 //li节点的onclick事件都能正确的弹出当前被点击的li索引 index = 0 index = 1 index = 2 index = 3 var nodes = document.getElementsByTagName(\"li\"); for(i = 0;i 执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在 使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源 因为say667()的内部函数的执行需要依赖say667()中的变量 这是对闭包作用的非常直白的描述 ```javascript function say667() { // Local variable that ends up within closure var num = 666; var sayAlert = function() { alert(num); } num++; return sayAlert; } var sayAlert = say667(); sayAlert()//执行结果应该弹出的667 * #### javascript代码中的\"use strict\"是什么意思?使用它区别是什么? >use strict 是一种ECMAscript 5添加的(严格)运行模式,这种模式使得javascript在更严格的条件下运行 >使编码更加规范化的模式,消除javascript语法的的一些不合理、不严谨之处,减少一些怪异行为。 >默认支持的糟糕特性都会被禁用,比如不能用with,也不能在意外的情况下给全局变量赋值; >全局变量的显示声明,函数必须声明在顶层,不允许在非函数代码块内声明函数,argument.callee也不允许使用; >消除代码运行的一些不安全之处,保证代码运行的安全,限制函数中的argument修改,严格模式下的eval函数的行为和非严格模式的也不相同; >提高编译器效率,增加运行速度; >为未来新版本的javascript标准做铺垫 * #### 如何判断一个对象是否属于某各类 >使用instanceof ```javascript if(a instanceof Person){ alert('yes'); } javascript中,有一个函数,执行时对象查找时,永远不会查找原型,这个函数是? hasOwnProperty javascript中hasOwnProperty函数是返回一个布尔值,指出一个对象是否具有制定名称的属性。此方法无法检查该对象的原型链中是否有该属性,该属性必须是对象本身的一个成员。使用方法:object.hasOwnProperty(proname)如果object具有指定名称的属性,那么javascript中hasOwnProperty函数方法返回true,反之返回false js延时加载的方式有哪些? defer和async、动态创建DOM方式(用的最多)、按需异步载入js Ajax是什么?如何创建一个Ajax ajax的全称:Asynchronous javascript And XMl异步传输+JS+XML所谓异步,在这里简单的解释就是:像服务器发送请求的时候,我们不必等待结果,而是同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。 1.创建XMLHttpRequest对象,也就是创建一个异步调用对象;2.创建一个新的httpRequest对象,也就是创建一个异步调用对象;3.设置响应http请求状态变化的函数;4.发送http请求;5.获取异步调用返回的数据;6.使用javascript和dom实现局部刷新 同步和异步的区别? 同步的概念应该是来自OS中关于同步的概念:不同进行为协同完成某项工作而在先后次序上调整(通过阻塞,唤醒等方式),同步强调的是顺序性,谁先谁后,异步则不存在这种顺序性。 同步:浏览器访问服务器请求,用户看的到页面刷新,重新发送请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作。异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求,等请求完,页面不刷新,新内容也会出现,用户看到新内容。 如何解决跨域问题 参考 页面编码和被请求的资源编码如果不一致如何处理 模块化开发怎么做? 立即执行函数,不暴露私有成员 var module1 = (function(){ var _count = 0; var m1 = function(){ //... }; var m2 = function(){ //... }; return { m1 : m1, m2 : m2 }; })(); document.write和innerHTMl的区别 document.write只能重绘整个页面innerHtml可以重绘页面的一部分 DOM操作,怎样添加、移除、移动、复制、创建和查找节点? 创建节点 createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体的元素 createTextNode() //创建一个文本节点 (2)添加、移除、替换、插入 appendChild() removeChild() replaceChild() insertBefore() //在已有的子节点前插入一个新的子节点 (3)查找 getElementsByTagName() //通过标签名称 getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的) getElementById() //通过元素Id,唯一性 检测浏览器版本有哪些方式? 功能检测、userAgent特征检测 比如:navigator.userAgent //\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36\" Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:13:43 "},"interview/Javascript面试2.html":{"url":"interview/Javascript面试2.html","title":"Javascript面试题2","keywords":"","body":"1.类型转换为字符串类型有哪些形式,请写出具体代码。 答:var num=123; num.toString();String(num); 2.请写出代码中console.log将会打印什么? var scope=\"global\"; function log(){ var args=Array.prototype.join.call(arguments,\",\"); //console.log(this); console.log(this.scope+\":\"+args); } var dog={ scope:\"dog\", yelp:function(){ var scope=\"dog.yelp\"; log('wow'); } }; dog.yelp(); dog.yelp.call(dog); log.apply(dog,['created']) 答:global:wowglobal:wow (this只跟执行环境的上下文有关,这道题,log原本的作用于是全局)dog:cretated (call的作用域问题,log的作用域被修改为dog。) 3.写一个通用的正则表达式,并从变量text中匹配所有的数字 答:var test=\"123lkj/.,k2\";test.match(/\\d+/ig) 4.如何判断一个变量是字符串?如何判断一个对象是数组 答: var name=\"123\"; var arr=[1,2,3]; console.log(typeof name); console.log(arr instanceof Array) 5.请用promise改写下列代码 $(document).ready(funtion(){ $.get('/get/user/info',funtion(result){ $.get('/get/city?city='+result.user.city,funtion(city){ //show city info }) }) }) 答: 6.有一div容器A,宽300px,高200px。另有一个list数据B:{'cn':20,'us':26,'au':98,'en':56}; 现在需要把这串数据可视化在A容器中: 要求: 1.以横向条形图(div)展现。2.最大值需顶足整个容器宽度。3.垂直方向需均匀分布。问:1.cn,us和au的条形(div)的width和垂直定位分别是多少?2.条形(div)和容器A(div)的css样式分别是怎么样的。 Title .parent{ width: 300px; height: 200px; border: 1px solid #ff0000; } .parent div{ width: 100%; text-align: center; height: 50px; line-height: 50px; } $(function(){ var obj={'cn':20,'us':26,'au':98,'en':56}; var html=\"\"; for(var x in obj){ html+=''+x+':'+obj[x]+''; } $('div').html(html); }) 答:1.width:100% ,25px,75px,125px2.如代码所示 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:17:41 "},"interview/作用域的面试题.html":{"url":"interview/作用域的面试题.html","title":"作用域的面试题","keywords":"","body":"问题1:Scope作用域范围 (function(){ var a=b=5; })(); console.log(b); 输出:5 这个问题的诀窍是,这里有两个变量声明,但 a 使用关键字var声明的。代表它是一个函数的局部变量。与此相反,b 变成了全局变量。 这个问题的另一个诀窍是,它没有使用严格模式 ('use strict'; ) 。如果启用了严格模式,代码就会引发ReferenceError的错误:B没有定义(b is not defined)。请记住,严格模式,则需要明确指定,才能实现全局变量声明。比如,你应该写 ```javascript (function() { 'use strict'; var a = window.b = 5; })(); console.log(b); #### 问题2:创建\"原生(native)\"方法 给字符串定义个repeatify功能。当传入一个整数n时,它会返回重复n次字符串的结果。 例如 ` console.log('hello'.repeatify(3));应该打印hellohellohello` ```javascript String.prototype.repeatify=String.prototype.repeatify||function(times){ var str=''; for(var i=0;i 现在的问题测试开发者有关JavaScript继承prototype的知识点。这也验证了开发者是否知道该如何扩展内置对象(尽管这不应该这么做的)。 这里的另一个要点是,你要知道如何不覆盖可能已经定义的功能。通过测试一些该功能定义之前并不存在: 问题3:声明提升(Hoisting) 执行这段代码,输出什么结果。 function test(){ console.log(a); console.log(foo()); var a=1; function foo(){ return 2; } } test(); 输出: undefined 2 原因是,变量和函数的声明都被提前了(移到了函数的顶部),但变量不分配任何值。因此,在打印变量的时候,它在函数中存在(它被声明了),但它仍然是undefined。表示换句话说,上面的代码等同于以下内容。 ```javascript function test(){ var a; function foo(){ return 2; } console.log(a); console.log(foo()); a=1; } test(); #### 问题4:this在JavaScript中是如何工作的 下面的代码会输出什么结果? ```javascript var fullname='John Doe'; var obj={ fullname:'Colin Ihtig', prop:{ fullname:'Aurelio De Rosa', getFullanme:function(){ return this.fullname; } } } console.log(obj.prop.getFullanme()); var test=obj.prop.getFullanme; console.log(test()) 答案是‘Aurelio De Rosa’和‘John Doe’。原因是,在一个函数中,this的行为取决于JavaScript函数的调用方式和定义方式,而不仅仅是看它如何被定义的。 在第一个console.log()调用中,getFullname()被调用作为obj.prop对象的函数,所以,上下文指的是后者,函数返回该对象的fullname。与此相反,当getFullname()被分配到test()变量时,上下文指的是全局变量(window)。这是因为test是被隐式设置为全局对象的属性。 问题5:call()和apply() 现在让你解决前一个问题,使最后的console.log()打印Aurelio De Rosa 回答 该问题可以通过强制使用call()或者apply()改变函数上下文。在下面我将使用call(),在这种情况下,apply()会输出相同的结果: 注: call()参数“,”隔开和apply()参数为数组形式 console.log(test.call(obj.prop)); 问题6:下列代码执行的结果 var length = 10; function fn(){ console.log(this.length) } var obj = { length: 5, method: function(fn) { fn() arguments[0]() } } obj.method(fn,1) 答: 10 ,2 解析 第二个没有输出5,也没有输出10,反而输出了2,有趣。这里arguments是javascript的一个内置对象(可以参见mdn:arguments - JavaScript),是一个类数组(就是长的比较像数组,但是欠缺一些数组的方法,可以用slice.call转换,具体参见上面的链接),其存储的是函数的参数。也就是说,这里arguments[0]指代的就是你method函数的第一个参数:fn,所以arguments[0]()的意思就是:fn()。 不过这里有个疑问,为何这里没有输出5呢?我method里面用this,不应该指向obj么,至少也会输出10呀,这个1是闹哪样? 实际上,这个1就是arguments.length,也就是本函数参数的个数。为啥这里的this指向了arguments呢?因为在Javascript里,数组只不过使用数字做属性名的方法,也就是说:arguments[0]()的意思,和arguments.0()的意思差不多(当然这么写是不允许的),你更可以这么理解: 问题7:作用域 var a = 6; setTimeout(function () { alert(a); a = 666; }, 1000); a = 66; 答:66 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:55:25 "},"interview/忘记var的副作用.html":{"url":"interview/忘记var的副作用.html","title":"忘记var的副作用","keywords":"","body":"参考链接: 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 1.忘记var的副作用 隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力。 通过var 创建的全局变量(任何函数之外的程序中创建)是不能被删除的。 无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。 这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的: ```javascript // 定义三个全局变量 var global_var = 1; global_novar = 2; // 反面教材 (function () { global_fromfunc = 3; // 反面教材 }()); // 试图删除 delete global_var; // false delete global_novar; // true delete global_fromfunc; // true // 测试该删除 typeof global_var; // \"number\" typeof global_novar; // \"undefined\" typeof global_fromfunc; // \"undefined ``` Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:56:09 "},"interview/赋值优先级和地址引用.html":{"url":"interview/赋值优先级和地址引用.html","title":"赋值优先级和地址引用","keywords":"","body":"- 博客园 - 百度知道 问题 var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x);// --> undefined console.log(b.x);// --> [object Object] 解析 var a = {n: 1} // 定义变量 a 为一个新对象,且这个新对象有一个值为 1 的 n 成员 var b = a; // 定义变量 b ,并且让 b 也引用变量 a 的对象 // 经过上面这两句之后,变量 a 和 b 都引用了对象 {n:1} // 下面这句是问题的关键 a.x = a = {n: 2} // a.x = 表示要给 a 引用的那个对象 {n:1} 的 x 成员赋值 // 实际上,此时变量 b 也引用了这个对象 {n:1} // 此时,JavaScript引擎首先给 {n:1} 添加一个空的 x 成员,即:{n:1,x:undefined} // 接下来要给{n:1,x:undefined}.x 赋的是什么值呢? // 要赋的值是 a = {n: 2} // 也就是先让变量 a 引用一个新的对象 {n:2} // 然后再把 a 的新值赋给 {n:1,x:undefined}.x // 所以原来的那个对象变成了 {n:1,x:{n:2}} // 由于变量 b 始终引用那个原来的对象,所以 b 的值是 {n:1,x:{n:2}} // 由于变量 a 被赋予了一个新的对象,所以 a 的值是 {n:2} // 这面这两句是控制台输出 console.log(a.x); // 变量 a 引用的对象是 {n:2},没有 x 成员,所以输出 undefined console.log(b.x); // 变量 b 引用的对象是 {n:1,x:{n:2}},所以输出 {n:2} Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:57:10 "},"interview/极易被忽视的javascript面试题七问七答.html":{"url":"interview/极易被忽视的javascript面试题七问七答.html","title":"极易被忽视的javascript面试题七问七答","keywords":"","body":"极易被忽视的javascript面试题七问七答 此题是我出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力。 题目如下 function Foo(){ getName=function(){ console.log(1); } return this; } 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(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); new new Foo().getName(); 此题是我综合之前的开发经验以及遇到的js各种坑汇集而成。此题涉及的知识点众多,包括变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性以及原型属性优先级等等。 此题包含7小文,分别如下: 第一问 先看此题的上半部分做了什么,首先定义了一个叫Foo的函数,之后为Foo创建了一个叫getName的静态属性存储了一个匿名函数,之后为Foo的原型对象创建了一个叫getName的匿名函数。之后又通过函数变量表达式创建了一个getName的函数,最后再声明一个叫getName的函数。 第一问的Foo.getName自然是访问Foo函数上存储的静态属性,自然是2,没什么可说的。 第二问 第二问,直接调用getName函数。既然是直接调用那么就是访问当前上下文左右域内的叫getName的函数,所以跟1 2 3 都没什么关系。此题有无数面试者回答为5。此处有两个坑,一是变量声明提升,二是函数表达式。 1、变量声明提升 即所有声明变量或声明函数都会被提升到当前函数的顶部。 例如下代码: console.log('x' in window);//true var x; x=0; 代码执行时js引擎会将声明语句提升至代码最上方,变为: var x; console.log('x' in window);//true x=0; 2、函数表达式 var getName与fuction getName 都是声明语句,区别在于var getName是函数表达式,而function getName是函数声明。关于JS中的各种函数创建方式可以看大部分人都会做错的经典js闭包面试题,这篇文章有详细说明。 函数表达式最大的问题,在于js会将此代码拆分为两行代码分别执行。 例如下代码: console.log(x);//输出:function x(){} var x=1; function x(){} 实际执行的代码为,先将var x=1拆分为var x;和x=1;两行,再将var x;和function x(){}两行提升至最上方变成: var x; function x(){}; console.log(x); x=1; 所以最终函数声明的x覆盖了变量声明的x,log输出为x函数。 同理,原题中代码最终执行时的是: function Foo(){ getName=function(){ console.log(1); }; return this; } var getName;//只提升变量声明 function getName(){ console.log(5);//提升函数声明,覆盖var的声明 } Foo.getName=function(){ console.log(2); } Foo.prototype.getName=function(){ console.log(3); } getName=function(){ console.log(4); };//最终的赋值再次覆盖function getName声明 getName();//最终输出4 第三问 第三问的Foo().getName();先执行了Foo函数,然后调用Foo函数的返回值对象的getName属性函数。 Foo函数的第一句 getName=function(){console.log(1);};是一句函数赋值语句,注意它没有var声明,所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是第二问中的alert(4)函数,将此变量的值赋值为function(){alert(1)}。 此处实际上是将外层作用域内的getName函数修改了。 注意: 此处若依然没有找到会一直向上查找到window对象,若window对象中也没有getName属性,就在window对象中创建一个getName变量。 之后Foo函数的返回值是this。而Js的this问题博客园已经有非常多的文章介绍,这里不再多说。 简单的讲,this的指向是由所在函数的调用方式决定的。而此处的直接调用当时,this指向window对象。 遂Foo函数返回的是window对象,相当于执行window.getName(),而window中的getName已经被修改为alert(1),所以最终会输出1 此处考察了两个知识点,一个是变量作用域问题,一个是this指向问题。 第四问 直接调用getName函数,相当于window.getName(),因为这个变量已经被Foo函数执行时修改了,遂结果与第三问相同,为1 第五问 第五问 new Foo.getName();此处考察的是js的运算符优先级问题。 通过查上表可以得知点(.)的优先级高于new操作,遂相当于: new (Foo.getname)(); 所以实际上将getName函数作为了够着函数来执行,遂弹出2。 第六问 第六问 new Foo().getName(),首先看运算符优先级括号高于new,实际执行位(new Foo()).getname() 遂先执行Foo函数,而Foo此时作为构造函数缺有返回值,所以这里需要说明下js中的构造函数返回值问题。 构造函数的返回值 在传统语言中,构造函数不应该有返回值,实际执行的返回值就是此构造函数的实例化对象。 而在js中构造函数可以有返回值也可以没有。 1、没有返回值则按照其他语言一样返回实例化对象。 > function F(){} new F() 2、若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本l类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。 > function F(){return true;} new F() 3、若返回值是引用类型,则实际返回值为这个引用类型。 > function F(){return true;} new F() 原题中,返回的是this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象。 之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(protocol)中寻找getName,找到了。 遂最终输出3。 第七问 第七问,new new Foo().getName();同样是运算符优先级问题。 最终执行为: new ((new Foo()).getName)(); 先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new。 遂最终结果为3 最后 就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。 只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:57:50 "},"interview/五个比较难的面试题.html":{"url":"interview/五个比较难的面试题.html","title":"五个比较难的面试题","keywords":"","body":"1. 找出数字数组中最大的元素(使用Match.max函数) 2. 转化一个数字数组为function数组(每个function都弹出相应的数字) 3. 给object数组进行排序(排序条件是每个元素对象的属性个数) 4. 利用JavaScript打印出Fibonacci数(不使用全局变量) 5. 实现如下语法功能:var a=(5).plus(3).minus(6);//2 6. 实现如下语法的功能: var a=add(2)(3)(4);//9 6. function add(x){ return function(y){ return function (z){ return x+y+z; } } } console.log(add(2)(3)(4));//9 // 实现一个add方法,使计算结果能够满足如下预期: add(1)(2)(3) = 6; add(1, 2, 3)(4) = 10; add(1)(2)(3)(4)(5) = 15; 前端基础进阶(八):深入详解函数的柯里化 - 简书 function add() { // 第一次执行时,定义一个数组专门用来存储所有的参数 var _args = [].slice.call(arguments); // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值 var adder = function () { var _adder = function() { // [].push.apply(_args, [].slice.call(arguments)); _args.push(...arguments); return _adder; }; // 利用隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回 _adder.toString = function () { return _args.reduce(function (a, b) { return a + b; }); } return _adder; } // return adder.apply(null, _args); return adder(..._args); } var a = add(1)(2)(3)(4); // f 10 var b = add(1, 2, 3, 4); // f 10 var c = add(1, 2)(3, 4); // f 10 var d = add(1, 2, 3)(4); // f 10 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:58:38 "},"interview/考验你的JavaScript底细.html":{"url":"interview/考验你的JavaScript底细.html","title":"考验你的JavaScript底细","keywords":"","body":"参考链接 QM 2017/6/26 1. (function(){ return typeof arguments; })(); A:\"object\" B:\"array\" C:\"arguments\" D:\"undefined\" 2. var f = function g(){ return 23; }; typeof g(); A:\"number\" B:\"undefined\" C:\"function\" D:Error 3. (function(x){ delete x; return x; })(1); A:1 B:null C:undefined D :Eror 4. var y = 1, x = y = typeof x; x; A:1 B:\"number\" C:undefined D:\"undefined\" 5. (function f(f){ return typeof f(); })(function(){ return 1; }); A:\"number\" B:\"undefined\" C:\"function\" D:Error 6. var foo = { bar: function() { return this.baz; }, baz: 1 }; (function(){ return typeof arguments[0](); })(foo.bar); A:\"undefined\" B:\"object\" C:\"number\" D:\"function\" 7. var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)(); A:\"undefined\" B:\"object\" C:\"number\" D:\"function\" 8. var f = ( function f(){ return \"1\"; }, function g(){ return 2; } )(); typeof f; A:\"string\" B:\"number\" C:\"function\" D:\"undefined\" 9. 不明白 var x = 1; if (function f(){}) { x += typeof f; } x; A:1 B:\"1funciton\" C:\"1undefined\" D:NaN 10. var x = [typeof x, typeof y][1]; typeof typeof x; A:\"number\" B:\"string\" C:\"undefined\" D:\"object\" 11. (function(foo){ return typeof foo.bar; })({ foo: { bar: 1 } }); A:\"undefined\" B:\"object\" C:\"number\" D:Error 12. (function f(){ function f(){ return 1; } return f(); function f(){ return 2; } })(); A:1 B:2 C:Error(e.g \"Too much recursion\") D:undefined 13. 不明白 function f(){ return f; } new f() instanceof f; A:true B:false 14. with (function(x, undefined){}) length; A:1 B:2 C:undefined D:error 答案 1:A2:D3:A4:D5:A6:A7:A8:B9:C10:B11:A12:B13:B14:B Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:59:28 "},"interview/this和声明优先.html":{"url":"interview/this和声明优先.html","title":"this和声明优先","keywords":"","body":"地址 问题1:\"1\" + 2 + \"3\" + 4结果是? 1234,加法优先级等同,从左往右,数字与字符串相加,数字转换为字符串进行运算,结果等同于:\"12\"+\"3\"+4=\"123\"+4=\"1234\"; 问题2:4 + 3 + 2 + \"1\"结果是? 答案:91,优先级同上,从左往右,等同于7+2+\"1\"=\"91\". 问题3:下列输出什么 var foo=1; function bar(){ foo=10; return; function foo(){} } bar(); console.log(foo); 答案:1,function的定义会提前到当前作用域之前,所以等同于: var foo = 1; function bar() { function foo() {} foo = 10; return; } bar(); console.log(foo);//1 所以,在foo=10的时候,foo是有定义的,属于局部变量,影响不到外层的foo。 问题4:下列输出什么 function bar(){ return foo; foo=10; function foo(){} var foo=11; } console.log(typeof bar()); 答案:function,JavaScript中函数声明优先于变量声明,等同于: function bar(){ var foo; function foo(){} return foo; foo=10; foo=11; } console.log(typeof bar()); 解析:js中的function声明和var声明都会被提前,最终得到function,是因为function声明优先级大于var声明,而不是由return语句返回导致 问题5:下列输出什么 var x=3; var foo={ x:2, baz:{ x:1, bar:function(){ return this.x; } } } var go=foo.baz.bar; console.log(go()); console.log(foo.baz.bar()); 答:3,1this指向执行时刻的作用域,go的作用域是全局,所以相当于window,取到的就是window.x,也就是var x=3;这里定义的x。而foo.baz.bar()里面,this指向foo.baz,所以取到的是这个上面的x,也就是1; 问题6:下列输出什么 var x=4, obj={ x:3, bar:function(){ var x=2; setTimeout(function(){ var x=1; console.log(this.x); },1000); } } obj.bar(); 答:4,不管有这个setTimeout还是把这个函数立即执行,它里面这个function都是孤立的,this只能是全局的window,即使不延时,改成立即执行结果同样是4。 问题7:下列输出什么 x=1; function bar(){ this.x=2; return x; } var foo= new bar(); console.log(foo.x); 答:2,这里主要问题是最外面x的定义,试试把x=1改为x={},结果会不同的(undefined),这是为什么呢?在把函数当做构造器使用的时候,如果手动返回了一个值,要看这个值是否是简单类型,如果是,等同于不写返回,如果不是简单类型,得到的就是手动返回的值。如果,不手写返回值,就会默认从原型创建一个对象用于返回。 问题8:下列输出什么 function foo(a){ console.log(arguments.length); } foo(1,2,3) 答:3,arguments取的实参的个数,而foo.length取的是形参的个数 问题9:下列输出什么 var foo = function bar() {}; console.log(typeof bar); console.log(typeof foo); 答:undefined,function 问题10:下列输出什么 var arr=[]; arr[0]='a'; arr[1]='b'; arr.foo='c'; console.log(arr.length); 答:2,数组的原型是Object,所以可以像其他类型一样附加属性,不影响其固有性质。 问题11:下列输出什么 function foo(a,b){ arguments[0]=2; arguments[1]=22; console.log(a); console.log(b); } foo(1); 答:2,undefined,实参可以直接从arguments数组中修改,没有传进来的参数不能修改 问题12:下列输出什么 function foo(){} delete foo.length; console.log(typeof foo.length); 答:number ,foo.length是无法删除的,它在Function原型上,重点它的 configurable是false Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:00:27 "},"interview/JavaScript中alert1&&2为2的原因.html":{"url":"interview/JavaScript中alert1&&2为2的原因.html","title":"JavaScript中alert(1&&2)为2的原因","keywords":"","body":"问题 一、先来说说||(逻辑或),从字面上来说,只有前后都是false的时候才返回false,否则返回true。 alert(true||false); // true alert(false||true); // true alert(true||true); // true alert(false||false); // false 但是,从深层意义上来说的话,却有另一番天地,试下面代码 alert(0||1); 显然,我们知道,前面0意味着false,而后面1意味着true,那么上面的结果应该是true,而事实返回的结果是1。再看下面代码: alert(2||1); 我们知道,前面2是true,后面1也是true,那返回结果又是什么呢?测试结果是2,继续看: alert('a'||1); 同样,前面'a'是true,后面1也是true;测试结果是'a',下面 alert(''||1); 由上,我们知道前面''是false,后面1是true,而返回结果是1。再看下面 alert('a'||0); 前面'a'是true,而后面0是false,返回结果是'a',继续下面 alert('a'||'b'); 前面'a'是true,后面'b'是false,返回结果是'a',我们继续下面 alert(''||0); 前面''是false,后面0同样是false,返回结果是0 alert(0||''); 前面0是false,后面''是false,返回结果是'' 这就意味 1、只要“||”前面为false,不管“||”后面是true还是false,都返回“||”后面的值。 2、只要“||”前面为true,不管“||”后面是true还是false,都返回“||”前面的值。 二、下面说说&&(逻辑与),从字面上来说,只有前后都是true的时候才返回true,否则返回false。 alert(true&&false); // false alert(true&&true); // true alert(false&&false); // false alert(false&&true); // false 然后,根据上面经验,我们看看“&&”号前后,不单单是布尔类型的情况。 alert(''&&1); 结是返回'',“&&”前面''是false,后面是1是true。 alert(''&&0); 结是返回'',“&&”前面''是false,后面是0也是false。 alert('a'&&1); 结是返回1,“&&”前面'a'是true,后面是1也是true。 alert('a'&&0); 结是返回0,“&&”前面'a'是true,后面是0是false。 alert('a'&&''); 结是返回'',“&&”前面'a'是true,后面是''是false。 alert(0&&'a'); 结是返回0,“&&”前面0是false,后面是'a'是true。 alert(0&&''); 结是返回0,“&&”前面0是false,后面是''也是false。 这意味着 1、只要“&&”前面是false,无论“&&”后面是true还是false,结果都将返“&&”前面的值; 2、只要“&&”前面是true,无论“&&”后面是true还是false,结果都将返“&&”后面的值; 让我们总结一下: 1、只要“||”前面为false,无论“||”后面是true还是false,结果都返回“||”后面的值。 2、只要“||”前面为true,无论“||”后面是true还是false,结果都返回“||”前面的值。 3、只要“&&”前面是false,无论“&&”后面是true还是false,结果都将返“&&”前面的值; 4、只要“&&”前面是true,无论“&&”后面是true还是false,结果都将返“&&”后面的值; 由上两个测试可知,逻辑运算符,“||”和“&&”都是遵行短路原则,只要确定符号前面的真假,既可确定返回值。 需要说明的是“&&”的优先级是高于“||”的,下面测试: alert(1||'a'&&2); 返回结果是1。 根据反证原理,我们假设“||”的优先级不低于“&&”(这里只所以用“不低于”,是为了同时证明等级相同的情况)。 根据上面我们得出的结论(1),(1||'a')将返回前面的值1,(1&&2)根据结论(4)应该返回后面的值2。这显然不对,由此可知“&&”的优先级是高于“||”的。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:01:28 "},"html/谈谈你对webpack的看法.html":{"url":"html/谈谈你对webpack的看法.html","title":"谈谈对webpack的看法","keywords":"","body":"webpack是一个模块打包工具,你可以使用webpack管理你的模块依赖,并编译输出模块们所需的静态文件。它能够很好的管理、打包web开发中所用到的HTML、JavaScript、css以及各种静态文件(图片,字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后生成了优化且合并后的静态资源。 webpack的两大特色: code splitting(可以自动完成) loader 可以处理各种类型的静态文件,并且支持串联操作 webpack是以commonJS的形式来书写脚本的,但对于AMD/CMD的支持也很全面,方便旧项目进行代码迁移。 webpack具有requireJS和browserify的功能,但仍有很多自己的新特性: 1. 对CommonJS、AMD、ES6的语法做了兼容 2. 对js、css、图片等资源文件都支持打包 3. 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持 4. 有独立的配置文件 webpack.config.js 5. 可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间 6. 支持sourceUrls和SourceMap,易于调试 7. 具有强大的Plugin接口,大多是内部插件,使用起来比较灵活 8. webpack使用异步IO并具有多级缓存,这是的webpack很快且在增量编译上更加快。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:44:27 "},"html/对前端模块化的认识.html":{"url":"html/对前端模块化的认识.html","title":"对前端模块化的认识","keywords":"","body":" AMD 是requireJS在推广过程中对模块定义的规范化产出 CMD是SeaJs在推广过程中对模块定义的规划范产出 AMD是提前执行,CMD是延迟执行。 AMD推荐的风格通过返回一个对象作为模块对象,CommonJS的风格通过对module.exports或exports的属性值来达到暴露模块对象的目的。 CMD 模块方式 define(function(require, exports, module) { // 模块代码 }); Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:45:39 "},"html/说说严格模式的限制.html":{"url":"html/说说严格模式的限制.html","title":"说说严格模式的限制","keywords":"","body":" 变量必须声明后再使用 函数的参数不能有同名属性,否则报错 不能使用with语句 不能对只读属性复制,否则报错 不能使用前缀0表示八进制数,否则报错 不能删除不可删除的属性,否则报错 不能删除变量delete prop,会报错,只能删除属性delete global[prop] eval不会在它的外层作用域引入变量 eval和argument不会自动反映函数参数的变化 不能使用argument.callee 禁止this指向全局对象 不能使用fn.caller和fn.argument获取函数调用的堆栈 增加了保留字(比如protected、static和interface) 设立\"严格模式\"的目的,主要有以下几个: 消除JavaScript语法的一些不合理、不严谨之处,减少一些怪异行为; 消除代码运行的一些不安全之处,保证代码运行的安全; 提高编译器效率,增加运行速度 为未来新版本的JavaScript做好铺垫。 注:经过测试IE6,7,8,9均不支持严格模式 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-05 19:01:59 "},"html/说说你对语义化的理解.html":{"url":"html/说说你对语义化的理解.html","title":"说说你对语义化的理解","keywords":"","body":" 去掉或者丢失样式的时候能够让页面呈现出清晰的结构 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重; 方便其他设备解析(如屏幕阅读器,盲人阅读器,移动设备)以意义的方式来渲染网页; 便于团队开发和维护,语义化更具可读性,是下一步网页的重要动向,遵循W3C标准的团队都遵循这个标准 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-07-03 17:56:10 "},"html/谈谈你对重构的理解.html":{"url":"html/谈谈你对重构的理解.html","title":"谈谈你对重构的理解","keywords":"","body":"网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。 对传统的网站来说重构通常是: 表格(table)布局改为DIV+CSS 使网站前端兼容于现代浏览器(针对于不和规范的CSS,如对IE6有效的) 针对移动平台的优化 针对于SEO进行优化 深层次的网站重构应该考虑的方面 减少代码见的耦合 让代码保持弹性 严格按规范编写代码 设计可扩展的API 代替旧有的框架,语言(如VB) 增强用户体验 通常来说对于速度的优化也包含在重构中 压缩JS,CSS,images等前端资源(通常是由服务器来解决) 程序的性能优化(如数读写) 采用CDN来加速资源加载 对于JS DOM的优化 HTTP服务器的文件缓存 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:06:35 "},"html/说说你对前端架构师的理解.html":{"url":"html/说说你对前端架构师的理解.html","title":"说说你对前端架构师的理解","keywords":"","body":" 负责前端团队的管理及与其他团队的协调工作,提升团队成员能力和整理效率; 带领团队完成研发工具及平台前端部分的设计、研发和维护 带领团队进行前端领域前沿技术研究及新技术调研,保证团队的技术领先 负责前端开发规范制定、功能模块化设计、公共组件搭建等工作,并组织培训。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:07:26 "},"html/说说你觉得前端工程的价值体现在哪.html":{"url":"html/说说你觉得前端工程的价值体现在哪.html","title":"说说你觉得前端工程的价值体现在哪","keywords":"","body":" 为简化用户使用提供计数支持(交互部分) 为多个浏览器兼容提供技术支持 为提高用户浏览速度(浏览器性能)提供支持 为跨平台或者其他基于webkit或其他渲染引擎的应用提供支持 为展示数据提供支持(数据接口) Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:39:46 "},"html/谈谈对前端界面工程师这个职位是怎么样的理解的?它的前景会怎么样.html":{"url":"html/谈谈对前端界面工程师这个职位是怎么样的理解的?它的前景会怎么样.html","title":"谈谈对前端界面工程师这个职位是怎么样的理解的?它的前景会怎么样","keywords":"","body":"前端是最贴近用户的程序员,比后端,数据库,产品经理,运营,安全都近。 实现界面交互 提高用户体验 有了node.js前端可以实现服务端的一些事情。 前端是最贴近用户的程序员,前端的能力就是能让产品从90分进化到100分,甚至更好。 参与项目,快速高质量完成实现效果图,精确到1px; 与团队成员,UI设计,产品经理的沟通; 做好的页面结构,页面重构和用户体验; 处理hack,兼容,写出优美的代码格式; 针对服务器的优化,拥抱最新前端技术。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 17:11:23 "},"html/一些开放性题目.html":{"url":"html/一些开放性题目.html","title":"一些开放性题目","keywords":"","body":" 自我介绍:除了基本个人信息以外,面试官更想听的是你与众不同不同的地方和你的优势。 项目介绍 如何看待前端开发? 平时是如何学习前端开发的? 未来三到五年的规划是怎样的? Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 16:43:46 "},"sites/":{"url":"sites/","title":"参考","keywords":"","body":"网址汇总 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 14:41:37 "},"sites/书单.html":{"url":"sites/书单.html","title":"参考网址汇总","keywords":"","body":"https://www.douban.com/search?cat=1001&q=javascript 豆瓣 Javascript 搜索结果。 http://search.jd.com/Search?keyword=javascript&enc=utf-8&wq=javascript 京东 Javascript 搜索结果。 1. Javascript http://product.china-pub.com/199113 JavaScript高级程序设计(第3版) http://product.china-pub.com/199271 JavaScript权威指南(第6版) http://product.china-pub.com/3683795 JavaScript语言精粹(修订版) http://item.jd.com/11019625.html 锋利的jQuery(第2版) http://item.jd.com/11747684.html JavaScript设计模式 百度前端专家力作,阿里巴巴、百度前端高级工程师鼎力推荐的、极具趣味,容易理解,讲解又极为严谨和透彻的写作风格帮你打造出更为专业的Web产品的好书 http://item.jd.com/1557415034.html JavaScript设计模式与开发实践 腾讯前端Alloy Team团队出品,资深前端架构师曾探力作 http://item.jd.com/11667775.html JavaScript面向对象精要 http://item.jd.com/11642532.html JavaScript面向对象编程指南(第2版) http://item.jd.com/11123174.html 编写高质量代码:改善JavaScript程序的188个建议 http://product.china-pub.com/4879620 JavaScript忍者秘籍 http://item.jd.com/11783868.html SVG精髓(第2版) http://product.china-pub.com/3804284 学习JavaScript数据结构与算法 http://item.jd.com/11676671.html 你不知道的JavaScript(上卷) http://item.jd.com/10570721907.html 你不知道的JavaScript(中卷) https://item.jd.com/10607212456.html 精通Javascript 第二版 http://product.china-pub.com/4172218 WebKit技术内幕 2. Nodejs http://item.jd.com/11688177.html Node.js项目实践:构建可扩展的Web应用 http://item.jd.com/11358579.html 了不起的Node.js 将JavaScript进行到底 http://item.jd.com/11355978.html 深入浅出Node.js http://item.jd.com/11384782.html MongoDB权威指南 第2版 [MongoDB: The Definitive Guide, Second Edition] http://item.jd.com/11584538.html NoSQL数据库技术实战 3. Html5 http://item.jd.com/11241807.html HTML5移动Web开发实战 http://item.jd.com/10982275.html HTML5程序设计(第2版) http://item.jd.com/1049266194.html HTML5游戏开发 http://item.jd.com/11231175.html HTML5 Canvas核心技术:图形、动画与游戏开发 http://item.jd.com/11253207.html HTML5+JavaScript动画基础 http://item.jd.com/1056089175.html HTML5+JavaScript动画基础最经典的Canvas图书之一 http://item.jd.com/1027684138.html HTML5实验室 Canvas世界 http://item.jd.com/1526419766.html 现货 移动Web手册(双色) http://item.jd.com/11513456.html HTML5 canvas开发详解(第2版) http://item.jd.com/1267591181.html HTML5Canvas游戏开发实战 4. Angularjs http://item.jd.com/11568614.html 精通AngularJS http://item.jd.com/11845736.html AngularJS深度剖析与最佳实践 http://item.jd.com/11522200.html AngularJS权威教程 http://item.jd.com/11796312.html Web Component实战:探索PolymerJS、Mozilla Brick、Bosoni http://product.china-pub.com/4974294 迈向Angular 2:基于TypeScript的高性能SPA框架 5. PHP: http://item.jd.com/10701892.html PHP与MySQL程序设计(第4版) http://item.jd.com/11389753.html Web开发技术丛书·深入理解PHP:高级技巧、面向对象与核心技术(原书第3版) http://item.jd.com/11113844.html 细说PHP(第2版)(含DVD光盘1张) http://item.jd.com/10059047.html PHP和MySQL Web开发(原书第4版) http://item.jd.com/11769793.html 自己动手设计数据库 6.CSS http://item.jd.com/11911279.html http://product.china-pub.com/4942111 CSS揭秘 http://product.china-pub.com/63768 图解CSS3:核心技术与案例实战 7. 其它 https://zhuanlan.zhihu.com/p/22151280 私以为可以提高程序员技术档次的书和博客 http://product.china-pub.com/4975707 软件设计重构 http://product.china-pub.com/4720077 重构:改善既有代码的设计(第2版) 8. Vue http://item.jd.com/12028224.html Vue.js权威指南 9. Http 协议 http://product.china-pub.com/4976155 HTTPS权威指南 在服务器和Web应用上部署SSL TLS和PKI http://product.china-pub.com/3683063 HTTP权威指南(国内首本HTTP及其相关核心Web技术权威著作) http://product.china-pub.com/3769819 图解HTTP http://product.china-pub.com/3768070 图解TCP/IP(第5版) 10. 算法 http://product.china-pub.com/3684367 算法:第4版(Sedgewick之巨著,与高德纳TAOCP一脉相承) http://product.china-pub.com/3021144 算法导论(原书第3版) http://product.china-pub.com/3804002 数据结构与算法JavaScript描述 http://product.china-pub.com/3770208 啊哈 算法 http://product.china-pub.com/3804284 学习JavaScript数据结构与算法 11. 高性能 http://product.china-pub.com/4778083 高性能JavaScript http://product.china-pub.com/3769687 JavaScript性能优化:度量、监控与可视化 http://product.china-pub.com/3769752 Web性能权威指南 http://product.china-pub.com/62894 Nginx高性能Web服务器详解 12. React http://item.jd.com/11688174.html React:引领未来的用户界面开发框架 http://product.china-pub.com/4879807 React Native:用JavaScript开发移动应用 http://item.jd.com/11948386.html React 精髓 http://item.jd.com/11942017.html React Native开发指南 http://item.jd.com/11944670.html React Native跨平台移动应用开发 http://product.china-pub.com/5007398 深入React技术栈 13. Git, Github http://product.china-pub.com/5012829 GitHub实践 http://product.china-pub.com/4727673 GitHub入门与实践 14. 微信小程序 http://product.china-pub.com/5063953 小程序,巧应用:微信小程序开发实战 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 15:01:16 "},"sites/参考网址汇总.html":{"url":"sites/参考网址汇总.html","title":"书单","keywords":"","body":"个人博客 阮一峰的网络日志 张鑫旭的个人主页 廖雪峰的官方网站 网站 npm webpack react git git中文 sass sass中文文档 less less中文网 ES6中文 stackoverflow 头条 - SegmentFault WEB前端 - 伯乐在线 简书 实验楼 掘金 好文章 css Flex 布局教程:语法篇 Flex 布局教程:实例篇 个人总结(css3新特性) JS 前端知识体系 个人分享--web前端学习资源分享 JavaScript核心概念归纳整理 2017.10.10 理清javascript中的面向对象(一)——原型继承 2017 10.11 一篇文章看懂proto和prototype的关系及区别 2017.10.11 JavaScript创建对象的七种方式 2017.10.16 JavaScript六种继承方式 2017.10.16 深入理解javascript原型和闭包系列 2017.10.17 前端基础进阶系列 2017.10.18 部分 深入理解JavaScript系列 React 技术栈系列教程 web调试优化 web调试优化-chrome开发者工具不完全指南 14个你可能不知道的JavaScript调试技巧 webpack Webpack 3,从入门到放弃 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 14:58:52 "},"sites/知识点.html":{"url":"sites/知识点.html","title":"知识点","keywords":"","body":"内存空间:堆(heap),栈(stack)和队列(queue) 栈:先进后出,后进先出 队列:先进先出 引用数据类型: 引用传递: 浅复制: 深复制: 数据类型、判断方法 执行上下文 变量对象、活动对象 原型、原型链 作用域、作用域链 闭包、垃圾回收机制 this指向 类和模块 继承 函数是编程 同步异步 JS正则表达式 事件模型 Ajax、跨域访问 DOM BOM 相关网址: 前端知识点 JavaScript 参考文档 JavaScript 标准参考教程 JavaScript核心 Map 对象 (JavaScript)思考 原型、原型链、作用域、作用域链 1.函数声明和函数表达式 2.基本类型和引用类型 3.原型和构造函数 4.闭包、匿名函数、内部函数、内部匿名函数 5.原型、原型链、作用域、作用域链 6.执行上下文 7.prototype、construct 8.隐式原型、instanceof、自由变量 html5 es6 1.WebSocket 2.jsonp 3.fetch 4.promise 数值类型 vs. 引用类型—了解如何复制对象、数组和函数以及如何将它们传递到函数中。知道引用类型复制的是什么。了解原始值是通过复制值来复制及传递的。 作用域 —了解全局作用域、函数作用域及块作用域的不同。了解变量的作用范围。知道 JavaScript 引擎如何查找变量。 声明提升—了解变量和函数声明会被提升到可用范围的顶部。了解函数表达式不会被提升。 闭包 — 知道函数内部创建的函数可以访问该函数的作用域。知道这种方式允许我们做什么,比如数据隐藏、记忆以及动态函数变换。 this- 知道 this 绑定的原则。知道它的工作原理,在函数中指代的内容以及为什么有用。 new- 知道它与面向对象编程的关系。知道使用 new 调用的函数发生了什么。了解使用 new 生成的对象是如何从函数的原型继承的。 apply, call, bind- 知道每个函数是如何工作的。知道如何使用它们。知道它们对 this 做什么。 原型 & 继承- 了解 JavaScript 的继承是通过 [[Prototype]] 实现的。了解如何通过函数及对象建立继承并通过 new 实现继承。理解proto 及 prototype 的属性以及作用。 异步的 JS -了解事件循环。理解浏览器如何处理一般的用户输入、网络请求以及事件。知道如何正确认识和实现异步代码。了解 JavaScript 是异步的和单线程的。 高阶函数- 了解 JavaScript 中的函数是第一类对象以及它的意义。知道从另一个函数返回函数是完全合法的。了解闭包及高阶函数允许使用的技术。 Copyright @QiangMin 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-02-20 14:59:55 "}}