本篇文章围绕JS代码的健壮性、可读性、可复用性和可拓展性,四个方面做简单描述。
简单说,健壮性就是指代码抗击风险的能力。(例如:项目中出现一个错误,不至于导致整个项目瘫痪。)
function a(type){
var obj = {
data1:[1,2,3],
data2:[4,5,6]
}
return obj[type][2];
}
//函数a是我们写的一个程序,如果我们调用(执行)a函数时,不传入参数导致出错,程序中断执行(“不传入参数”就是和程序无关的因素)。
function b(num1,num2){
return num1+num2;
}
var num = b(); //num值为NaN(不是一个数字)
//假设我们的函数b是一个第三方的功能插件,我们需要的结果是一个数字,而上述代码中,它返回一个NaN程序是不会自动报错的,那我们后续一些操作中由于NaN导致报错的话,这个问题查找起来就会耽误一些时间。
//main.js内
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
throw new Error(); //假设这里抛出的错误不受我们控制,是使用的一个第三方插件抛出的错误;这个错误导致页面白屏(程序中断执行)。
new Vue({
render: h => h(App),
}).$mount('#app')
//上例中,因为一个第三方插件抛出的一个错误就导致我们的程序中断执行,这显然不是我们所希望看到的。
例如:我们上面2.1的函数a,我们就可以给参数type一个默认值来保障健壮性。
function a(type = "data1"){ //给参数type设置默认值为data1
//var type = type || "data1"; //这种方式也是给参数type设置默认值为data1
var obj = {
data1:[1,2,3],
data2:[4,5,6]
}
return obj[type][2];
}
//函数a是我们写的一个程序,如果我们调用(执行)a函数时,不传入参数导致出错,程序中断执行(“不传入参数”就是和程序无关的因素)。
//举一反三———在我们的实际操作中,我们可能还会遇到传入的参数是一个对象,并且这个对象中的某一个属性是必需存在的。
function a(obj){
//var obj.name= obj.name || "Xiao Ming"; //当参数obj对象下只有name属性是必须存在时
var _obj = { //当参数obj对象下有多个属性是必须存在时
name: "Xiao Ming",
phone: "13100008888"
}
for (var item in obj) {
_obj[item] = obj[item] || _obj[item];
}
}
我们上面2.2的函数b,其两个参数num1和num2是两个必填参数,如果是给其设置默认值,则该函数变没有了意义,这种情况我们可以主动抛出错误来提示使用者。
function b(num1,num2){
if(typeof num1 != 'number' || num2 != 'number') { //判断 如果num1和num2中有一个或都不是number数据类型,则抛出错误提示
throw new Error("num1 or num2 must be a number");
}
return num1+num2;
}
var num = b(); //num值为NaN(不是一个数字)
//假设我们的函数b是一个第三方的功能插件,我们需要的结果是一个数字,而上述代码中,它返回一个NaN程序是不会自动报错的,那我们后续一些操作中由于NaN导致报错的话,这个问题查找起来就会耽误一些时间。
判断某个对象是不是一个类的实例,可使用 instanceof 来判断。
例如:我们上面2.3的报错,我们就可以用 try{ }catch(err){ } 来包裹。
//main.js内
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
try { //用 try{ }catch(err){ } 来包裹,错误就不会
throw new Error();
} catch (err) {
console.log(err);
}
new Vue({
render: h => h(App),
}).$mount('#app')
//上例中,因为一个第三方插件抛出的一个错误就导致我们的程序中断执行,这显然不是我们所希望看到的。
可读性就是代码阅读起来很清楚。
1. if-else分支过长。(可采用策略模式和状态模式进行优化,后面设计模式的部分会详细介绍)
//示例
if (xx) {
}else if (xxx) {
}else if (yyy) {
}
2. 分支套分支。(可采用与或非的联合逻辑表达符来优化)
//示例
if (xx) {
if (xxx) {
if (yyy) {
}
}
}
//采用与或非的联合逻辑表达符来优化
if (xx && xxx && yyy){
}
3. 回调地狱。(可采用 promise , async 进行优化,后面异步编程的部分会详细介绍)
$.ajax({
url:"/api/xxx",
success: function () {
$.ajax({
url:"/api/xxx",
success: function () {
$.ajax({
url:"/api/xxx",
success: function () {
}
})
}
})
}
})
开发中,大家约定俗成的一些命名规范。
1. 常量全大写;
const PIE = 3.1415926;
2. 类名首字母大写;
function ClassSchool() {
}
3. 普通变量和方法,小驼峰的形式(首字母小写);
var name = 'Xiao Ming';
function getList() {
}
4. 局部变量下划线开头;
function getList() {
var _sum = 0;
}
5. 遵循语义化; (先起个中文名字,在通过翻译软件转译成英文。)
注释方案,按照团队规定执行就可。
可复用性就是代码像积木一样,能够很方便的哪里需要去哪里。
1. 采用设计模式(桥接模式、享元模式);
2. 函数式编程;
3. 低耦合,高内聚;
可拓展性就是代码应对以后的变更,可以不用大规模的改动。
革命尚未成功,同志仍需努力。