Hank's House


  • Home

  • About

  • Tags

  • Categories

  • Archives

map/forEach/for/reduce/for~of/for~in/filter

Posted on 2019-04-11

特点 效率

for

1
2
3
4
5
6
let data = [{id:1},{id:2},{id:3}]
let len = data.length
for(let i=0;i<len;i+=1) {
data[i].id = i
}
console.log(data)

最基础的,相比于其他支持break、continue

for~in

1
2
3
4
5
let data = [{id:1},{id:2},{id:3}]
for(let i in data) {
data[i].id = i
}
console.log(data)

循环后id变成了字符串。(i是索引’0’ ‘1’ ‘2’)
多用于遍历对象

1
2
3
4
5
let obj = {a:1,b:2,c:3}
for(let i in obj) {
obj[i] += 1
}
console.log(obj)

forEach

1
2
3
4
5
6
7
8
9
let hasSpaceInValue = false
const reg = /[\r\n]/g
if (response && response.records) {
response.records.forEach(item => {
if (reg.test(item.value) || String(item.value).length > 180) {
hasSpaceInValue = true
}
})
}

不打算改变数据时使用。

1
2
3
4
5
let arr = [1, 2, 3, 4, 5];
arr.forEach((num, index) => {
return arr[index] = num * 2;
});
console.log(arr)

可以改变原始数组。

map

1
2
3
4
5
let arr = [1, 2, 3, 4, 5];
let doubled = arr.map(num => {
return num * 2;
});
console.log(arr)

创建新数组(分配内存空间存储新数组)

es6 for~of

代替for~in和forEach
遍历数组、字符串、映射(maps)、sets(集合)————iterable迭代器对象

1
2
3
4
5
6
7
let data = [{id:1},{id:2},{id:3}]
for(let i of data) {
console.log(i)
if(i.id === 1) {
break;
}
}

遍历的是元素值;可以响应break、continue、return
(考虑兼容问题)

filter

1
2
3
let target = data.list.filter(
item => item.name && item.name.toLowerCase().indexOf(value.toLowerCase()) > -1
);

不改变原数组

reduce

1
2
3
4
5
6
var arr = [1,2,8,20];
var sum = arr.reduce(function (prev, cur) {
console.log(prev,cur)
return prev + cur;
},0);
console.log(sum)

可同时将前面数组项遍历产生的结果与当前遍历项进行运算

效率

for~in map

for for~of forEach

待掌握的知识点

Posted on 2018-09-27

手动置顶。
Native App(weex)/wEB App
H5界面(video等)
PWA 渐进式web应用程序
Echart数据图表(数据可视化)
node爬虫
经典算法补充
表单验证

ajax axios fetch

Posted on 2018-04-26

定时循环输出汇总(闭包 promise async)

Posted on 2018-04-22

参考网站:https://zhuanlan.zhihu.com/p/25855075

/*for(var i=0;i<4;i++){
console.log(i);
}//0 1 2 3直接顺序输出

for(var i=0;i<4;i++){
setTimeout(function(){console.log(i);},1000);
}//隔1s输出4444

for(var i=0;i<4;i++){
(function(a){
setTimeout(function(){console.log(a);},1000);
})(i)
}//隔1s输出0123(传入i)

for(let i=0;i<4;i++){
setTimeout(function(){console.log(i);},1000);
}//隔1s输出0123(使用let)

for (var i = 0; i < 4; i++) {
setTimeout(fn(i), 3000);
}//fn()压栈,显示的实际是function(){console.log(a);},3s后执行
function fn(a){
return function(){
console.log(a);
}
}//无return的话,就直接输出了

//以上为隔n秒后输出全部
//以下为隔n秒输出一个数
for(var i=0;i<4;i++){
(function(a){
setTimeout(function(){console.log(a);},1000a);
})(i)
}//设置1000
a 相对于初始时间依次递增
function a(){
var s = 0;
setInterval(function(){console.log(s);s++},1000);
}//setInterval实现
var obj={val:0,
count:function(){
this.val++;
console.log(this.val);
}
};
setInterval(()=>{obj.count();},1000) //对象方法调用实现
*/

几个特例:
一、

1
2
3
4
5
6
7
8
 
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
console.log(i); //5 55555


