我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何让你的JS写得更漂亮

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何让你的JS写得更漂亮

本篇内容介绍了“如何让你的JS写得更漂亮”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1. 按强类型风格写代码

JS是弱类型的,但是写代码的时候不能太随意,写得太随意也体现了编码风格不好。下面分点说明:

(1)定义变量的时候要指明类型,告诉JS解释器这个变量是什么数据类型的,而不要让解释器去猜,例如不好的写法:

var num,
 str,
 obj;

声明了三个变量,但其实没什么用,因为解释器不知道它们是什么类型的,好的写法应该是这样的:

var num = 0,
 str = '',
 obj = null;

定义变量的时候就给他一个默认值,这样不仅方便了解释器,也方便了阅读代码的人,他会在心里有数——知道这些变量可能会当作什么用。

在这里小编建了一个前端学习交流扣扣群:132667127,我自己整理的最新的前端资料和高级开发教程,如果有想需要的,可以加群一起学习交流

(2)不要随意地改变变量的类型,例如下面代码:

var num = 5;
num = "-" + num;

第1行它是一个整型,第2行它变成了一个字符串。因为JS最终都会被解释成汇编的语言,汇编语言变量的类型肯定是要确定的,你把一个整型的改成了字符串,那解释器就得做一些额外的处理。并且这种编码风格是不提倡的,有一个变量第1行是一个整型,第10行变成了一个字符串,第20行又变成了一个object,这样就让阅读代码的人比较困惑,上面明明是一个整数,怎么突然又变成一个字符串了。好的写法应该是再定义一个字符串的变量:

var num = 5;
var sign = "-" + num;

(3)函数的返回类型应该是要确定的,例如下面不确定的写法:

function getPrice(count){
 if(count < 0) return "";
 else return count * 100;
}

getPrice这个函数有可能返回一个整数,也有可能返回一个空的字符串。这样写也不太好,虽然它是符合JS语法的,但这种编码风格是不好的。使用你这个函数的人会有点无所适从,不敢直接进行加减乘除,因为如果返回字符串进行运算的话值就是NaN了。函数的返回类型应该是要确定的,如下面是返回整型:

function getPrice(count){
 if(count < 0) return -1;
 else return count * 100;
}

然后告诉使用者,如果返回-1就表示不合法。如果类型确定,解释器也不用去做一些额外的工作,可以加快运行速度。

如何让你的JS写得更漂亮

2. 减少作用域查找

(1)不要让代码暴露在全局作用域下

例如以下运行在全局作用域的代码:

<script>
 var map = document.querySelector("#my-map");
 map.style.height = "600px";
</script>

有时候你需要在页面直接写一个script,要注意在一个script标签里面,代码的上下文都是全局作用域的,由于全局作用域比较复杂,查找比较慢。例如上面的map变量,第二行在使用的时候,需要在全局作用域查找一下这个变量,假设map是在一个循环里面使用,那可能就会有效率问题了。所以应该要把它搞成一个局部的作用域:

<script>
!function(){
 var map = document.querySelector("#my-map");
 map.style.height = "600px";
}()
</script>

上面用了一个function制造一个局部作用域,也可以用ES6的块级作用域。由于map这个变量直接在当前的局部作用域命中了,所以就不用再往上一级的作用域(这里是全局作用域)查找了,而局部作用域的查找是很快的。同时直接在全局作用域定义变量,会污染window对象。

(2)不要滥用闭包

闭包的作用在于可以让子级作用域使用它父级作用域的变量,同时这些变量在不同的闭包是不可见的。这样就导致了在查找某个变量的时候,如果当前作用域找不到,就得往它的父级作用域查找,一级一级地往上直到找到了,或者到了全局作用域还没找到。因此如果闭包嵌套得越深,那么变量查找的时间就越长。如下:

function getResult(count){
 count++;
 function process(){
 var factor = 2;
 return count * factor - 5;
 }
 return process();
}

上面的代码定义了一个process函数,在这个函数里面count变量的查找时间要高于局部的factor变量。其实这里不太适合用闭包,可以直接把count传给process:

function getResult(count){
 count++;
 function process(count){
 var factor = 2;
 return count * factor - 5;
 }
 return process(count);
}

这样count的查找时间就和factor一样,都是在当前作用域直接命中。这个就启示我们如果某个全局变量需要频繁地被使用的时候,可以用一个局部变量缓存一下,如下:

var url = "";
if(window.location.protocal === "https:"){
 url = "wss://xxx.com" + window.location.pathname + window.location.search;
}

