JS学习(一)

JS学习(一)

标签: 前端 js

背景描述:

JavaScript是世界上最流行的脚本语言,因为你在电脑、手机、平板上浏览的所有的网页,以及无数基于HTML5的手机App,交互逻辑都是由JavaScript驱动的。

简单地说,JavaScript是一种运行在浏览器中的解释型的编程语言。

那么问题来了,为什么我们要学JavaScript?尤其是当你已经掌握了某些其他编程语言如Java、C++的情况下。

简单粗暴的回答就是:因为你没有选择。在Web世界里,只有JavaScript能跨平台、跨浏览器驱动网页,与用户交互。

Flash背后的ActionScript曾经流行过一阵子,不过随着移动应用的兴起,没有人用Flash开发手机App,所以它目前已经边缘化了。相反,随着HTML5在PC和移动端越来越流行,JavaScript变得更加重要了。并且,新兴的Node.js把JavaScript引入到了服务器端,JavaScript已经变成了全能型选手。

JavaScript一度被认为是一种玩具编程语言,它有很多缺陷,所以不被大多数后端开发人员所重视。很多人认为,写JavaScript代码很简单,并且JavaScript只是为了在网页上添加一点交互和动画效果。

但这是完全错误的理解。JavaScript确实很容易上手,但其精髓却不为大多数开发人员所熟知。编写高质量的JavaScript代码更是难上加难。

一个合格的开发人员应该精通JavaScript和其他编程语言。如果你已经掌握了其他编程语言,或者你还什么都不会,请立刻开始学习JavaScript,不要被Web时代所淘汰。

​ --- 廖雪峰js教程

1.ES6新特性

ES6的模板字符串写法令我很感兴趣。

在没有ES6新特性之前,使用js拼接字符串是这样的:

var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '岁了!';
alert(message);

如果你想换行,还要加上转义字符:

var name = '小明';
var age = 20;
var message = '你好, \n' + name + ', 你今年\n' + age + '岁了!';
alert(message);	

可ES6允许你使用以下写法:

var name = '小明';
var age = 20;
alert(`你好
${name},你今年
${age}岁了`);

这一下就让代码极其清晰易懂。

以上只是一个简单的事例,还看不出它的好处。我举一个我工作中遇到的问题,这是我接手的之前人写的代码(安全起见,变量名全部换为xx):

var xx = data.xx.id;
var xx = data.xx;
var xx = data.xx;
var result = '<a class="tdbut" onclick="xx(\'' + id + '\',\'' + workFlowId + '\');">查看(' + xx + ')</a>&nbsp;' +
    '<input type="button" class="tdbut" value="打印" onclick="xx(\'' + id + '\')"/>&nbsp;';

if (xx == 10 && xx == xx) {
    result = result +
        '<a class="tdbut" onclick="xx(\'' + id + '\',\'' + xx + '\');">派发</a>&nbsp;';
}
if (xx == 20 && xx == xx && xx == 0) {
    result = result +
        '<a class="tdbut" onclick="xx(\'' + id + '\',\'' + xx + '\');">派发</a>&nbsp;';
}

这是一个在jsp中使用ajax请求服务器,并根据返回结果在页面中添加按钮的方法。

这个玩意能看懂啥意思,但是这些拼接看起来让人恶心,写这种玩意的时候,需要注意太多的单引号双引号匹配,少写一个就要出错。想象一下,假如你要修改这个函数,需要增加一个参数,是一个多么恶心的事情。更离谱的是:像这种代码有几百行!!

如果使用ES6,可以改成这样:

var xx = data.xx.id;
var xx = data.xx;
var xx = data.xx;
var result = `<a class="tdbut" onclick="xx('${id}', '${xx}')">查看('${name}')</a>&nbsp;`;
if (xx == 10 && xx == xx) {
    result = result +`<a class="tdbut" onclick="xx('${id}', '${xx}')">派发('${name}')</a>&nbsp;`;
}
if (xx == 20 && xx == xx && xx == 0) {
    result = result +`<a class="tdbut" onclick="xx('${id}', '${xx}')">派发('${name}')</a>&nbsp;`;
}

瞬间感觉舒服了。

不要感觉代码能正常运行就好了,写的好不好看无所谓。每一份代码大概率需要迭代和维护的,你开发的时候多花一份心思写一份结构清晰、风格优美的代码,可以为你日后维护升级剩下大量的精力。

有时候你为了早点下班,匆匆忙忙写了一份未经思考的代码。也许现在轻松,但是高耦合、混乱的逻辑、恶劣的编码风格一定会让你在日后的工作中付出成倍的代价。

实在忍不住吐槽一下以下编码风格,你们是吃奥利给吃多了吗?:

  • 一个类写几千行,一个方法写上大几百行
当你维护这种狗屁玩意的时候,你需要花一两个小时去看他到底写了个什么狗屁逻辑。
  • 变量名使用拼音或者英文拼音结合
你TM活在10年前搞开发呢?你写的这种狗屁变量很难让人理解这个玩意。TM英语不好,你不会搜索一下?
  • jsp中js代码与EL表达式混着写:
<script>
var a = ${id}
</script>

呵呵,告诉你,你把数据库连接写在jsp中都行,你怎么不写?springmvc框架分离的已经很完美了,你就是要强行增加耦合!就是要让代码看的麻烦!就因为你懒得增加一个标识。

  • 魔法值和无穷无尽的if嵌套,尤其是当这两者结合到一起的时候,短短几行代码就会花费你一上午的时间去找这些变量。