注意点:var换为let后,循环外的console.log无法输出5,因为会把i限定在循环内,循环体外无i。

二、promise实现见链接
注意点:将多个promise中的setTimeout函数推入tasks数组,Promise.all(tasks).then实现。

三、async实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
const sleep = (timeountMS) => new Promise((resolve) => {
setTimeout(resolve, timeountMS);
});

(async () => { // 声明即执行的 async 函数表达式
for (var i = 0; i < 5; i++) {
await sleep(1000); //暂停一秒
console.log(new Date, i);
}

await sleep(1000);
console.log(new Date, i);
})();

定时器、promise等执行顺序(事件循环相关)

Posted on 2018-04-21

以面试常见代码题目为例:

1
2
3
4
5
6
7
8
9
10
11
12
 
setTimeout(function(){console.log(4)},0);
new Promise(function(resolve){
console.log(1)
for( var i=0 ; i<10000 ; i++ ){
i==9999 && resolve()
}
console.log(2)
}).then(function(){
console.log(5)
});
console.log(3);

输出顺序为:1 2 3 5 4
关键词:
事件循环(event loop):一个
任务队列(task queue):多个,主要是下面这俩
宏任务macrotask:script(整体代码) setTimeout setInterval setImmediate I/O UIrendering
微任务microtask:process.nextTick Promise.then MutationObserver
任务源(task source):每个任务都有,相同任务源放入同一个任务队列
备注:点击事件等属于I/O;UIrendering是在DOM变化时执行,大约16ms调用一次;关于setImmmediate和process.nextTick,为node.js中的方法;关于tick——
事件循环:主线程不断从任务队列中读取事件。
每一次事件循环中,macrotask只会提取一个执行,而microtask会一直提取,直到队列空。接着继续提取一个macrotask中的任务,再执行完microtask中的任务。如此循环。
故上述代码大致顺序为:
1、整个script推入macrotask中,遇见setTimeout挂起到新的macrotask中,遇见promise.then挂起到microtask中;
2、script的macrotask执行完后,输出1 2 3(注意promise自身中的是在script部分执行),接着执行完microtask中的所有事件,输出5;
3、读取任务队列,此处为setTimeout的事件,输出4;所有队列均清空。

异步任务 回调函数 执行栈 任务队列 主线程:
将正常任务扔到主线程的执行栈中执行,异步任务扔到任务队列(事件)中。执行栈执行完后,任务队列中的事件进入执行栈,回调函数开始执行。
若涉及定时器,主线程会检查后确认任务队列相应任务是否进入主线程。
""
参考网站:http://www.ruanyifeng.com/blog/2014/10/event-loop.html

捋清了又忘了的问题

Posted on 2018-04-12

缓存

参考网页:https://segmentfault.com/a/1190000008956069
强缓存&协商缓存

强缓存:expires(绝对到期时间) cache-control(max-age相对时间)
如果文件没过期,不必向服务器发送数据,直接使用缓存;注意,后者优先级更高。
如果过期,浏览器携带关于缓存header字段信息比如Etag什么的发给服务器

协商缓存:
Etag/If-none-match 客户端发回header后,服务器比对Etag,不同就将If-none-match设置为true返回200,更新资源;否则返回304继续使用缓存
Last-Modify/If-Modified-Since 前者是服务器返回的header中的,表示该资源最后修改时间;后者是浏览器请求时header包含的,为上次缓存前的Last-Modify,这样服务器比对自身的Last-Modify和刚收到的浏览器发回来的If-Modified-Since的值,不同即不命中缓存,返回200,相同即命中缓存,返回304使用缓存就好。(也不会返回Last-Modify,毕竟没变嘛)

关于两种协商缓存为什么要同时存在?
1、有时仅仅修改文件时间但不改变内容,这样按照modify仍然不会命中缓存,故使用Etag相当于双保险;
2、修改过于频繁比如在秒级以下,这样modify无法判断;
3、服务器的文件修改时间不精确
服务器会优先验证Etag,一致才会继续比对Last-Modify。

XSS、CSRF攻击

参考网站:https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
跨站脚本攻击XSS
原理:插入script字符串使得提交地址指向黑客服务器,诱导用户点击提交数据
预防:
1 浏览器自身可以识别
2 http-only:cookie中设置该属性,js脚本无法获取cookie信息
3 过滤客户端提交的数据,特别是表单数据,如字符转义,使得script的括号不会被js引擎直接解析,如合法性验证等

