前端

他虽疯,但却有他的一套理论

引言

如果说前两天的复习属于张口就来,花不了什么时间,
那么今天,我恐怕就得面向搜索引擎写作了,虽然同样是基础,也许我在刚学完JavaScript的时候还能对各种基本操作如数家珍
而现在,我只能在要用到啥的时候意识到,有这么个东西,但是不知道叫啥。这极大地拖慢了工作效率,尤其是在不能自由上网的环境下
故而,在这个章节中,我将主要过一过各种基础操作的API也许会有几个常用的JavaScript片段,我不确定,这得写了才知道。
JavaScript的操作,反正经常能听到写起来不舒服的言论,反之亦然,然我对别的语言并没有系统的学习过,
所以没有对比,也没有什么高见。
本文依旧是以ES5为主,具有随处可见,而覆盖面略为偏颇为指导思想。

字符串操作

众所众知字符串操作是最为常见的,在web领域曾经有一段时间,所谓后端就是在后端用诸如ASP甚至C来拼接字符串来实现服务端渲染
和一些业务逻辑,而之后渐渐地将这个行为移动到前端,也就是在前端拼HTML字符串,一直到Js模板出现这种行为也不算少见。
虽然在三大框架流行的现在用Js来写Html似乎并不是什么难事,然而还请记住,说不准在哪个角落还有拼字符串来做前端渲染的公司
就像十八线开外的山区总有没通水通电的地方一般。
言归正传,即使是Js模板,其实大多数情况下核心依旧是操作字符串,只是在这里不再是拼接,而是用了更高大上,或者说实有而花哨的做法罢了。

//字符串操作基础
    //大小写转换
    var str= 'Tom'; var res=str.toLowerCase()//res输出:tom
    var res2=res.toUpperCase() //res 输出TOM
//大小写转换可以说是非常常用的操作,这对保证传入数据库的数据格式是否符合预期至关重要。
    //基础查找
    var str = 'apple'
    str.indexOf('p') //返回1
    str.lastIndexOf('p')//返回2
    str.indexOf('a') //返回-1
//indexOf可能是用的最多的查找方法了,它会查找一串字符串中是否存在某个值存在会返回第一个的下标,不存在则会返回-1,非常好用
    //基础查找2 metch
//这个方法我没用过,看起来和indexOf差不多,区别只是返回的是查找值本身,我也是刚翻w3cSchool发现还有这个方法的
    //替换
    var str = 'apple';
    var res = str.replace(/a/,'b') //res=bpple
//replace的第一个参数是正则,这使它能玩出很多花样。

再加个自身的属性length,w3cSchool上有关字符串的部分就结束了。
很简单对不对?然而,Js的字符串有个特点,从它有length这个属性就不难看出,其实它是一个类数组对象。
也就是说,数组上的方法它基本能用,但是有个问题,字符串不能被修改,只能被覆盖,也就是说不管你的修改多么微小
它都会修改整个字符串才能保存,这点和数组完全不一样,也是假如你要将数组的方法用在字符串上时需要注意的。
其它,如果你的正则表达式足够熟练,这里已经可以玩出很多花样来,
然而遗憾的是我正则向来是现用现查,所以这块在此按下不表。

数组操作

//数组转换为字符串: 
var str=arr.toString();  var str=arr.join("连接符") //连接符为空可无缝拼接
//嘛,数据处理是工作的一环
//数组拼接
    //不修改原数组
      arr.concat(arr,sr1,sr2,sr3) //将多个字符串拼接进数组并返回新数组 传入数组会打散再拼接
      arr.slice(starI,endI) //复制一段数组,返回新数组 ,从stari开始,endi结束
//这两个方法都不会修改原数组,对arr这个数组也不会有任何影响,而且如果不拿个变量接一下
//那么这两个操作就和不存在是一样的,所以其实通常使用这两个方法建议从Array中点
//也就是var resArr=Arrary.concat(arr,arr1,arr2,arr3)
    //修改原数组
    //arr.splice(starti,n,值1,值2) 从starti开始修改n位,值为空,删除,有值为替换,n为0插入
    var arr =[1,2,3,4,5];
    arr.splice(2,1) //arr=[1,2,4,5] 删除下标为2的
    arr.splice(2,0,a,4,5,6) //arr=[1,2,4,a,4,5,6,5,6] 下标2后插入
    arr.splice(3,3) //arr=[1,2,4,3,4,5,6,5,6] //下标3替换
//对数组的基本操作,作用嘛..数据处理是工作的一环
//排序
arr.reverse() //倒序 原数组改变
arr.sort()    //正序  (通过对比字符串的unidecod码实现,
//比较纯数字的时候需要传入比较函数(compareFunctin) 
//function(a,b){return a-b})//原数组改变
//核心:数组中比较两个值返回-1的时候停止,1的时候前者与后者交换位置

