ES6&&JavaScript:
最近因为工作的缘故又用回nodejs了,然后语法和2年前用的变化挺大的,而且JavaScript的语法越来越趋近于支持对象之类的typeScript,这算是最近半个月看书和博客的总结。
-
顺序次序不一致但对取值没有影响:
var{bar,foo}={foo:"aaa",bar:"boo"};
-
循环的相关的写法:
for a in obj //非常方便的进行对象的遍历 for a of array//适合于进行一般的遍历 arr.forEach(()=>{});//速度接近原始方式进行的速度 //常用的MAP遍历结构 for(let [key.value] of map)
-
es7中async / await,为解决function, 事件发布和监听方式模糊了异步方法之间的流程
可以完全取代promise, generator的应用,但注意async只能够在函数内部进行应用
- 基本上任何一个函数都可以成为async,使用async则表明这个函数是一个异步函数
async function foo(){} const foo = async funtion(){} const foo = async()=>{}//es6的写法
-
在调用 async定义的函数时,使用await,可以简单的理解为函数挂起后等待promis进行返回。
//async/await相关的代码 const printData = async function (filepath) { let keyword = await readFile(filepath); let count = await queryDB(keyword); let data = await getData(res.length); console.log(data); });
-
generator//es6
function后面加*号函数则函数可以变为generator;执行generator将会返回一个遍历器对象,用于遍历generator内部的状态。
//生成器的定义generator const gen function*() { yield 1; return 3; } //迭代器的定义iterator,迭代器是生成器的实例化 let g =gen(); g.next(); //在异步任务处使用yield关键词,此时generator会将程序执行权交给其他代码,而在异步任务完成后,调用next方法来恢复yield下方代码的执行。
yeild
关键字后面需要是function
,promise
,generator
,array
或object
。可以改写文章一开始的例子:const co = reuqire('co'); const task = function* (filepath) { let keyword = yield readFile(filepath); let count = yield queryDB(keyword); let data = yield getData(res.length); console.log(data); }); co(task, './sample.txt');
-
Promise通过进行链接的方式进行改造:
readFile('./sample.txt').then(content => { let keyword = content.substring(0, 5); return queryDB(keyword); }).then(res => { return getData(res.length); }).then(data => { console.log(data); }).catch(err => { console.warn(err); }); //通过then连接的链式操作,使代码更加简洁
Promise的相关方法函数:
-
reduce的相关用法:
//例子,previousValue初始值0,currentValue初始的值为index[currentValue],初始的值为0,index的初始值也为0,array一直不发生改变 //previousValue2次以上为上一次执行的值 [0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){ return previousValue + currentValue; }, 10);
-
weakmap是map的弱引用对象,只是相比于map上面少了很多函数方法,set和weakset也是类似的关系。
-
//JS提供5种内置对象之一 //map的常用方法 clear()方法, 删除所有的键/值对; delete(key), 删除指定的键/值对; entries()返回一个迭代器, 迭代器按照对象的插入顺序返回[key, value]; forEach(callback , context) 循环执行函数并把键/值对作为参数; context为执行函数的上下文this; get(key) 返回Map对象key相对应的value值; has(key) 返回布尔值, 其实就是返回Map对象是否有指定的key; keys() 返回一个迭代器,迭代器按照插入的顺序返回每一个key元素; set(key, value) 给Map对象设置key/value 键/值对, 返回这个Map对象(相对于Javascript的Set,Set对象添加元素的方法叫做add,而Map对象添加元素的方法为set; [@@iterator] 和entrieds()方法一样, 返回一个迭代器, 迭代器按照对象的插入顺序返回[key, value]; //weakmap的常用方法 delete(key) : 删除指定的键/值对; get(key) :返回Map对象key相对应的value值; has(key) :返回布尔值, 其实就是返回Map对象是否有指定的key; set(key):给Map对象设置key/value 键/值对, 返回这个Map对象;
-
-
JavaScript的继承(JavaScript语言特性决定了,类即函数,函数即类),ES6中出现class使得更加像一个类
-
JavaScript的语法中并没有多继承的存在
-
实现多继承:通过class里面引用多个function
-
-
Reflect的属性:(都是对于Object里面的方法进行修改)
Reflect.deleteProperty(queRes[i],'count');//删除指定的json对象属性: Reflect.apply(target, thisArg, args)// Reflect.construct(target, args)//等同于new target(...args) Reflect.get(target, name, receiver)//查找并返回target对象的name属性 Reflect.set(target, name, value, receiver)//设置target对象的name属性 Reflect.defineProperty(target, name, desc)//等同于Object.defineProperty,用来为对象定义属性 Reflect.has(target, name)//相当于name in target Reflect.ownKeys(target)//返回对象的所有属性,等同Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和 Reflect.isExtensible(target)//表明当前对象是否可扩展 Reflect.preventExtensions(target)//阻止该对象进行扩展 Reflect.getOwnPropertyDescriptor(target, name) //等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象,将来会替代掉后者 Reflect.getPrototypeOf(target) //读取对象的__proto__属性,对应Object.getPrototypeOf(obj) Reflect.setPrototypeOf(target, prototype) //用于设置目标对象的原型(prototype),对应Object.setPrototypeOf(obj, newProto)方法
-
JSON是用于TCP,http,websoket的常用数据交互格式,但传入的是JSON字符串
常用的JSON对象和字符串转换方法:
-
JSON字符串转换为JSON对象
let obj = eval('(' + str + ')');//1st let obj = str.parseJSON();//2nd let obj = JSON.parse(str)//3rd
-
JSON对象转换为JSON字符串
let last=obj.toJSONString(); ;//1st let JSON.stringify(obj);//2nd
-
JavaScript tips
1. 字面量/变量/常量和数据类型
-
变量 let /常量 const
-
标识符号的命名:必须以字母, 在JQuery中则代表自身。
-
三种基本数据类型( Number,String,Boolean ),两种引用数据类型(Object,array),两种特殊数据类型(undefined,null);
-
转换数据类型:JavaScript能识别4种类型的数字字面量:十进制数、二进制数、八进制数和十六进制数
parseInt("string",进制)://强制转化为整形,不填默认为10进制 parseFloat("string",进制)://强制转化为浮点型不填,默认为10进制 Boolean(value)//把给定的值转换成Boolean型; Number(value)//把给定的值转换成数字(可以是整数或浮点数); String(value)//把给定的值转换成字符串。
-
特殊字符:
\n 换行 \r 回车 \t 制表符 \' 单引号 \" 双引号 ` 重音符(tab键上方的按键) \$ 美元符 \\ 反斜线 \uXXX 任意的Unicode码 \xXX Latin1字符 其他常用字符 \0 NUL字符 \v 垂直制表符 \b 退格 \f 分页
-
模板字符串:${ } ,如果紧跟 $ 的值被包裹在大括号中,那么该值就会被注入到字符串中
const message = `The curren temperatrue is ${currentTemp} \u00b0C`;
对象- js5种内置对象之一
本质上对象是一个容器,对象的容器可以随着时间推移而改变。
基本语法:let obj={key:value},key必须是字符串或者符号,值可以是任意类型
//for...in是枚举对象属性的传统方式
const SYM =Symbol();
const o={a:1,b:2,c:3,{SYM}:4};
for(let prop in o)
{
if(!o.hasOwnProperty(prop))continue;
console.log('${prop}:${o{prop}}');
}
数组处理(Array) - js5种内置对象之一
数组是一种特殊类型的对象。
数组的内容天生具有自然排序特性。键是数字,并且是有序的。它具有强大的传递信息的能力。
数组特性:
-
数组长度不固定,可以随时添加和删除元素。
-
数组中元素的类型是多样的,每个元素都可以是任意类型。
-
数组从下标0开始。
//获取子数组
arr.slice(start);
arr,slice(start,end);
arr.slice(-end);
//从任意位置添加或删除元素
arr.splice(alterPos,count,elem)
//数组内的分割和替换
arr.copyWithin(targetPos,start,end)
//用指定值填充数组
arr.fill(1)//用相应数值填充过来
arr.fill(elem,start,end)
//数组反转和排序
arr.reverse()
arr.sort()
//map&&filter
arr.map(x=>x.name)//可以把json的map转换为数组
arr.filter(condition)
//reduce转化数组,可以将一个数组归纳为一个单独的值
const sum = arr.reduce({a,x}=>a += x,0)//a表示初始值arr[0],x表示第一个元素的值,然后循环运算
//字符串连接
arr.join(elem)
数组内容操作
push;pop//返回新数组的长度
unshift;shift
concat//在数组末尾添加多个元素
slice
splice
copyWithin//剪切并替换数组元素
fill//填充数组
reverse
sort
数组搜索
indexOf(简单的值),findIndex(复杂的值)//查找元素的下标
lastIndexOf(简单值)//查找最后一个元素的下标
find//元素本身
some//数组中符合条件的元素
every//数组中所有元素都符合给定条件
数组转化
map//转化数组中的所有元素
filter//根据给定条件排除数组元素
reduce//把整个数组转化成另一种数组类型
join//把元素转化成字符串合并
日期和时间(Date)- js5种内置对象之一
//moment.js为日期提供支持方法
const m = moment().add(10,'hours').subtract(3,"days").endof('month');
fromNow()//从现在算起
m为未来10个小时以后的时间点倒退3天后所在月份的月底
//创建当前日期
const now = new Date();
//创建指定日期从0开始,9-10月
const halloweenParty = new Date(2016,9,31,19,0);
//创建指定日期和时间,19:00am = 7:00pm
const halloweenParty = new Date(2016,9,31,19,0)
//一些方法检索Date对象的组件
halloweenParty.getFullYear();
getMonth();getDate();getDay();getHours();getMinutes();getSeconds();getMillseconds();
//上述时间所对应的UTC时间
getUTCFullYear();getUTCMonth();getUTCDate();
正则表达式(RegExp)-js5种内置对象之一
//简单邮件识别器
const email = /\b[a-z0-9._-]+@[a-z_-]+(?:\.[a-z]+)+\b/;
//US手机号码识别器
const phone = /(:?\+1)?(:?\d3\s?|\d{3}[\s-]?)\d{3}[\s-]?\d{4}/;
//基本正则表达式
const re1 = /going/ //可以搜索going的表达式
const re2 =new RegExP('going')//使用对象构造器的等价形式
//一些常用的正则方法
startWith(),endWith(),includes(),indexOf()
match(),search(),input.replace().test()//从字符串开始
re.exec//从正则表达式开始
{n}//精确n次,匹配5位数字
{n,}//至少n次,匹配5位或者5位以上的数字
{n,m}//最少n次,最多m次 /\d{2,5}/
?//0或者1,等价于{0,1}/[a-z]\d?/i
*//0次或者多次,匹配跟随了0个或多个数字的字母 /a-z\d*/i 匹配跟随了0个或者多个数字的字母,表示重复
+//1次或者多次 /a-z\d+/i 匹配至少跟随一个数字的字母
\s\S能匹配所有的空格和非空格
函数替换
//保留class,id和href的属性,并删除其他内容
function sanitizeATag//获取标签
const parts = aTag.match(/<a\s+(.*?)>(.*?)<\/a>/i);
//parts[1]是<a>标签中的属性,parts[2]是<a></a>之间的内容
const attributes = parts[1]
.split(/\s+/);//接下来将其分割成独立的属性
return '<a'+attributes
.filter(attr=>/^(?:class|id|href)[\s+]/i.test(attr)) //过滤掉class.id和href之外的属性
.join('')//将它们用空格连接起来
+'>'//关闭<a>标签
+parts[2]//添加内容
+'</a>'//添加闭合标签
replace函数的接受顺序//整个匹配的字符串(等价$&)>>匹配上的组,有多少组就会有多少参数,原始字符串中的匹配偏移量,原始字符串
描点
//只有两种描点:^和$,类似于标记物之类的
//一般字符串匹配的是整个字符串的开始和末尾,即使字符串中有换行;
//如果把某个字符串当作多行字符串(以换行符分隔来处理,就需要用到m选项)
const input = "One line\nTwo lines\nTree lines\nFour"
const beginners = input.match(/^\w+/mg);//{"One","Two","Three","Four"}
const endings = input.match(/\w+$/mg)
向前查找
//向前查找(?=<subexpression>)
//否定向前查找(?!<subexpression>)
//重要场景:密码验证
动态构造正则
const userRegex= new RegExp('@(?:${user.join('|')})\\b','g');//第一个反斜杆是用来转义第二个反斜杠
text.match(userRegex)
表达式和运算符
- 算术表达式的优先级:PEMDAS(括指乘除加减)Parentless括号 Exponents指数 Multiplication乘法 Division除法 Addition加法 subtraction减法
- typeof能够打印运算符,instanceof原型链测试,判断是否在其中,与in比较类似
作用域和严格模式
异步编程
-
JavaScript对异步编程的支持有三个不同的阶段:回调阶段,promise阶段和生成器阶段
-
异步编程的4个主要使用场景:用户输入,网络请求(如Ajax请求),文件系统操作(读/写文件等)刻意的时间延迟(比如警告)
-
setTimeout,setInterval和clearInterval都定义在全局对象中(在浏览器中是Window,在node中是global)
-
错误优先回调
const fs = require('fs'); const fname ='may_or_may_not_exist.txt' fs.readFile(fname,function(err,data){ if(err)return console('error reading file ${fname}:${err.message}') console.log('${fname}contents:${data'} })
-
Promise
-
Promise只会返回两种事情:被满足(success)和被拒绝(failure)里面分别使用resolve(满足)和reject的回调
-
resolve和reject可以被多次调用,但只有一次会起作用,且并没有终止函数执行,只是修改promise的状态
-
事件:EvenEmitter
-
promise链:
function launch(){ return new Promise((resolve,reject)=>{ console.log("on") setTimeout(function(){ resolve("In orbit"); },2*1000) }) } const c = new Countdown(5) .on('tick',i=>console.log(i+'...')); c.go() .then(launch) .then(msg=>{ console.log(msg); }) .catch(err=>{ console.error("Houston, we have a problem....") }) //开发人员不应该编写自己的生成器运行器,应该使用co或者koa
-
DOM和JQuery以及Node
-
文档对象的基本模型
<html> <head> <title></title> <js></js> <style></style> </head> <body> <h1></h1> <div> <h1></h1> text node <p></p> text node </div> </body> </body> </html>
-
事件捕获与事件冒泡:三件事情来影响其他处理器的调用
- 第一种最常见的,即已经见过的preventDefault,它可以取消地址;事件会继续传播,但是defaultPrevented会被置成true
- 第二种是调用stopPropagation,时间传播到当前元素之后,将不会继续传播(所有绑定到当前元素上的处理器都会被调用,但绑定到其他元素上的处理器不会被调用)
- 最后一件事,调用stopImmediatePropagation会阻止所有还未调用的处理器被调用(即使这些处理器被绑定在当前的元素上)
-
在JQuery的事件监听器中,直接在处理器中返回false与调用stopPropagation是等价的,这是Jquery的约定,但不能在DOM API中进行使用。
-
事件的种类
- 拖拽事件(Drag events):实现了拖放事件的接口,比如drag start,drag, dragend,drop。
- 焦点事件(Focus events):用户与可编辑的元素交互时执行的一些操作。当用户“进入一个字段”会触发focus事件,用户离开时会触发blur事件,当用户修改字段时则会触发change事件。
- 表单事件(Form events):当用户提交一个表单(由submit或者对应的地方敲击回车),会触发表单上的submit事件。
- 输入设备事件(Input device events):常见的触摸事件有鼠标触摸事件(mousedown,move,mouseup,mouseenter,mouseleave,mouseover,mousewheel)和键盘事件(keydown,keypress,keyup)
- 媒体事件(media events):用于追踪用户与html5中的视频,音频播放器的交互
- 进度事件(Progress events):通知浏览器加载网页的速度,最常用的是load
- 触摸事件(Touch events):触摸事件为可触摸设备提供了高级支持
-
JQuery提供的text和html方法分别等于对DOM元素的textContent和innerHTML属性进行赋值
//jQuery的基本实例 //方法1 $(document).ready(function(){ // 开始写 jQuery 代码... }); //方法2 $(function(){ // 开始写 jQuery 代码... }); //一个简单的例子 $('p') .after('<hr>') .append('<sup>*</sup>') .filter(':odd') .css('margin-left','20px')
-
Ajax:在相应元素定义触发事件,能够在文件中定义触发的函数
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> function loadXMLDoc() { var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码 xmlhttp=new XMLHttpRequest(); } else { // IE6, IE5 浏览器执行代码 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; } } xmlhttp.open("GET","/try/ajax/ajax_info.txt",true); xmlhttp.send(); } </script> </head> <body> <div id="myDiv"><h2>使用 AJAX 修改该文本内容</h2></div> <button type="button" onclick="loadXMLDoc()">修改内容</button> </body>
-
Node相关的操作
-
exports有快捷语法和moudle.exports两种表达方式
//方法1 exports.function=function((err,a)={ return a; }) //方法2 //index.get=function((err,a)={ //return a; //}) class index{ } module.exports = index;
-
核心模块,文件模块,npm模块,自定义函数模块
核心模块//不需要用显示声明,可以进行直接使用 文件模块//自己定义的模块,需要用require(./)进行使用 npm模块//通过npm导入,需要用require进行定义 自定义函数模块 //const debug = require('debug')('main') 直接将文件所包含的函数
-
文件,进程,操作系统,流
//文件系统 fs.writeFile();fs.readFile();fs.writeFileSync();fs.readFileSync(); //进程 process //子进程的模块对外主要是三个函数:exec,exeecFile和fork 并且有其自身的同步函数 //流 const ws = fs.createWriteStream('streaming.txt',{encoding:'utf-8'}); //操作系统os
-
web服务
const http = require('http') const server = http.createServer((req,res)={ console.log('${req.method} ${req.url}'); res.end('hi') }) const port = 8080 server.listen(port,()={ console.log('server started on port ${port}') })
-
-
预留
[1].(美)鲍尔斯. JavaScript学习指南(第三版)[M].北京:人民邮电出版社
[2].