频繁地使用了window.location对象,所以可以先把它缓存一下:

var url = "";
var location = window.location;
if(location.protocal === "https:"){
 url = "wss://xxx.com" + location.pathname + location.search;
}

搞成了一个局变变量,这样查找就会明显快于全局的查找,代码也可以写少一点。

如何让你的JS写得更漂亮

3. 避免==的使用

这里你可能会有疑问了,有些人喜欢用==,有些人喜欢用===,大家的风格不一样,你为什么要强制别人用===呢?习惯用==的人,不能仅仅是因为==比===少敲了一次键盘。为什么不提倡用==呢?

(1)如果你确定了变量的类型,那么就没必要使用==了,如下:

if(typeof num != "undefined"){
} 
var num = parseInt(value);
if(num == 10){
}

上面的两个例子都是确定类型的,一个是字符串,一个是整数。就没必要使用==了,直接用===就可以了。

(2)如果类型不确定,那么应该手动做一下类型转换,而不是让别人或者以后的你去猜这里面有类型转换,如下:

var totalPage = "5";
if(parseInt(totalPage) === 1){
}

(3)使用==在JSLint检查的时候是不通过的:

if(a == b){
}

如下JSLint的输出:

Expected ‘===’ and instead saw ‘==’. if(a == b){

(4)并且使用==可能会出现一些奇怪的现象,这些奇怪的现象可能会给代码埋入隐患:

null == undefined //true
'' == '0' //false
0 == '' //true
0 == '0' //true
'
 ' == 0 //true
new String("abc") == "abc" //true
new Boolean(true) == true //true
true == 1 //true

上面的比较在用===的时候都是false,这样才是比较合理的。例如第一点null居然会等于undefined,就特别地奇怪,因为null和undefined是两个毫无关系的值,null应该是作为初始化空值使用,而undefined是用于检验某个变量是否未定义。

这和第1点介绍强类型的思想是相通的。

4. 合并表达式

如果用1句代码就可以实现5句代码的功能,那往往1句代码的执行效率会比较高,并且可读性可能会更好

(1)用三目运算符取代简单的if-else

如上面的getPrice函数:

function getPrice(count){
 if(count < 0) return -1;
 else return count * 100;
}

可以改成:

function getPrice(count){
 return count < 0 ? return -1 : count * 100;
}

这个比写一个if-else看起来清爽多了。当然,如果你写了if-else,压缩工具也会帮你把它改三目运算符的形式:

function getPrice(e){return 0>e?-1:100*e}

(2)连等

连等是利用赋值运算表达式会返回所赋的值,并且执行顺序是从右到左的,如下:

overtime = favhouse = listingDetail = {...}

有时候你会看到有人这样写:

var age = 0;
if((age = +form.age.value) >= 18){
 console.log("你是成年人");
} else {
 consoe.log("小朋友,你还有" + (18 - age) + "就成年了");
}

也是利用了赋值表达式会返回一个值,在if里面赋值的同时用它的返回值做判断,然后else里面就已经有值了。上面的+号把字符串转成了整数。

(3)自增

利用自增也可以简化代码。如下,每发出一条消息,localMsgId就自增1:

chatService.sendMessage(localMsgId++, msgContent);

5. 减少魔数

例如,在某个文件的第800行,冒出来了一句:

dialogHandler.showQuestionNaire("seller", "sell", 5, true);

就会让人很困惑了,上面的四个常量分别代表什么呢,如果我不去查一个那个函数的变量说明就不能够很快地意会到这些常量分别有什么用。这些意义不明的常量就叫“魔数”。

所以最好还是给这些常量取一个名字,特别是在一些比较关键的地方。例如上面的代码可改成:

var naireType = "seller",
 dialogType = "sell",
 questionsCount = 5,
 reloadWindow = true;
naireHandler.showNaire(naireType, dialogType, questionsCount, reloadWindow);

这样意义就很明显了。

6. 使用ES6简化代码

ES6已经发展很多年了,兼容性也已经很好了。恰当地使用,可以让代码更加地简洁优雅。

(1)使用箭头函数取代小函数

有很多使用小函数的场景,如果写个function,代码起码得写3行,但是用箭头函数一行就搞定了,例如实现数组从大到小排序:

var nums = [4, 8, 1, 9, 0];
nums.sort(function(a, b){
 return b - a;
});
//输出[9, 8, 4, 1, 0]

如果用箭头函数,排序只要一行就搞定了:

var nums = [4, 8, 1, 9, 0];
nums.sort(a, b => b - a);

代码看起来简洁多了,还有setTimeout里面经常会遇到只要执行一行代码就好了,写个function总感觉有点麻烦,用字符串的方式又不太好,所以这种情况用箭头函数也很方便:

setTimeout(() => console.log("hi"), 3000)

箭头函数在C++/Java等其它语言里面叫做Lambda表达式,Ruby比较早就有这种语法形式了,后来C++/Java也实现了这种语法。

当然箭头函数或者Lambda表达式不仅适用于这种一行的,多行代码也可以,不过在一行的时候它的优点才比较明显。

(2)使用ES6的class

虽然ES6的class和使用function的prototype本质上是一样的,都是用的原型。但是用class可以减少代码量,同时让代码看起来更加地高大上,使用function要写这么多:

function Person(name, age){
 this.name = name;
 this.age = age;
}
Person.prototype.addAge = function(){
 this.age++;
};
Person.prototype.setName = function(name){
 this.name = name;
};

使用class代码看加地简洁易懂:

class Person{
 constructor(name, age){
 this.name = name;
 this.age = age;
 }
 addAge(){
 this.age++;
 }
 setName(name){
 this.name = name;
 }
}

并且class还可以很方便地实现继承、静态的成员函数,就不需要自己再去通过一些技巧去实现了。

(3)字符串拼接

以前要用+号拼接:

var tpl = 
 '<div>' + 
 ' <span>1</span>' +
 '</div>';

现在只要用两个反引号“`”就可以了:

var tpl = 
` <div>
 <span>1</span>
 </div>
`;

另外反引号还支持占位替换,原本你需要:

var page = 5,
 type = encodeURIComponet("#js");
var url = "/list?page=" + page + "&type=" + type;

现在只需要:

var url = `/list?page=${page}&type=${type}`;

就不用使用+号把字符串拆散了。

(4)块级作用域变量

块级作用域变量也是ES6的一个特色,下面的代码是一个任务队列的模型抽象:

var tasks = [];
for(var i = 0; i < 4; i++){
 tasks.push(function(){
 console.log("i is " + i);
 });
}
for(var j = 0; j < tasks.length; j++){
 tasks[j]();
}

但是上面代码的执行输出是4,4,4,4,并且不是想要输出:0,1,2,3,所以每个task就不能取到它的index了,这是因为闭包都是用的同一个i变量,i已经变成4了,所以执行闭包的时候就都是4了。那怎么办呢?可以这样解决:

var tasks = [];
for(var i = 0; i < 4; i++){
 !function(k){
 tasks.push(function(){
 console.log("i is " + k);
 });
 }(i);
}
for(var j = 0; j < tasks.length; j++){
 tasks[j]();
}

把i赋值给了k,由于k它是一个function的一个参数,每次执行函数的时候,肯定会实例化新的k,所以每次的k都是不同的变量,这样就输出就正常了。

但是代码看起来有点别扭,如果用ES6,只要把var改成let就可以了:

var tasks = [];
for(let i = 0; i <= 4; i++){
 tasks.push(function(){
 console.log("i is " + i);
 });
}
for(var j = 0; j < tasks.length; j++){
 tasks[j]();
}

只改动了3个字符就达到了目的。因为for循环里面有个大括号,大括号就是一个独立的作用域,let定义的变量在独立的作用域里面它的值也是独立的。当然即使没写大括号for循环执行也是独立的。

除了以上几点,ES6还有其它一些比较好用的功能,如Object的assign,Promise等,也是可以帮助写出简洁高效的代码。

“如何让你的JS写得更漂亮”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何让你的JS写得更漂亮

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

码如其人,小老弟,你能写一手漂亮的Py

与多数现代编程语言一样,在 Python 中,函数是抽象和封装的基本方法之一。你在开发阶段或许已经写过数百个函数,但并非每个函数都生而平等。写出「糟糕的」函数会直接影响代码的可读性和可维护性。那么,什么样的函数是「糟糕的」函数呢?更重要的是
2023-01-31

如何让你的Linux终端变得酷炫复古

这篇文章给大家分享的是有关如何让你的Linux终端变得酷炫复古的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。怀旧?那就安装复古终端应用程序 cool-retro-term 吧 —— 顾名思
2023-06-15

如何才能让你的网站更加优秀

小编给大家分享一下如何才能让你的网站更加优秀,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!  首页设计必须要吸引眼球,如果用户们在进入到你的网站中,第一眼就很有好
2023-06-10

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录