至此似乎没多少需要提的,Js中sort排序数量比较小的时候是冒泡排序,
数量上去了似乎是快速排序,效率上很高。排序都会修改原数组。
当然数组的操作方法现在才讲了一半,下面还有。

//栈和队列
//从尾部进入,排出  入:
    arr.push();//返回长度  
//出
    arr.pop();//返回排出数 //操作时剩余元素不会发生变化
//从头部进入,排出  入:
    arr.unshift();//返回长度  
//出
    arr.shift()//返回排出数 //操作时剩余元素会发生变化
//arr.push + arr.shift 模拟栈,后入先出 LIFO
//arr.unshift+arr.pop  模拟队列,先入先出 FIFO
//这块很有用,虽然很多时候我用到时都会去查笔记....
//缩容
    arr=[1,2,3] arr.length //3;
    arr.length-=1
    arr.length //2
    arr=[1,2];
//奇怪的操作..我反正没用过..
//看起来更高端的操作
//every 是否都符合要求
    var bool=arr.every(function(val,idx,arr){
        return 判断条件
    })

//some 是否包含符合要求的元素
    var bool=arr.some(function(val,idx,arr){
    return 判断条件
    })

//forEcah 对原数组中每个元素执行相同的操纵 直接修改原数组
    arr.forEach(function(val,idx,arr){
     对arr[idx]值做修改,无须return
    })

//map 对原数组中每个元素的值执行相同的操纵再生成新数组 原数组不变
arr.map(function(val,idx,arr){
    return 对[idx]值做修改
}) //不加return 和forEach作用相当
//例子:创建映射关系来改变排序。

var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];
// 对需要排序的数字和位置的临时存储var mapped = list.map(function(el, i) {
  return { index: i, value: el.toLowerCase() };})

// 按照多个值排序数组
mapped.sort(function(a, b) {
  return +(a.value > b.value) || +(a.value === b.value) - 1;});

// 根据索引得到排序的结果var result = mapped.map(function(el){
  return list[el.index];});  

//filter 过滤 原数组不变
var sub=arr.filter(function(var,idx,arr){
 return 判断条件
})
//上面都是很有用的操作,但是我几本只用过for each和map
//毕竟剩下的操作更像是这两个的语法糖,实践中,大多数时间基本想不起来有这个方法
//经过这次整理下次有应用场景了也许回来看一眼

数组的操作至此高一段落,剩下的,emmm,数字?算了吧..
来看看Date如何

Date操作

本想大大咧咧写个时间操作,画风都不一样了,还是来Date操作吧。
这方面我遇到最常见的操作就是上传的时候附上当前时间,或者展示的时候格式化下时间
题外话,Js在浏览器里的时间不大靠谱,从定时器就能看出来。
Js定时器比如你设置一个10s的定时器它并不是到10s执行,而是差不多到10s执行
为什么会这样呢?因为浏览器资源有限环境复杂,它不是在你执行定时器的时候开始计时的
而是浏览器利用空闲时间来进行的,忘记在哪看的了大概这个意思,也许不对,但结果来看差不了多远
看看定时器动画多容易出问题就知道了。
所以依赖前台来传当前时间是比较不靠谱的操作,大多数情况,时间还是以服务器为主。
毕竟你不知道运行网页的电脑时钟是不是和服务器上一致。

//其实我学Js的时候感觉Date操作又多又难记,但实际到应用中..我发现..
//最常用的只有两个
var time=new Date() //获得当前时间,会是标准格式
num = time.getTime() //获得1970年到这个时间点的一个毫秒数
//其它其实还有很多年月日操作,然而我几乎没用过,毕竟直接操作毫秒数要简单不少
//而绝大多数情况下数据库上存的也是毫秒数
var get = 1527144944436;
new Date(get) //输出标准时间格式
//这里需要注意传进去各种格式时间都能转换,问题在于,IOS..
//高版本不知道,低版本它并不支持标准时间格式,必须一个一个传
//这个时候如果后台反回时间格式字符串就只能无奈先处理字符串了
//其它
Date.prototype.Format = function(formatStr) {
    var str = formatStr;
    var Week = ['日', '一', '二', '三', '四', '五', '六'];
    str = str.replace(/yyyy|YYYY/, this.getFullYear());
    str = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : '0' + (this.getYear() % 100));
    str = str.replace(/MM/, (this.getMonth() + 1) > 9 ? (this.getMonth() + 1).toString() : '0' + (this.getMonth() + 1));
    str = str.replace(/M/g, (this.getMonth() + 1));
    str = str.replace(/w|W/g, Week[this.getDay()]);
    str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate());
    str = str.replace(/d|D/g, this.getDate());
    str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : '0' + this.getHours());
    str = str.replace(/h|H/g, this.getHours());
    str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : '0' + this.getMinutes());
    str = str.replace(/m/g, this.getMinutes());
    str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : '0' + this.getSeconds());
    str = str.replace(/s|S/g, this.getSeconds());
    return str
}
//上面是一个常见的时间格式化函数..网上搜到的大多数版本都是这个..
//实践中也还好用..我曾经见过拼接字符串来格式化的..
//不用说..拼接字符串来处理时间总是有奇奇怪怪Bug发生的可能

