1 | var a = 1; // a === 1 |
这就是深拷贝,意思是拷贝之后,改变其中一个值的同时并不改变另一个值。
除了object以外的数据类型,赋值都是深拷贝
1 | var a = { |
这就是浅拷贝,赋值时只能把地址赋过去,并没把heap内存里的东西赋给b。
未完待续……
1 | var a = 1; // a === 1 |
这就是深拷贝,意思是拷贝之后,改变其中一个值的同时并不改变另一个值。
除了object以外的数据类型,赋值都是深拷贝
1 | var a = { |
这就是浅拷贝,赋值时只能把地址赋过去,并没把heap内存里的东西赋给b。
未完待续……
1 | Number('1') // 1 |
1 | '1' - 0 === 1 //最常见 |
'[object Object]'
1 | (1).toString(); // '1' |
1 | 1 + '' // '1' |
总共只有6个falsy值,0、NaN、’’、null、undefined,除了这6个,其它值都是true。所有对象都是true,包括var n = new Boolean(false),n也是true1
2
3
4
5
6
7
8
9
10
11
12
13
14Boolean(1) // true
Boolean(2) // true
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // 空字符串false
Boolean(' ') // 空格字符串true
Boolean(null) // false
Boolean(undefined) // false
Boolean({}) // 空对象true
Boolean([]) // 空数组true
取反两次,总共只有6个falsy值,0、NaN、’’、null、undefined,除了这6个,其它值都是true。所有对象都是true,包括var n = new Boolean(false),n也是true1
2
3
4
5
6
7
8
9
10
11
12!!1 // true
!!0 // false
!!NaN // false
!!'' // false
!!' ' // true
!!{} // true
!!null // false
!!undefined // false
1 | 1. div1 = document.createElement('div') //要加引号 |
当用js创建一个span标签并想同时给它添加className和textContent时,可以用一个函数来一起实现,如:1
2
3
4
5
6function createSpan(textContent) {
var span = tag('span',{className:'text',textContent:textContent});
return span;
}
var span = createSpan('sb'); // 这样可以直接创建className为text、textContent为sb的span标签
1 | var pageWidth = document.documentElement.clientWidth; |
var a = 011 // a === 9,0开头代表8进制!
var b = 0b11 // b === 3,0b开头代表2进制
var c = 0x11 // c === 17,0x代表16进制
JavaScript 认为’𝌆’的长度为2,而不是1。
对于码点在U+10000到U+10FFFF之间的字符,JavaScript 总是认为它们是两个字符(length属性为2)。所以处理的时候,必须把这一点考虑在内,也就是说,JavaScript 返回的字符串长度可能是不正确的。
用来生成一个全局唯一的值
null和undefined都表示没有值,一般来说
1.若一个变量没有赋值,例:var a;,则a的值就是undefined
2.若创建一个对象,现在还不想赋值,则可以var obj = null;
3.若一个number、string不想赋值,则可以参照第一条
前面六种是简单类型或基本类型,对象是合成类型
对象可以分成:
> 狭义的对象
> 数组
> 函数
当你在遍历对象的时候
1
2
3
4
5 > var person = {name:'pyz',age:18}
>for(var key in person){
> console.log(person[key]); >//console.log(person.key);
>}
>
用person.key和person[key]是不同的,person.key代表person里有一个键名为key的属性,key被当作字符串,会出现undefined。而且数值键名也不能用点,会被当作小数点。
obj.123 //报错
只能用person[key]来表示,因为使用方括号运算符时key会被当作变量来处理。
bug1: typeof null //object
bug2: typeof function //function,function也是object的一种,但function有自己的原型
{foo:123},javascript理解为语句(即代码块)
({foo:123}),JavaScript理解为对象
在eval语句(作用是对字符串求值)中
eval(‘{foo: 123}’) // 123
eval(‘({foo: 123})’) // {foo: 123}
一般遍历对象自身属性时结合使用hasOwnProperty方法
1
2
3
4
5
6
7
8 >var person = { name: '老彭' };
>for (var key in person) {
> if (person.hasOwnProperty(key)) {
> console.log(key);
> }
>}
>// name
>
查看一个对象本身的所有属性,也可以使用Object.keys方法
1
2
3
4
5
6
7
8 >var obj = {
> key1: 1,
> key2: 2
>};
>
>Object.keys(obj);
>// ['key1', 'key2']
>
JavaScript里不要直接比较小数,因为浮点数不是精确的值
1 | 0.1 + 0.2 === 0.3 |
JavaScript 对15位的十进制整数都可以精确处理,大于15位就不行了
以下两种情况,JavaScript 会自动将数值转为科学计数法表示
(1)小数点前的数字多于21位。
(2)小数点后的零多于5个。
JavaScript 对整数提供四种进制的表示方法:十进制、十六进制、八进制、二进制。默认情况下,JavaScript 内部会自动将八进制、十六进制、二进制转为十进制。
十进制:没有前导0的数值。
八进制:有前缀0o或0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值。
十六进制:有前缀0x或0X的数值。
二进制:有前缀0b或0B的数值。
若字符串要换行的话,可以这样1
2
3
4'a\
b\
c'
//‘abc’
重点是\后只能加回车,不能有任何空格
计数排序中的桶就是hash,hash的意思就是一个key对应一个value,如:
数组也是hash:a[0]=1,a[1]=2,……
对象也是hash
先进先出,和排队一样1
2
3
4
5
6
7
8let q = [];
q.push('第一');
q.push('第二');
q.push('第三');
q.shift(); //第一
q.shift(); //第二
q.shift(); //第三
基数排序里的桶就是队列,因为是先进先出
先进后出,和队列相反1
2
3
4
5
6
7
8let stack = [];
stack.push('第一');
stack.push('第二');
stack.push('第三');
stack.pop(); //第三
stack.pop(); //第二
stack.pop(); //第一
1 | let a = { |
a.next.value=2;
a.next.value=3;
比数组好在删除中间的数据很方便,比如删除第二项,直接:1
a.next = a.next.next
时间复杂度:O(n^2^)
有个数组a=[5,4,1,3,2,6],从小到大排序,总共进行a.length-1轮,首先将a[0]和a[1]比较,谁大就把谁放在后面,交换完后再将a[1]和a[2]比较,谁大就把谁放在后面,交换完后再将a[2]和a[3]比较…..一直到a[4]和a[5]比较,进行完第一轮后,最大的那个就已经放在最后一位了,接下来再重新从a[0]开始……直到进行到a[3]和a[4]比较(a[5]上一轮已经确定了最大的,不用再动了),直到a[2],a[3],a[4],a[5]都确定了,最后再比较一次a[0],a[1],排完a[0],a[1]的顺序,a数组的顺序就排好了~
点BUB是冒泡排序的动画演示
时间复杂度:O(n^2^)
选出最小的和第一位交换位置,第一位就被确定了,接下来找倒数第二小的和第二位换位置,接着再找倒数第三小的和第三位换位置……一直找到最后一位
点SEL是冒泡排序的动画演示
时间复杂度:O(n^2^)
从数组的第二个开始,和第一个比较并排顺序,接着拿第三个和第二个比,若比第二个大则直接不动,若比第二个小则和第一个比,若比二小比一大则插在它们中间,若比第一个小则放在第一个,接着再拿第四个分别和三、二、一
比…….直到最后。
这就像打扑克牌时你摸牌的方法
点INS是冒泡排序的动画演示
优点:
效率高,时间复杂度:O(n*log2n)
缺点:
有时候比计数排序慢
简介:
随机选一个数,例:36,#将这个数和第一个数交换位置,于是36到了第一位,接着将36和其他所有数依次比较大小,把所有比36小的放左边,比36大的放右边,比完其他所有数后把36同比它小的数里的最右边的那个交换位置,这样36就定位了。
接着以同样的方式随机选择一个36左边的数,然后回到上面#的位置继续进行,在36的左边再次快排,这样左边排序时完全不用管右边,大大提高了效率,把左边排完再排右边。
演示:点R-Q是随机快排
优点:
效率高,时间复杂度:O(n+max)
缺点:
1.需要一个hash来作为工具
2.无法对小数和负数进行排序,只能排正整数
3.可能需要很多桶,不像桶排序可控制桶数量
用途:
数字相差不大的时候可以用计数排序,如年龄排序
简介:
和基数排序差不多,比快排更快,需要一个额外数组(Hash)辅助,例:a=[3,2,4,5,1,3,34]
a[0]=3于是将Hash数组中的hash[3]=1
a[1]=2于是将hash[2]=1
a[2]=4于是将hash[4]=1
a[3]=5于是将hash[5]=1
a[4]=1于是将hash[1]=1
a[5]=3于是将hash[3]=hash[3]+1=2
a[6]=34于是将hash[34]=1
这样hash=[ ,1,1,2,1,1, , , , ,……, , , , ,1]
最后将hash中的数据按顺序取出来存放在另外一个数组里则排序完成。
优点:
和计数排序不同的是一个桶里可放多个数字,效率高,计数排序的改良版,时间复杂度:O(N+C)
缺点:
需要hash工具,和计数排序不同的是每个桶里都是无序的,还要再排一次序
用途:
高考总分排序,每100分放在一个桶里,数字很分散的时候不好用,可用基数排序(比如从几十到几千)
简介:
a=[0,2,1,56,32,67,32],存入hash里1
2
3
4
5
6
7
8
9hash = {
'0':[0,2,1],
'1':[],
'2':[],
'3':[32,32],
'4':[],
'5':[56],
'6':[67],
}
还要把每个桶里的数字排序一下,再依次拿出来
优点:
效率高
桶数量是确定的,时间复杂度:O(nlog(r)m)
缺点:
需要一个hash当工具,要多次排序
简介:
和桶排序类似,数字很分散的时候,可以用基数排序,首先用个位排,每次出桶的时候要按照进桶的顺序出!再到百位,再到千位,具体看下面演示
演示:点RAD是基数排序
时间复杂度:nlogn
用数组表示一个堆,每次都做最大堆排序,每做完一次就把最大的数和最后一位交换位置,并定下来,于是每做一次最大堆排序就能确定一个最大的数并把它放到最后一位,一直重复到排完所有的数,这样一个从小到大的数组就排出来了
演示:堆排序
css2.1是目前世界上应用最广泛的版本,2011年开始css被分为多个模块单独升级,统称为CSS3,现在已经有很多模块升级到了CSS4。css文档
给你要写的css标签加上borderborder:1px solid red;
让你知道它在哪、它的大小、形状
给所有li加上cssfloat:left;
,然后给ul加上class:clearfix
,下面是clearfix的css1
2
3
4
5.clearfix::after{
content: "";
display: block;
clear: both;
}
方法二:给ul加上display:flex
若想让li在同一行里平均分布,见下面6.5
div(块级元素):高度是由内部文档流元素高度的总和决定的。文档流:文档内元素的流动方向,内联元素是从左往右,块级元素是从上往下
span(内联元素):高度是由其中文字高度决定的,内联元素设置width和height是无效的,上下的margin和padding也无效,要将它们设为display:inline-block才有效。
尽量不写height和width,这两个属性会引出很多bug,要宽高的时候可以用padding,但img最好先写width,因为可以先占位,因为引用图片时浏览器不知道图片大小,所有等图片下载完成,它后面的元素又要重新排位置,若先写好width,则不用重排,知道height也可以先写好height。
另外span元素设置padding的时候要将它设为display:inline-block,因为内联元素不能设置宽高,inline-block具有inline的同行特性,也具有block的高度特性。
对于display:inline(内联元素)的元素,设置width/height/上下margin和padding都是无效的
若父元素没有写height,则直接在父元素写
1 | padding: 10px 0; |
子元素就可以居中,所以尽量避免父亲高度确定
让一个元素在父级元素中绝对居中
方法一:
给父级元素加:
1 | position:relative; //若父级元素是body可以不用 |
再给自己加:
1 | div{ |
方法二:(若不兼容IE,工作中只要用这一种方法即可,最简单,Chrome,移动端都可以用)
给父元素加:
1 | display: flex; //让它变成一个弹性盒 |
table自带居中(兼容IE)
1 | <html> |
文字会居中
用div假扮table(兼容IE)
1 | <html> |
用100%高度的before和after
1 | .parent{ |
绝对定位加上margin-top: -自身height的50%
1 | <html> |
让一个背景图居中,并且让它自适应屏幕
1 | background: url("wallhaven-w-min.jpg") no-repeat center center ; |
块级元素水平居中
1 | margin-left:auto; |
内联元素水平居中,给它们的父元素加上
1 | text-align:center; |
若不是内联元素想让它居中,可加display:inline-block,加了之后一般还要加下面这句,不然可能会有bug(下面可能会空出一行)
1 | vertical-align: top; |
让导航栏横过来,并在同一行里均匀分布
给ul加css
1 | ul{ |
去掉li的float:left
去掉ul的clearfix
等腰三角形:
1 | div{ |
增高三角形
1 | div{ |
直角三角形:
1 | div{ |
不规则三角形
1 | //还有这种操作! |
1 | div{ |
position:fixed
position:relative
position:absolute
(绝对定位后元素会变成display:block)要加上这两行的代码,才会显示内容1
2content: "";
display:block; //如果是绝对定位就不用加,因为绝对定位是display:block;
而且before和after是不受*管束的,例如1
2
3
4
5
6
7
8
9
10
11
12*{
box-sizing: border-box;
}
//设置了这个,但是对before和after无效,给它们加border它们还是会变化大小
//除非这样
*::after{
box-sizing: border-box;
}
*::before{
box-sizing: border-box;
}
\<html>1
2
3
4
5
6
7<div class="window">
<div class="images" id=images>
<img1>
<img2>
<img3>
</div>
</div>
\<css>
要给window的div和每个img都定好宽高!并给window加上overflow:hidden1
2
3
4
5
6.images{
display: flex; //给image的div加上这个图片才能横这放!
}
.images > img{
width: 100%;
}
1 | box-shadow: -16px 0 16px 1px rgba(102,102,102,0.4); |
第一个值代表阴影左右偏移,正数往右,负数往左
第二个值代表上下偏移,正往下,负往上
第三个值越大,模糊面积越大越淡
第四个值取正值时,阴影扩大,取负值时,阴影收缩
1 | //css3新属性,绝对定位的时候 |
1 | *{ |
1 | img{ |
iframe标签支持相对路径
<iframe name="xxx" src="" frameborder="0"></iframe>
<a href="" target="xxx"></a>
点击a,则新页面会在iframe里出现
若index.html里写:<iframe src="./index2" frameborder="0"></iframe>
index2.html里写:<iframe src="./index3" frameborder="0"></iframe>
index3.html里写:<a href="http://qq.com" target=_blank>QQ</a>
(点击会在一个新的标签页面里打开)<a href="http://qq.com" target=_self>QQ</a>
(点击会在index3的嵌套页面里打开)<a href="http://qq.com" target=_parent>QQ</a>
(点击会在index2的嵌套页面里打开)<a href="http://qq.com" target=_top>QQ</a>
(点击会在index里打开)
在index的左上角出现一个小的嵌套页面里显示着index2页面里嵌套的index3里的四个QQ链接
<a href="//qq.com">QQ</a>
href里写的是无协议地址,意思是当前用的是http协议就自动继承http协议,用的是file就会用file协议。
我们在终端运行sudo npm i -g http-server
即可安装一个服务器,进入你写index.html的文件夹里运行http-server
即可开启服务器,然后在浏览器浏览终端返回的地址即可用http协议来访问你写的文件
href
a. <a href="?name=pyz">qq</a>
点击之后会在当前页面发起?name=pyz的请求
b. <a href="#sss">qq</a>
点击之后不会发起请求,因为锚点仅仅是在当前页面内的跳转
c. <a href="/..">link</a>
标签被点击后浏览器会发起GET / HTTP/1.1的请求,路径还是/,因为/已经是根目录,无法再往前退
<a href="javascript:;">qq</a>
点击之后a不会做任何事情<a href="javascript:alert(1)";>qq</a>
点击之后会弹出11. \<form>和\<a>的区别:
\<a>提交时是GET请求
\<form>可以用method=’post’发送POST请求
\<form>里必须要有一个submit按钮才能被提交1
2
3
4
5
6
7
8
9
10
11
12
13
14<form action="users" method="post">
<input type="text"value="username">
<input type="password"value="password">
<input type="submit" value="提交">
</form> //form被提及一定会刷新当前页面
//若不想刷新页面的话,可以添加一个iframe,然后把form指向它,不过这种方法已过时
<iframe name="result" src="about:blank" frameborder="0" height="200"></iframe>
<form action="users" method="post" target="resule">
......
</form>
//较新方法,用JSONP(动态创建script)
即\<form>是注册时用的,你提交的账号密码会出现在第四部分里,但GET请求是不会有第四部分的,POST若想有查询参数,可以直接写在action里,如;1
2
3
4
5<form action="users?name=pyz" method="post">
<label>用户名<input type="text" name="username"></label> //input要被提及的话一定要有那么值
<label>密码<input type="password" name="password"></label>
<input type="submit" value="提交">
</form>
2. \<input>要被提交的话一定要有name值
\<label>直接包在input外面用
\<form>里的target和\<a>是一模一样的。
\<form>里如果没有<input type="submit">
而有\<button>,则\<button>会默认为submit,若写成这样<button type="button">button</button>
则不会成为submit,一个form里必须要有一个submit按钮才能提交
1. checkbox
1 | <label><input type="checkbox" name="apple" value="yes">苹果</label> |
一定要有name才能被提交上去
2. radio1
2<label><input type="radio" name="sexual">男</label>
<label><input type="radio" name="sexual">女</label>
和checkbox不同的是,两个name一样的radio只能选中一个
1 | <select name="group" multiple> |
disabled属性意味着不能被选中,selected意思是默认选中的,multiple意思是可以同时选中几项
若想让用户输入一大段文字则用这个元素1
<textarea style="resize: none; width: 200px; height: 100px;" name="hobbies"></textarea>
resize若不设置为none,则用户可以随意更改输入框的大小
1 | <table border="1"> |
thead tbody tfoot不写浏览器也不会报错,而会自动全部加入到tbody里
不要用css来调整canvas的宽高,因为若用css,canvas里的东西都会被拉伸,和img一样,可以用js来设置宽高1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function autoSetCanvasSize(canvas) {
setCanvasSize();
window.onresize = function () { //浏览器改变窗口大小时触发onresize事件
setCanvasSize()
};
function setCanvasSize() {
var pageWidth = document.documentElement.clientWidth; //代表浏览器的宽
var pageHeight = document.documentElement.clientHeight; //代表浏览器的高
canvas.width = pageWidth;
canvas.height = pageHeight;
}
}
html没有块级元素和内联元素的区别,意思就是html只管内容,不管样式,所有样式都由css决定
万维网联盟(W3C)由李爵士于1994年10月离开欧洲核子研究中心(CERN)后成立,该组织通过W3C制定的新标准来促进业界成员间的兼容性和协议。联盟试图让所有的供应商实施一套由联盟选择的核心原则和组件。
MDN Web Docs(旧称Mozilla Developer Network、Mozilla Developer Center,简称MDN)是一个汇集众多Mozilla基金会产品和网络技术开发文档的免费网站。
MDN网站上有目前较全的前端基础教学,如HTML、CSS、JS等
HTML元素表
空标签就是不用加闭标签的标签,也可以叫闭元素。如:
<area>
<base>
<br>
<col>
<colgroup>
when the span is present<command>
<embed>
<hr>
<img>
<input>
<keygen>
<link>
<meta>
<param>
<source>
<track>
<wbr>
宽高由自己决定的元素,如:<img>
<video>
<input>
HTTP协议底层由TCP协议和IP协议构建
TCP 的三次握手指的是什么
简答:每次建立连接前,客户端和服务端之前都要先进行三次对话才开始正式传输内容,三次对话大概是这样的:
1 | 1\. 客户端:我要连接你了,可以吗 |
上面内容足以应付前端面试中关于 TCP 的考题,如果你想更了解 TCP 可以看 此文
外网IP
你的路由器自己会有一个外网IP,像访问的腾讯、阿里的网站就是租用了很多外网IP
内网IP
而你在家用的手机、电脑用的就是内网IP,路由器也会给自己一个内网IP,一般是:192.168.1.1
内网和外网之间不能互相访问,但是外网和外网之间可以访问,所以你在家上网就是通过路由器的外网和其他外网连接,你访问的网站在外网发送信息到你的路由器上,然后路由器将信息转到内网发送到你电脑上
本地 IP:127.0.0.1
特别特殊的 IP:0.0.0.0,它不表示任何设备。
一个端口对应一种服务
HTTP服务用80端口
HTTPS服务用443端口
FTP服务用21端口
使用HTTP协议访问一个IP,要同时提供IP和端口号,平常没填是因为浏览器默认帮你加了
进入服务器所在文件夹输入node server.js 1024
服务器开始监听,使用1024端口
在另一个 窗口输入curl -s -v -- http://localhost:1024
访问服务器的index页面,返回的是请求信息、响应信息和下载内容。
在浏览器中访问则直接显示index页面加上css和js效果
一般情况下/代表index,同时在index里引用了css和js文件,所以出现了三个路径