本文共 28525 字,大约阅读时间需要 95 分钟。
答案:30px
在文档流中,父元素的高度默认是由子元素撑开的,但是我们把子元素设置为浮动后,子元素完全脱离文档流,此时子元素无法撑起父元素的高度,导致父元素高度坍塌。
给父元素设置高度 缺点:只适用于父元素高度固定的情况下。
给父元素也设置浮动样式(如float: left
) 缺点:给父元素设置浮动样式后,父元素的父元素也会产生高度坍塌问题。
给父元素设置overflow: hidden;
或overflow: auto
缺点:设置hidden会导致超出部分直接被隐藏,且不占据文档流位置,而设置auto的话超出部分会生成一个滚动条,影响视觉效果。
增加块级元素并设置clear: both
属性 缺点:增加无意义的标签
复制代码
使用伪元素after 推荐使用这种方法
复制代码
伪类和伪元素的根本区别在于:它们是否创造了新的元素(抽象)。从我们模仿其意义的角度来看,如果需要添加新元素加以标识的,就是伪元素,反之,如果只需要在既有元素上添加类别的,就是伪类。
CSS 伪类用于向某些选择器添加特殊的效果。
CSS 伪元素用于将特殊的效果添加到某些选择器。
这是为什么我们经常把CSS放在<head></head>
标签之间,而把JS放在body的最底部的原因。
设置左右设置float: left
和float: right
,中间使用margin-left
和margin-right
缺点:三个元素没有按照常规顺序排列,中间center的元素一定要放在最后
复制代码
两侧使用绝对定位,中间使用margin-left
,和margin-right
缺点:top的值需要根据页面上的其它内容确定
复制代码
父元素使用两端对齐方式display: flex
,中间宽度设置为width: 100%
复制代码
margin负值法:左右两栏均左浮动,左右两栏采用负的margin值。
复制代码
ps: px绝对度量单位,就是像素,是屏幕能显示出的最小的一个点
rem的特点
em的特点:
内联样式1000 -- id100 -- 类、伪类、属性选择器10 -- 类型选择器、伪元素选择器1 通过相加计算大的优先级高,值相等的话后声明的优先级高。
绝对定位与负边距实现 缺点:需要知道div的高度和宽度
复制代码
绝对定位与margin
复制代码
使用CSS3的transform属性
复制代码
使用flex布局
复制代码
使用table-cell 缺点:只支持行内元素inline或inline-block,可将块级元素设为inline-block
复制代码
display:flex和margin:auto
复制代码
border-radius 、box-shadow、border-image、text-shadow、word-wrap、transform、@media、flex
常用:
或者是: 或者是借助HTML注释: 复制代码
.space a { display: inline-block; margin-right: -3px;}复制代码
注意,为了向下兼容IE6/IE7等浏览器,最后一个列表的标签的结束(闭合)标签不能丢。复制代码
font-size: 0
.space { font-size: 0; -webkit-text-size-adjust:none; //兼容部分浏览器}复制代码
单行文本省略
.ellipsis-line { width: 400px; overflow: hidden; text-overflow: ellipsis; //文本溢出显示省略号 white-space: nowrap; //文本不会换行 }复制代码
多行文本省略
.multi-line { border: 1px solid #f70505; width: 400px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;}复制代码
利用定位和伪类元素
p{ position: relative; width:400px; line-height: 20px; max-height: 60px; overflow: hidden;}p::after{ content: "..."; position: absolute; bottom: 0; right: 0; padding-left: 40px; background: -webkit-linear-gradient(left, transparent, #fff 55%); background: -o-linear-gradient(right, transparent, #fff 55%); background: -moz-linear-gradient(right, transparent, #fff 55%); background: linear-gradient(to right, transparent, #fff 55%);}复制代码
{ display: none; /* 不占据空间,无法点击 */ } { visibility: hidden; /* 占据空间,无法点击 */ } { position: absolute; top: -999em; /* 不占据空间,无法点击 */ } { position: relative; top: -999em; /* 占据空间,无法点击 */ } { position: absolute; visibility: hidden; /* 不占据空间,无法点击 */ } { height: 0; overflow: hidden; /* 不占据空间,无法点击 */ } { opacity: 0; filter:Alpha(opacity=0); /* 占据空间,可以点击 */ } { position: absolute; opacity: 0; filter:Alpha(opacity=0); /* 不占据空间,可以点击 */ } 复制代码
渐进增强(progressive enhancement):针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。(从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面添加无害于基础浏览器的额外样式和功能。当浏览器支持时,它们会自动地呈现出来并发挥作用。)
.transition{ -webkit-transition: all .5s; -moz-transition: all .5s; -o-transition: all .5s; transition: all .5s; }复制代码
优雅降级(graceful degradation):一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。(Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效。)
.transition{ transition: all .5s; -o-transition: all .5s; -moz-transition: all .5s; -webkit-transition: all .5s;}复制代码
复制代码
a) 尽可能多的利用硬件能力,使用3D开启GPU加速translate3d
b) 使用transform的translate替代margin或position中的top、right、bottom和left,同时使用transform中的scaleX或者scaleY来替代width和height
.box { background-color: blue; width: 100%; height: 0; padding-bottom: 50%;}复制代码
content-box(W3C 标准盒模型)
属性width,height只包含内容content,不包含border和padding。
布局所占宽度Width: Width = width + padding-left + padding-right + border-left + border-right
布局所占高度Height: Height = height + padding-top + padding-bottom + border-top + border-bottom
border-box(IE 盒模型)
属性width,height包含border和padding,指的是content+padding+border
布局所占宽度Width: Width = width(包含padding-left + padding-right + border-left + border-right)
布局所占高度Height: Height = height(包含padding-top + padding-bottom + border-top + border-bottom)
link
标签引入的 CSS 被同时加载;@import
引入的 CSS 将在页面加载完毕后被加载。@import
是 CSS2.1 才有的语法,故只可在 IE5+ 才能识别;link
标签作为 HTML 元素,不存在兼容性问题。link
标签来改变样式;由于 DOM 方法是基于文档的,无法使用@import
的方式插入样式。@import
是 CSS 提供的语法规则,只有导入样式表的作用;link
是HTML提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性等。CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。通俗的说,CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件
由于不同的浏览器对CSS的支持及解析结果不一样,还由于CSS中的优先级的关系。我们就可以根据这个来针对不同的浏览器来写不同的CSS。 a) 条件注释法 只在IE下生效
复制代码
b) 类内属性前缀法
line-height: normal; // line-height=font-size*1.2 (默认为1.2)line-height:inherit; // 继承父元素line-height:24px; // 通过像素px或者em等单位赋值line-height:150%; // line-height=font-size*1.5line-height:1.5; // line-height=font-size*1.5line-height:1.5em; // line-height=font-size*1.5复制代码
width=device-width
指定了布局视口=理想视口,并且禁止缩放。所以添上width=device-width
的viewport meta
后页面变大了(一开始页面内容小得看不清),实际上是布局视口变小了。
<nav>、<article>、<header>、<section>、<footer>、<video>、<canvas>、draggable拖放、Input 类型color、date、datetime、datetime-local、email、month、number、range、search、tel、time、url、week
DOCTYPE是docunment type(文档定义)的简写,用来说明web设计中所用的html或xhtml的类型,指出浏览器或者其他阅读程序按照什么样的规则
XHTML是XML重写了HTML的规范,比HTML更加严格,表现如下:
1、XHTML中所有的标记都必须有一个相应的结束标签;
2、XHTML所有标签的元素和属性的名字都必须使用小写;
3、所有的XML标记都必须合理嵌套;
4、所有的**属性都必须用引号“”**括起来;
5、把所有<和&特殊符号用编码表示;
6、给所有属性附一个值;
7、不要在注释内容中使用“--”;
8、图片必须使用说明文字。
语义化HTML:用最恰当的HTML元素标记的内容。
语义化是指用合理HTML标记以及其特有的属性去格式化文档内容。通俗地讲,语义化就是对数据和信息进行处理,使得机器可以理解.
:简短、描述性、唯一(提升搜索引擎排名) :h1~h6分级标题 :页眉通常包括网站标志、主导航、全站链接以及搜索框。 :标记导航,仅对文档中重要的链接群使用。 :页面主要内容,一个页面只能使用一次。如果是web应用,则包围其主要功能。 :包含像报纸一样的内容= =||是这么理解的,表示文档、页面、应用或一个独立的容器 :具有相似主题的一组内容,比如网站的主页可以分成介绍、新闻条目、联系信息等条块。 :页脚,只有当父级是body时,才是整个页面的页脚。 :指定附注栏,包括引述、侧栏、指向文章的一组链接、广告、友情链接、相关产品列表等。 :指定细则,输入免责声明、注解、署名、版权。 :表示内容重要性。 :标记内容着重点(大量用于提升段落文本语义)。 :标记时间。datetime属性遵循特定格式,如果忽略此属性,文本内容必须是合法的日期或者时间格式。 :作者、相关人士或组织的联系信息(电子邮件地址、指向联系信息页的链接)。 :标记代码。包含示例代码或者文件名 (< < > >)复制代码
网页渲染机制
解析 HTML 标签, 构建 DOM 树解析 CSS 标签, 构建 CSSOM 树把 DOM 和 CSSOM 组合成 渲染树 (render tree)在渲染树的基础上进行布局, 计算每个节点的几何结构把每个节点绘制到屏幕上 (painting)复制代码
加载方式
css 异步加载(不阻塞)img 异步加载(不阻塞)js 同步加载(阻塞)复制代码
放置顺序
css 放置于标签中原因:要是页面在无CSS渲染下先加载HTML的话将会面目全非,样式先行的话在加载HTML内容时可以同时渲染样式js 放置于标签之前、body标签中html内容的后面原因:为了提高页面渲染的速度效率。浏览器在加载
回流必将引起重绘,重绘不一定会引起回流。回流比重绘的代价要更高。
回流: 当Render Tree
中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
会导致回流的操作:
DOM
元素CSS
伪类(例如::hover
)一些常用且会导致回流的属性和方法:
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
重绘: 当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color
、background-color
、visibility
等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
数字(number)、字符串(string)、布尔值(boolean)、undefined、null、对象(Object)、Symbol (ES6)
event.stopPropagation()
event.preventDefault()
event.stopImmediatePropagation
event.target
对象来获取JavaScript中每个对象都有一个私有属性(称之为 __proto__
),它指向它的原型对象(prototype
)。该 prototype
对象又具有一个自己的 __proto__
,层层向上直到一个对象的原型为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
闭包就是能够读取其他函数内部变量的函数。在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成**“定义在一个函数内部的函数“ **。在本质上,闭包是将函数内部和函数外部连接起来的桥梁
function fn () { var n = 1 return function bar () { console.log(n++) }}复制代码
let 、const、 => 、 import、 export、 export defualt
includes、**表示乘方
`padStart、padEnd、Object.values(obj)返回对应的value数组、Object.entries(obj)返回的是有每一对键值对数组组成的数组、Object.getOwnPropertyDescriptors(obj)获取属性信息
toString()、valueOf()、toLocaleString()、join()、push()、pop()、shift()、unshift()、reverse()、sort()、concat()、slice()、indexOf()、lastIndexOf()、reduce()、map()、forEach()、filter()
concat()、charAt()、slice()、substr()、substring()、split()、trim()、toLowerCase()、toUpperCase()、match()、search()
1. JSON.parse方法const newObj = JSON.parse(JSON.stringify(oldObj));2. 构造一个深克隆函数function deepClone (obj) { if (typeof obj !== "object" && typeof obj !== "function") { return obj; } if (typeof obj === "function") { return eval(obj.toString()); // 有问题 } if (obj.constructor === Date) { return new Date(obj.getTime()); } if (obj.constructor === RegExp) { return new RegExp(obj); } var o = Array.isArray(obj) ? [] : {}; for (i in obj) { if (obj.hasOwnProperty(i)) { o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i]; } } return o;}复制代码
==
用于比较判断两者相等 ==
在比较的时候可以转自动换数据类型
===
用严格比较判断两者严格相等===
严格比较,不会进行自动转换
0.1的二进制格式是:0.0001100011....。这是一个二进制无限循环小数,但计算机内存有限,我们不能用储存所有的小数位数。那么在精度与内存间如何取舍呢?
答案是:在某个精度点直接舍弃。当然,代价就是,0.1在计算机内部根本就不是精确的0.1,而是一个有舍入误差的0.1。当代码被编译或解释后,0.1已经被四舍五入成一个与之很接近的计算机内部数字,以至于计算还没开始,一个很小的舍入错误就已经产生了。这也就是 0.1 + 0.2 不等于0.3 的原因。
MVC
MVP
MVVM
Controller: 负责监听View的用户事件,得到数据后Controller做一些处理,然后渲染View。Presenter: 比起Controller,Presenter会调用View层提供的接口去渲染Model。这样做有几点好处:面向接口编程、更好的解耦、方便做单元测试ViewModel: 比起MVP中View需要自己提供API,MVVM在VM中构建一组状态数据(state data),作为View状态的抽象。然后通过双向数据绑定(data binding)使VM中的状态数据(state data)与View中的显示状态(screen state)保持一致。这样,VM中的展示逻辑只需要修改对应的状态数据,就可以控制View的状态,从而避免在View上开发大量的接口。复制代码
a) 减少HTTP请求
b) 使用精灵图和CSS Sprites(CSS精灵)
c) 使用CDN
d) 将样式表放在头部,将脚本放在底部
e) 使用
f) 资源合并压缩
g) 减少DNS查找
h) 使用懒加载、预加载
setTimeout(表达式,延时时间)在执行时,是在载入后延迟指定时间后,去执行一次表达式,记住,次数是一次 而setInterval(表达式,交互时间),它从载入后,每隔指定的时间就执行一次表达式 ,直到 clearInterval() 被调用或窗口被关闭
JavaScript 是单线程执行的,也就是无法同时执行多段代码, 如果代码中设定了一个 setTimeout
,那么浏览器便会在合适的时间,将代码插入任务队列,如果这个时间设为 0
,就代表立即插入队列,但不是立即执行。
声明函数具有函数提升效果,可以在声明函数的代码前执行函数
console.log(add2(1,1)); //输出2function add2(a,b){ //函数声明 return a+b;}console.log(add1(1,1)); //报错:add1 is not a functionvar add1 = function(a,b){ return a+b;}复制代码
var会变量提升(预解析),let不会变量提升(变量提升:函数及变量的声明都将被提升到函数的最顶部。 )
if(true){ // TDZ开始 tmp = 'abc' //报错 let tmp; //TDZ结束}复制代码
函数作用域是产生闭包的原因
在Javascript函数体内,标识符arguments具有特殊含义。它是调用对象的一个特殊属性,用来引用Arguments对象。 Arugments对象就像数组 ,其中arguments[0]表示第一个参数。 arguments.length长度
XSS定义的主语是“脚本”,是一种跨站执行的脚本,也就是javascript脚本,指的是在网站上注入我们的javascript脚本,执行非法操作。
CSRF定义的主语是”请求“,是一种跨站的伪造的请求,指的是跨站伪造用户的请求,模拟用户的操作。
XSS: 通过客户端脚本语言(最常见如:JavaScript) 在一个论坛发帖中发布一段恶意的JavaScript代码就是脚本注入,如果这个代码内容有请求外部服务器,那么就叫做XSS!
CSRF:又称XSRF,冒充用户发起请求(在用户不知情的情况下),完成一些违背用户意愿的请求(如恶意发帖,删帖,改密码,发邮件等)。
防御XSS攻击可以通过以下两方面操作:
CSRF攻击的防御可以通过以下两方面操作:
"number","string","boolean","object","function","undefined"复制代码
new共经历了四个过程。
var fn = function () { };var fnObj = new fn();复制代码
创建一个空对象
var obj = new object()复制代码
设置原型链
obj._proto = fn.prototype;复制代码
让fn的this指向obj,并执行fn函数体
var result = fn.call(obj);复制代码
判断fn的返回值类型,如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。
if (typeof(result) == "object"){ fnObj = result; } else { fnObj = obj;}return fnObj复制代码
var arr = new Array("123", "ash")- arr instanceof Array- Array.isArray(arr)- arr.constructor //查看输出是否为function Array(){ [native code] }- Object.prototype.toString.call(arr) === '[object Array]'复制代码
__proto__
和prototype
的区别__proto__
(隐式原型)与prototype
(显式原型) ,__proto__
指向prototype
默认绑定:
a) 全局环境中,this默认绑定到window console.log(this === window);//true
b) 函数独立调用时,this默认绑定到window
function foo(){ console.log(this === window);}foo(); //true复制代码
c) 被嵌套的函数独立调用时,this默认绑定到window
//虽然test()函数被嵌套在obj.foo()函数中,但test()函数是独立调用,而不是方法调用。所以this默认绑定到windowvar a = 0;var obj = { a: 2, foo: function () { function test () { console.log(this.a); } test(); }}obj.foo(); // 0复制代码
隐式绑定
a) 一般地,被直接对象所包含的函数调用时,也称为方法调用,this隐式绑定到该直接对象
function foo () { console.log(this.a);};var obj1 = { a: 1, foo: foo, obj2: { a: 2, foo: foo }}//foo()函数的直接对象是obj1,this隐式绑定到obj1obj1.foo(); // 1//foo()函数的直接对象是obj2,this隐式绑定到obj2obj1.obj2.foo();// 2复制代码
隐式丢失
a) 隐式丢失是指被隐式绑定的函数丢失绑定对象,从而默认绑定到window。这种情况容易出错却又常见
var a = 0;function foo(){ console.log(this.a);};var obj = { a : 2, foo:foo}//把obj.foo赋予别名bar,造成了隐式丢失,因为只是把foo()函数赋给了bar,而bar与obj对象则毫无关系var bar = obj.foo;bar(); // 0复制代码
显式绑定
a) 通过call()、apply()、bind()方法把对象绑定到this上,叫做显式绑定。对于被调用的函数来说,叫做间接调用
var a = 0;function foo(){ console.log(this.a);}var obj = { a:2};foo(); // 0foo.call(obj); // 2复制代码
new绑定
如果函数或者方法调用之前带有关键字new,它就构成构造函数调用。对于this绑定来说,称为new绑定
function fn(){ this.a = 2;}var test = new fn();console.log(test); // {a:2}复制代码
a) 原型链继承
核心: 将父类的实例作为子类的原型
function Cat(){ }Cat.prototype = new Animal(); //父类Animal实例Cat.prototype.name = 'cat';Cat.prototype.constructor = Cat;// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.eat('fish'));console.log(cat.sleep());console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true复制代码
b) 构造继承
核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
function Cat(name){ Animal.call(this); this.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true复制代码
c) 实例继承
核心:为父类实例添加新特性,作为子类实例返回
function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance;}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false复制代码
d) 拷贝继承(支持多继承)
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true复制代码
e) 组合继承
核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
function Cat(name){ Animal.call(this); this.name = name || 'Tom';}Cat.prototype = new Animal();// 组合继承也是需要修复构造函数指向的。Cat.prototype.constructor = Cat;// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // true复制代码
f)寄生组合继承
核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
function Cat(name){ Animal.call(this); this.name = name || 'Tom';}(function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Animal.prototype; //将实例作为子类的原型 Cat.prototype = new Super();})();Cat.prototype.constructor = Cat; // 需要修复下构造函数// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); //true复制代码
JS获取的是DOM元素。 jQuery返回的是jQuery对象, jQuery对象比js对象多了一些包装方法,比如.htm() .attr() .css() 等等
通过Object创建对象
var person = new Object();person.name = "hebiwen";person.getName = function() { console.log(this.name);};复制代码
通过字面量创建
var person = { name: "hebiwen", getName: function() { console.log(this.name); }}复制代码
工场模式(无法识别对象类型,即无法通过instanceof
和constructor
来识别对象类型)
function createPerson(name) { var o = new Object(); o.name = name; o.getNmae = function() { console.log(this.name); }; return o;}var person = createPerson("hebiwen");复制代码
构造函数
function Person(name) { this.name = name; this.getName = function() { console.log(this.name); }}var person = new Person("person");复制代码
构造函数的问题:
每个方法都要在每个实例上重新创建一次,尤其是函数,这样每个Person
的实例都包含了一个不同的sayName
的函数实例。
注意1 构造函数没有return
语句。要创建Person
的新实例,必须采用new
操作符,new
操作符大体上完成了一下4件事情:
Person
创建的新对象,记为person);this.name=name;this.say.....
);注意2 构造函数也是函数,如果不通过new
操作符调用,则作用环境为全局(浏览器中为windows
,node环境中为global
)
原型模式
function Person() {}Person.prototype.name = "hebiwen";Person.prototype.getName = function() { console.log(this.name);}var person = new Person();复制代码
浏览器支持:IE9+,这样所有的Person
实例共享name
属性及sayName
函数
注意1
hasOwnProperty()
来确定,如果是在原型中,则返回false
。in
操作符,例如console.log("name" in person)//true
来判断,不论是在原型还是实例中,都返回true
,通过for-in
循环时,实例及原型中均会被枚举。注意2 在定义原型时,如果用字面量代替为prototype
属性定义,则原型的constructor
属性不会指向Person
。因为通过字面量定义,完全重写了默认的prototype
对象。但是此时instanceof
还是能够返回正确的结果。
function Person(){};Person.prototype={ name : "hebiwen", sayName : function(){ console.log(this.name); }};var person = new Person();console.log(person instanceof Person);//trueconsole.log(person.constructor == Person);//falseconsole.log(person.constructor == Object);//true复制代码
注意3 在重定义原型前,不能创建对象实例,否则会造成实例的原型指向错误
构造函数与原型组合
function Person(name) { this.name = name; this.friends = ["Bob","Harry"];//引用类型为实例属性}Person.prototype.getName = function() { console.log(this.name); }复制代码
动态原型
function Person(name) { this.name = name; this.friends = ["Bob","Harry"];//引用类型为实例属性 if(typeof this.sayName != "function"){ Person.prototype.sayName = function(){ console.log(this.name); }; }}复制代码
寄生构造模式
function Person(name) { var o = new Object(); o.name = name; o.getName = function() { console.log(this.name); } return o;}var person = new Person("hebiwen");复制代码
稳妥构造函数模式
function Person(name) { var o = new Object(); var _name = name; o.getName = function() { console.log(_name); } return o;}var person = Person("hebiwen");复制代码
JSONP
利用script标签支持跨域的属性,用script标签拿到包裹了数据的方法(相当于是返回了一段js代码),在请求中包含callback,服务端注入参数后返回这个回调函数,然后script标签拿到返回的js代码跨域直接运行回调,需要前后端的配合。复制代码
CORS
请求头中的Content-Type请求头的值是下列之一:- application/x-www-form-urlencoded- multipart/form-data- text/plain复制代码
服务端代理
因为服务器间的数据交互没有跨域限制,所以我们可以通过一个中间代理服务器来请求目标服务器的数据,也就是开发服务器发送请求到代理服务器,代理服务器再请求目标服务器,将数据返回给开发服务器复制代码
不支持,因为script不支持post请求
img link iframe 等元素都可以发送跨域请求
Mounting:组件挂载,已插入真实DOM
组件即将被渲染到页面之前触发,此时可以进行开启定时器、向服务器发送请求等操作
组件渲染
组件已经被渲染到页面中后触发:此时页面中有了真正的DOM的元素,可以进行DOM相关的操作
Updating:组件更新,正在被重新渲染
在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用
在组件完成更新后立即调用。在初始化时不会被调用。
Unmounting:组件移除,已移出真实DOM
组件被销毁时触发。这里我们可以进行一些清理操作,例如清理定时器,取消Redux的订阅事件等等。
数据劫持: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调。 Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
发布者-订阅者模式: 一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set('property', value)
,
复制代码
问题1: 为什么要三次握手?
答:三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收机能正常。
问题2:为什么要发送特定的数据包,随便发不行吗?
答:三次握手的另外一个目的就是确认双方都支持TCP,告知对方用TCP传输。
问题3:上图中的SYN和ACK是什么?
答:SYN是标志位,SYN=1表示请求连接;
问题1: 为什么要四次挥手?
答:根本原因是,一方发送FIN只表示自己发完了所有要发的数据,但还允许对方继续把没发完的数据发过来。
问题2:为什么双方要发送这样的数据包?
答:和握手的情况类似,只是为了让对方知晓自己理解了对方的意图。
浏览器缓存的优点有:
1.减少了冗余的数据传输,节省了网费
2.减少了服务器的负担,大大提升了网站的性能
3.加快了客户端加载网页的速度
1.强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中可以看到该请求返回200的状态码;
2.协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;
**已存在缓存数据时,仅基于强制缓存,请求数据的流程如下 **
已存在缓存数据时,仅基于对比缓存,请求数据的流程如下
HTTP2.0的新特性
序号 | 方法 | 描述 |
---|---|---|
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
cookie和session的区别(cookie和session都是用来跟踪浏览器用户身份的会话方式。 )
a) 保持状态 :cookie保存在浏览器端,session保存在服务器端
b) 存储内容:cookie只能保存字符串类型,以文本的方式;session通过类似与Hashtable的数据结构来保存,能支持任何类型的对象(session中可含有多个对象)
c) 存储的大小:cookie:单个cookie保存的数据不能超过4kb;session大小没有限制。
d) 安全性:cookie:针对cookie所存在的攻击:Cookie欺骗,Cookie截获;session的安全性大于cookie。
WebStorage
HTML5的WebStorage提供了两种API:localStorage(本地存储)和sessionStorage(会话存储)
a) 生命周期:localStorage:localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。
b) 存储大小:localStorage和sessionStorage的存储数据大小一般都是:5MB
c) 存储位置:localStorage和sessionStorage都保存在客户端,不与服务器进行交互通信。
d) 存储内容类型:localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理
e) 应用场景:localStoragese:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据。sessionStorage:敏感账号一次性登录;
最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息 ,HTTP 协议做不到服务器主动向客户端推送信息。
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws
(如果加密,则为wss
),服务器网址就是 URL。
先暂存一下工作空间改动:git stash
新建一个分支,并且换到这个新分支
git branch fix_bug
//新建分支
git checkout fix_bug
//切换分支
这时候就可以安心的在这个fix_bug分支改bug了,改完之后
git add .
git commit -m "fix a bug"
切换到master主分支
git checkout master
从fix_bug合并到master分支
git merge fix_bug
提交代码
git push
然后从暂存区恢复代码
git stash pop
原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。