跨站请求伪造CSRF
原理:点击黑客链接,链接获取用户的cookie,直接执行用户目标网站界面的操作(当然得同一浏览器标签页以及有cookie时间限制)
是拿不到看不到cookie数据的,只能利用数据。所以改变数据的服务需要进行CSRF保护。
防范:
1 验证http referer字段:记录了http请求来源地址。(CSRF攻击肯定是不一样的url地址)(缺点:有些内网并不想服务端存储访问地址)
2 请求地址添加随机token验证(用户登陆http请求时产生token存在session中,每次进行对比)
3 http头中自定义属性并验证(写在 XMLHttpRequest中)

css动画

transform 静态效果,变形
animation 立即运行,控制更精确
transition 变换,配合hover等事件触发

setTimeout Promise

前者在新的事件循环开始时进行,后者在本轮事件循环结束时执行。

####IE6常见bug
参考:http://www.frontopen.com/1130.html
双边距:float+margin时,margin数值自动翻倍。==》显式设置display
3像素问题:float相邻元素总有3px间距 ==》同一行元素都加上float
点击链接后失效:==》注意顺序link visited hover active
img文件下方间隙:设置display或者font-size:0

webpack gulp 区别

https://segmentfault.com/q/1010000008058766?_ea=1535003
gulp:task runner,跑一个个任务,比如SASS==》CSS,coffee==》js

正则表达式

Posted on 2018-04-10

参考:
http://www.runoob.com/regexp/regexp-syntax.html 菜鸟教程
http://www.jb51.net/article/76901.htm 汇总的正则
设置规则,让计算机根据规则去寻找相应的东西。
定义正则两种方式:var a = new RegExp(“a”) 和 var a = /a/

正则常用方法(4个):

test:查找符合正则的内容,返回true
var str = ‘1111’;
var re = /\D/;//非数字。注意这里没有引号!!!
re.test(str) === false //用re规则来验证str中是否有非数字

search:查找符合正则的内容,返回出现的位置index
str.search(re) //注意写法,和test方法不同
再比如查找字符串中是否有字母b,则re = /B/i(i意味着不区分大小写)
我们可以进一步总结,无非是普通字母和加了反斜线的转义字母这两种。

match:查找符合正则的内容,成功返回内容数组。
str.match(/s/) 即查找str中的s并返回s
当然正常用法还是str.match(/\d+/g)。
此处以str = ‘ha123ha12’做一个区分:
/\d+/g [123,12]
/\d/g [1,2,3,1,2]
/\d+/ [“123”, index: 2, input: “ha123ha12”]
/\d/ [“1”, index: 2, input: “ha123ha12”]
故g表示搜索完整个字符串才停止;+表示每次匹配的不止一个,连续匹配

replace:查找替换
str.replace(正则,新字符串/回调函数)
回调函数的目的也是返回替换后的字符,只是可以针对不同的部分返回不同。
str = ‘123ss123aa’ //ss和aa替换成
str.replace(/ss|aa/g,’
‘) //“123123“
但显然我希望的是每个字母均替换为
故str.replace(/ss|aa/g,function(str){
console.log(str) //ss aa 这里要注意!
//接下来就是用
来替换咯
var result = ‘’;
for(var i = 0;i<str.length;i++){
result += ‘‘
}
return result;
})
实际就是先返回俩
替换了ss,再返回俩替换了aa。

正则字符

插入常用规则介绍:
\d(数字) \D(非数字) \s(空格) \S(非空格) \w(字符:字母数字下划线) \W(非字符)
| (或,比如/ss|sa/)
^:[^a]排除a ^[a]首位,比如^[1-9]即首位是1-9
$:正则最后,代表结束
\d{4,11}:4-11个数字
+、、?:表示出现在其前面的字符分别可以出现 最少一次、无所谓次数、最多一次 查找这些特殊字符时要注意转义,即/\*/这才是**

QQ号(首位不为0,至少5位数):
/^[1-9]\d{4,11}$/.test(inputQQ)

去空格:
所有空格 str.replace(/\s/g,””)
两头空格 str.replace(/^\s
|\s*$/g,””) 以及 trim
左or右空格 上面选一个就好