时间差不多就到此为止吧,会取时间戳,基本大多数需求就都能做了。
剩下你需要的就是一个加班一周还能计算时间间隔的大脑。

其它基本操作

差不多要结束了..
剩下的基本操作:数字,Json,RegExp
放一起说,数字,最常见的就是加减乘除,需要注意的就是取整问题。
科学计算不在讨论范围,基本上一篇提过了,在此不再赘述。

//JSON
var obj={a:1}
var str = JSON.stringify(obj) //转JSON字符串
var obj2 = JSON.parse(str) //转回对象

通常会这个就够了,传输的时候转成JSON字符串,接收的时候转回来。
后端是NodeJs或者有NodeJs这一层时通常JSON字符串会自动解析成对象。
但也有例外,我暂时不知为何,调试的时候输出出来看看再调整也不费事就是了。

//RegExp
//严肃的说,正则表达式的书写和使用可以出一本书,然而我不是很会写正则
//但是我会用
var patt1=new RegExp("e"); //创建一个正则;当然 /e/ 这样也可以
patt1.test('str') //测试是否符合返回 true false
patt1.exec() //检索,存在返回检索值,不存在返回Null..通常我选择indexOf
patt1.compile() //替换,然而我选择replace();

好了,关于正则的书写,还是得找本书来看,然后大量练习。
这个东西更像是语法,略为枯燥,我个人是多次捡起来然后又忘掉。
所幸实际开发中没遇到太复杂的,要么搜个现场的,要么一边学一边做...
其它..DOM操作...

//DOM树的5个API:
walker.parentNode();
walker.firstChild();
walker.lastChild();
walker.previousNode();
walker.nextNode();

//节点树的API:
parentElementNode();
firstElementChild();
lastElementChild();
previousElementNode();
nextElementNode();
//上面这些除了学习的时候用过,就再也没用过了..
//查找操作
// 1.按id查找一个元素
var elem=document.getElementById("id");
// 2.按标签名查找多个元素
var elem=parent.getElementsByTagName("标签名");
//  3.按name属性查找多个元素
var elem=parent.getElementsByName("name");
//  4.按class属性查找多个属性
var elem=parent.getElementsByClassName("class");
//  5.按选择器查找一个元素
var elem=parent.querySelector("selector");
//  6.按选择器查找多个元素
var elem=parent.querySelectorAll("selector");
//上面属于背的滚瓜烂熟也再也没用过的...我选择Jq
//或者...
function $('select'){
    var elem=parent.querySelectorAll("selector");
    return elem
}
//其它还有添加删除DOM节点和修改样式..添加删除,简单粗暴修改html,样式修改粗暴简单修改style..

上面这些DOM操作照理说应该是前端学习JavaScript最重要的部分,然而从我工作至今几乎很少有用到的时候。
三大框架自不用说,在有Jq的情况下,这些都是时代的眼泪了...

结语

这次复习了大多数常见的JavaScript Api意外的比我想象中的早结束。
可见随着实际开发的应用即使不愿意你也会记住。
虽是老生常谈,找个东西做做,提升相对要快些。
所谓光说不练假把式。
其它能算入门应该掌握的东西...emmmm...
基于原型的继承?面向对象?函数式编程?设计模式?
我个人来说,面向对象的写法就足够满足当前的工作需求的同时,还足够好看。
其它,JavaScript还有的就是一些,不想懂也不需要懂的奇怪特性...
这块建议踩到坑了再去解决..随着踩得坑的增多,就能切实的感受到自己的变强。
前两天看到一本,你不懂的JavaScript,没有细看,不过的确很多在现场踩到的坑都有提及
虽然我很想把它改名为你不需要懂的JavaScript..然而真遇到问题了,这套书还是很可靠的。
所幸这套书开源且有电子版,遇到什么奇奇怪怪的问题时去临时抱个佛脚似乎也是一幸。

评论

This is just a placeholder img.