@FunC
2017-08-10T00:54:12.000000Z
字数 8334
阅读 2534
前端
不用循环创建下标和索引相同的数组(注意本来数组的键就是数字,遍历键名)
//ES5//apply的第二个参数是类数组,所以这里的{length: 100}会识别成一百项undefined的数组//Object.keys()返回对象属性字符串组成的数组,而数组的属性就是下标Object.keys(Array.apply(null, {length: 100}));//ES6//array.keys()是一个迭代器,value等于下标,用扩展运算符展开就是下标组成的数组了[...Array(100).keys()]
onresize 事件会在窗口或框架(iframe)被调整大小时发生。除了window对象和body元素,其它元素虽然有的支持,但不会主动触发
resize的使用方式:
- 直接在元素中定义属性
- 直接给onresize赋值(强制,入侵式事件注册)
可以给window和document.body的onresize赋值
如window.onresize=function(){},document.body.onresize=function(){}
但需要注意的是,赋值之后,window.onresize === document.body.onresize 为true- 使用事件监听(事件队列,一个元素同一事件可以绑定多次)
只对window有作用
如window.addEventListener(“resize”,fn);
if(window.PointerEvent) //IE 11 & Edge{$('#holder').on('pointermove', printcoordinate);}else if(window.MSPointerEvent) //IE10{$('#holder').on('MSPointerMove', printcoordinate);}else //Chrome, Safari{$('#holder').on('touchmove', printcoordinate);}
<meta name="viewport" content="user-scalable=no"><meta name="viewport" content="initial-scale=1,maximum-scale=1">
<meta name="viewport" content="width=device-width">
//最佳方案(缺点是兼容性差).rect{width:100vmin;//vmin为1%视窗宽高中较小的一个heigth:100vmin;}//利用padding、margin的百分值计算依赖于父元素的width,无法实现横屏时的自适应.rect{width: 100%;background-color: lightblue;}.rect:after{display: block;content:' ';padding-top:100%;}
//一个元素既是第一个也是倒数第四个=>只有四个子元素//这时的相邻兄弟元素就是2,3,4//再加上自己=>仅有4个子元素时选择全部子元素.li:first-child:nth-last-child(4),.li:first-child:nth-last-child(4) ~ li {// 假设需求是近当有4个li时为四宫格padding-top: 50%;width: 50%;}
//a标签之间会有无法点击的空白,这是由于换行符导致的(不换行或不闭合//可在nav设置font-size:0;或者改用flex<nav><a href="#">One</a><a href="#">Two</a><a href="#">Three</a></nav>
基于baseline,可让父元素font-size:0;或极小的line-height;或使用flex
为什么用let就能解决?
原本用var,循环体属于全局作用域,i也在全局作用域内。
当计时器到达后,开始寻找变量
使用var时,顺序是:事件绑定函数作用域→上一级作用域→...→全局作用域
当使用let时,使循环体形成了块级作用域,即每一个循环体都是不同的作用域
顺序是:事件绑定函数作用域→循环体作用域→上一级作用域→...→全局作用域
相当于
{let i = 1;setTimeout(() => console.log(i)}, i*1000);}{let i = 2;setTimeout(() => console.log(i)}, i*1000);}{let i = 3;setTimeout(() => console.log(i)}, i*1000);}
从垃圾清理角度讲,当当前作用域结束后,会尝试清理不再被引用的变量。
使用var时,循环体为全局作用域,全局作用域在关闭环境时才清除。
而使用let时,循环体为块级作用域,每次循环都要尝试清除不再被引用的变量,而这时i被setTimeout的console.log引用着,所以形成了闭包(?)
传统的使用闭包(立即执行函数传参数)的解决方案其实就是在模拟块级作用域。update: ES6中的let在循环中的行为进行了特别规定
所以其实内部完成了赋值:
for (let i = 0; i < 10; i++) {let j = i; // 实际上内部多了这一步console.log(j);}
基于buffer实现,继承自EventEmitter
自动控制后端压力,可以链式调用,方便
如fs.readFile('./sthBig.gz', callback)需要将整个文件读入内存,才能返回结果(大量请求时消耗巨大)
改成fs.createReadStream('./sthBig.gz'),每次读一个chunk,中间还能处理(如使用split()模块调整为每chunk一行)需要加工时可使用transfromliu(如through2模块),读写完后的回调可以通过监听'close'事件来触发。
readstream,只可读(但在消耗前可通过readstream.push(sth)写入缓存)
writestream,只可写,还能通过.write()/.end()(不再可以写入)来写入
transfrom,可读可写,但不存数据。中转,中间处理(如a.pipe(b).pipe(c))中的b
duplex,可读可写存数据,如a.pipe(b).pipe(a)中的a。
HTML文档能流式处理 -> 所以其实document也有.open(), .write(), .close()方法
在文档解析中途进行.write():附加在文档尾部
文档加载结束后, 调用了.close()关闭文档流
此后再次调用.write(), 则强行先执行一次.open(),即开启新的文档流-> 故此后再write()会覆盖页面内容
application/x-www-form-urlencoded multipart/form-data text/plain以外的主体内容时,会使用OPTIONS发送Preflight请求 Origin Access-Control-Request-Method Access-Control-Request-Headers(可选,自定义头部)。响应头对应Access-Control-Allow-Origin Access-Control-Allow-Method Access-Control-Allow-Headers Access-Control-Max-Agefloat失效:
1.position:absolute/fixed;
2.display:flex
.parent{display:flex;justify-contet: center;align-items: center;}
.parent{position: relative;}.child{position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%)//自身的50%}
.parent{display: table-cell;text-align:center;vertical-align:middle;}.child{display: inline-block;vertical-align: center;}
git remote add origin xxxxxxxx//首次要用-u push上去同时关联文件git push -u origin mastergit push origin master//克隆远程库git clone xxxxxx
'A' !== new String('A'); //truenew String('A') !== new String('A'); //true
简单总结就是:
1. 非数字下标会忽略
2. length可写
var arr = [];arr['a'] = 'a';console.log(arr.length);//0arr['2'] = 2;console.log(arr.length);//3arr.length = 0;console.log(arr.length);//0arr.length = 3;console.log(arr);//[undefined,undefined,undefined]
思路:将浮点数转换为整数,计算后再切换为小数。
1. 用 split('.');判断小数点位数n
2. 取位数最大的,分别乘10的n次方
3. 重点:对结果使用parseInt(),转换为真正的整数
4. 整数运算,再除以10的n次方
//宽高element.offsetHeightelement.offsetWidth//绝对位置element.offsetTopelement.offsetLeft//相对位置var rectObj = element.getBoundingClientRect();//只读rectObj.leftrectObj.toprectObj.rightrectObj.bottomrectObj.height//IE8及以下没有宽高rectObj.width
伪造用户的请求,如让用户访问钓鱼网站,网站向目标站点发起请求,此时会带上用户的cookie使验证通过
cookie分为:session cookie(临时cookie)、本地cookie(expire之后才失效)(部分标签的请求禁止携带本地cookie,如img、iframe、script、link)CSRF的防御:
1. 验证码(需要用户互动才能完成操作,但仍有可能被钓鱼。且不可能全部请求都加验证码)
2. referer过滤:过滤不合理的referer(但服务端不一定能取到referer,有时出于隐私考虑会闲置referer的发送)
3. 依赖AJAX的CORS配合JSON API:因为AJAX限制跨域,而能跨域的form标签不能发送JSON
4.CSRF token:(从本质出发)CSRF本质:重要操作的所有参数能被猜到(才能构建出请求)
请求中带上随机数token
token由服务端发给客户端,请求时需要带上token进行验证token注意事项:
- 放在表单的隐藏项中,敏感操作改为post
- 避免token出现在**页面的**URL中,此时可能通过referer被记录
- token不能被ajax获取到(不要提供/csrf路由)
- token只能避免CSRF,如果攻击者能使用JavaScript(如XSS攻击),token自然无效
可能输出位置
1. HTML标签中<div>$var</div>构造script标签或使用事件属性等
2. HTML属性中,使用引号闭合属性
3. CSS中输出:含url()的属性,配合JavaScript、dataURI等伪协议等
4. 对于富文本:使用白名单
(set-cookie: key=value; expirse: GMT time; max-age:xxxs; domain: path: secure;等)
cookie储存于客户端,session储存于服务端。
cookie是客户端的状态保持方案(HTTP协议无状态)
session是客户端与服务端状态保持的解决方案(如购物车的添加),需要依赖客户端保存相应的标识(如sid),所以依赖于cookie(较好的实现方案)。
session可避免cookie直接存储敏感信息。
以用户登录为例:
1. 用户提交用户名密码的表单(经过前端加密(配合验证码哈希)/HTTPS)
2. 服务端验证用户名密码
3. 如果验证通过, 生成一个会话对象(检查有没有同用户的会话,有就删除,实现单用户登录),里面含有sid,用户名,以及其他敏感信息,如logIn=true,设置set-cookie:sid=value
4. 下次发起请求时cookie带有sid,服务端通过sid寻找对应的会话并根据状态进行操作。
5. 一个会话不会因为客户端关闭而结束,故一般有过期时间(进行‘登出’操作能主动关闭session)
onStateChange(() => {view = render(state)})
即state何时change?(修改setter,进行notify)
render哪些部分?组件内VNode diff
Watcher(监听表达式、回调操作)、Dep(watcher依赖收集)、Observer(其实只是响应化)的相互依赖
具体见
指向定义时的父级的this,自身无this
因为自身无this,所以也不能通过.bind()、.call()、.apply()方法改变this。
如果作为函数被return出来,因为自身无this,所以其实形成了一个闭包,指向上一级的this。
//用例数据var obj = {name: 'mike',sayHi: function(){console.log(this.name);},say: () => {console.log(this.name);}}var name = 'ben';//函数部分function c(){return () => console.log(this.name)}c()();//ben 指向父级的this,父级的this为windowc.bind(obj)()();//mike 指向父级的this,父级的this绑定为objc().bind(obj)();//ben bind无效
圆括号 > 成员访问(
.和[]) = 带参数的new()> 函数调用(fn()) = 无参数的new> 后置递增/递减(...++ ...--) > 除扩展运算符外的一元运算符