查找连续的单词:
I love love you,删除一个love
str.replace(/\b([a-z]+) \1\b/ig)
\1是为了重复前面一次 \b是确认字符和空格的边界

其他常用校验:
匹配中文:[\u4e00-\u9fa5] //中文ACALL码的范围
Email:^\w+@[a-z0-9]+(.[a-z]+){1,3}$
//起始至少为一个字符(\w字母,数字或者下划线),然后匹配@,接着为任意个字母或者数字,.代表真正的点,.后面为至少一个的字符(a-z),同时这个(比如.com)整体为一个子项作为结束,可以出现1-3次。因为有的邮箱是这样的.cn.net。(xxxx.@qq.com xxxx.@163.com xxxx.@16.cn.net )
网址:[a-zA-z]+://[^\s]* http://……
//匹配不分大小写的任意字母,接着是//,后面是非空格的任意字符

邮政编码:[1-9]\d{5} //起始数字不能为0,然后是5个数字
身份证:[1-9]\d{14}|[1-9]\d{17}|[1-9]\d{16}x

另:多个校验直接正则对象,re={
email:/^\w+@[a-z0-9]+(.[a-z]+){1,3}$/,
number:/\d+/
}

小程序&快应用

Posted on 2018-04-07

以实例项目进行问题总结。项目已上传到github。各种API等详见小程序官网。
实现:
调用地图&调用并显示cnode论坛。

几个点:
获取输入框的内容 e.detail.value
块级元素时hidden才生效
tab标签的切换—— data-idx=”“和e.currentTarget.dataset.idx来判断点击的哪一个tab。标签下的内容通过hidden进行控制。
读取服务端API单独存放。
灵活使用v-for。
关于标题长度过长显示省略号。
关于富文本的解析。(图片未成功转换)
关于点击按钮翻页。(下拉加载调用小程序api即可)
页面间数据传输——url:’../xxx?url=’+url 查询字符串形式将数据传输到跳转的界面

问题:
不使用appid时可以顺利调用cnodeAPI,但是使用了appid即便配置了request,也调用失败???

快应用
运行npm run server或者build时提示找不到相应js文件。
使用hap update –force命令,注意,之后会绿字提示‘升级完毕, 请运行npm install更新依赖包’,别理这。
重新运行npm命令即可。
命令行的二维码扫描无效,直接配置服务器。

node基础学习——进程管理

Posted on 2018-03-29

几个名词:
process对象:表示执行的进程
关于node子进程模块
操作系统任务调度:并发(多任务彼此交错进行)。
并行任务只能在多核CPU上进行,但任务数量必然多于CPU核心数量,操作系统也会自动进行任务调度。
进程创建——exec spawn fork
exec Buffer存储进程输出。适用于进程输入输出数据量较少时
spawn 数据量比较大(支持stream)
process.on在父子进程中监听message和send事件实现通信。
util模块封装了一些常用的js函数
进程线程参考

1
2
3
4
5
6
7
8
9
10
11
12
//主进程
var fs = require('fs');
const child_process = require('child_process');
var work = child_process.exec('node server.js',function(err,stdout,stderr){
console.log('stdout'+stdout);//server.js的输出结果。有两个子进程,一个是node.exe,一个是server(这是主模块文件路径)
console.log('stderr'+stderr);
});
work.on('exit',function(code){ //退出上述子进程
console.log('退出码'+code);//code为0即是正确
})
console.log(work.pid);//获取进程pid
//捕获异常退出程序 try...catch(err){process.exit(1)} 状态码设置1。正常是0。
1
2
console.log("进程"+process.argv+"执行");
//process对象的argv属性,表征各个进程,如process.argv[0]必是node执行程序路径(node.exe)。

node-爬虫初探

Posted on 2018-03-21

待补充

获取网页源码

1
2
3
4
5
6
7
8
9
http.get('http://www.baidu.com',(res)=>{
var html = '';
res.on('data',(data)=>{
html += data;
});
res.on('end',()=>{
console.log(html);
})
})

superagent页面数据下载

如何使用cheerio进行数据筛选?
实际就是load上html文件,类似jquery进行解析

123

Hank

29 posts
11 tags
© 2019 Hank
Powered by Hexo
|
Theme — NexT.Mist v5.1.4