public void test(int a, int b, int c){
	if(a == 1){
        if(b == 1){
            //TODO
        }else if(b == 2){
            if(c == 2){
				//TODO
            }else{
				//TODO
            }
        }else if(b == 3){
				//TODO
        }else{
            if(c == 3){
				//TODO
            }else{
				//TODO
            }
        }
        }
	} 

上面这个代码我真的遇到过,我真是佩服他在提高代码阅读难度上的强悍能力。奥利给吃多了的典型。兄弟们,你们觉得以下的代码,写起来很麻烦吗:

private static final int PROJECT_NUM = 1;
private static final int SUBJECT_NUM = 2;
private static final int PEOPLE_NUM = 3;

public void test(int projectNum, int subjectNum, int peopleNum){
    if(projectNum != PROJECT_NUM){
        //TODO
        return;
    }
    if(subjectNum == PROJECT_NUM){
       //TODO
       return;
    }
    if(subjectNum == SUBJECT_NUM){
       if(peopleNum == SUBJECT_NUM){
           //TODO
       	   return;
       }
       if(peopleNum != SUBJECT_NUM){
           //TODO
       	   return;
       }
    }
    if(subjectNum == PEOPLE_NUM){
       //TODO
       return;
    }
    if(peopleNum == PEOPLE_NUM){
		//TODO
        return;
    }else{
		//TODO
        return;
    }
  • 爱用try...catch,但是不捕获异常
求你了,做个人吧。你不用try...catch,至少还能由系统捕获异常,你写个try不处理异常,出了问题就得一行行的debug。

2.ES6兼容性

ES6新特性很好很美妙,遗憾的是它提出的较晚,一些浏览器不兼容他:没错就是你,终极恶心浏览器IE系列。我们项目都要求兼容IE9及以上,我就得研究一手ES6如何兼容IE。

参考以下博客:

Babel下的ES6兼容性与规范

教你如何快速让浏览器兼容ES6特性

[babel通过script标签引入无法解决低版本的ie兼容es6的问题(非解决方案,谈下遇到的坑)]

主要记录下我的使用体验:

2.1执行顺序

浏览器解析js都是顺序执行的,但是如果你的html中既有普通的js代码块,又有ES6代码块:

<script src="browser.min.js"></script>
<script>
    alert('before');
</script>
<script type="text/babel">
    const label = `张三爱`;
    function test(){
        var name = '李四';
        const Name = `张三爱${name}`;
        alert(Name);
    }
    test();
</script>
<script>
    alert('after');
</script>

按照写的顺序,我以为应该是:

打印(before)---> 打印(张三爱李四) ---> 打印(after)

但实际的执行情况是,type="text/babel"的代码块会在所有普通代码块执行之后执行:

打印(before)---> 打印(after) ---> 打印(张三爱李四)

所以兄弟们如果想在自己的旧项目中兼容ES6,需要考虑这个问题。

2.2变量范围

  • 在js中,变量的定义并不是以代码块作为作用域的,而是以函数作为作用域。也就是说,如果变量是在某个函数中定义的,那么,它在函数以外的地方是不可见的。但是,如果该变量是定义在if或者for这样的代码块中,它在代码块之外是可见的。

  • 在js中,术语“全局变量”指的是定义在所有函数之外的变量(也就是定义在全局代码中的变量),与之相对的是“局部变量”,所指的是在某个函数中定义的变量。其中,函数内的代码可以像访问自己的局部变量那样访问全局变量,反之则不行:

<script>
var label = '张三爱';
alert('before');
</script>
<script>
alert('after');
alert(label);
</script>

像这种就可以正常执行。

但是使用了babel解决兼容性问题的代码作用域就会局限在代码块中(我自己尝试的,没有找到官方说法),像以下代码:

<script src="browser.min.js"></script>
<script type="text/babel">
    const label = `张三爱${name}`;
    function test(){
    var name = '李四';
    const Name = `张三爱${name}`;
    alert(Name);
    }
    test();
</script>
<script type="text/babel">
    alert('before');
    test();
</script>
<script type="text/babel">
    alert('after');
    alert(label);
</script>

label常亮和test()函数是无法在其他代码块中调用的。

上述结果可能和babel重新编译代码有关,真正的原因目前没有深入探究。

2.3和后端渲染语法冲突

没错,ES6使可以使用${}拼接字符串,这显然和jsp的EL表达式冲突,也和freemaker冲突。为了避免这个冲突,在jsp中,你就得写这样写:

var data = 'xx';
var messag = `操作成功,${'${data}'}!`;

这样看起来也很nc,而且增加了耦合,实在是。。。。。。

3总结

鉴于上述缺陷,我还是没有在项目中使用这个新特性。但是这方面的知识不能放弃学。

有以下四个原因:

  • 随着浏览器的更新迭代,支持ES6必然成为主流
  • 如果启动一个新项目,可以使所有代码块都使用babel,可以避免缺陷2.1
  • 前后端分离的项目,可以避免缺陷2.3
  • 兼容ES6还有其他方法,我目前只尝试了babel,还没研究缺陷2.2如何解决。。。。。。
posted @ 2020-04-01 19:21  海森堡不如我侧的准  阅读(213)  评论(0)    收藏  举报