编程语言Javascript代码怎么写?

    作者:课课家教育更新于: 2019-09-24 15:59:36

    大神带你学编程,欢迎选课

    如何写出优雅耐看的Javascript代码。编程语言(programming language)是一种被标准化的交流技巧,用来向计算机发出指令,定义计算机程序,让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动的一种计算机语言。编程语言可以分成机器语言、汇编语言、高级语言三大类。

    计算机领域已发明了上千不同的编程语言,而且每年仍有新的编程语言诞生。

    前言

    在我们平时的工作开发中,大多数都是大人协同开发的公共项目;在我们平时开发中代码codeing的时候我们考虑代码的可读性、复用性和扩展性。

    干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。

    编程语言Javascript代码怎么写_编程语言_Java_Javascript_课课家

    我们从以下几个方面进行探讨:

    变量

    1、变量命名

    一般我们在定义变量是要使用有意义的词汇命令,要做到见面知义

    1. //bad code 
    2. const yyyymmdstr = moment().format('YYYY/MM/DD'); 
    3. //better code 
    4. const currentDate = moment().format('YYYY/MM/DD'); 

    2、可描述

    通过一个变量生成了一个新变量,也需要为这个新变量命名,也就是说每个变量当你看到他第一眼你就知道他是干什么的。

    1. //bad code 
    2. const ADDRESS = 'One Infinite Loop, Cupertino 95014'
    3. const CITY_ZIP_CODE_REGEX = /^[^,\\\\]+[,\\\\\\s]+(.+?)\\s*(\\d{5})?$/; 
    4. saveCityZipCode(ADDRESS.match(CITY_ZIP_CODE_REGEX)[1], ADDRESS.match(CITY_ZIP_CODE_REGEX)[2]); 
    5.  
    6. //better code 
    7. const ADDRESS = 'One Infinite Loop, Cupertino 95014'
    8. const CITY_ZIP_CODE_REGEX = /^[^,\\\\]+[,\\\\\\s]+(.+?)\\s*(\\d{5})?$/; 
    9. const [, city, zipCode] = ADDRESS.match(CITY_ZIP_CODE_REGEX) || []; 
    10. saveCityZipCode(city, zipCode); 

    3、形参命名

    在for、forEach、map的循环中我们在命名时要直接

    1. //bad code 
    2. const locations = ['Austin''New York''San Francisco']; 
    3. locations.map((l) => { 
    4.   doStuff(); 
    5.   doSomeOtherStuff(); 
    6.   // ... 
    7.   // ... 
    8.   // ... 
    9.   // 需要看其他代码才能确定 'l' 是干什么的。 
    10.   dispatch(l); 
    11. }); 
    12.  
    13. //better code 
    14. const locations = ['Austin''New York''San Francisco']; 
    15. locations.forEach((location) => { 
    16.   doStuff(); 
    17.   doSomeOtherStuff(); 
    18.   // ... 
    19.   // ... 
    20.   // ... 
    21.   dispatch(location); 
    22. }); 

    4、避免无意义的前缀

    例如我们只创建一个对象是,没有必要再把每个对象的属性上再加上对象名

    1. //bad code 
    2. const car = { 
    3.   carMake: 'Honda'
    4.   carModel: 'Accord'
    5.   carColor: 'Blue' 
    6. }; 
    7.  
    8. function paintCar(car) { 
    9.   car.carColor = 'Red'
    10.  
    11. //better code 
    12. const car = { 
    13.   make: 'Honda'
    14.   model: 'Accord'
    15.   color: 'Blue' 
    16. }; 
    17.  
    18. function paintCar(car) { 
    19.   car.color = 'Red'

    5、默认值

    1. //bad code 
    2. function createMicrobrewery(name) { 
    3.   const breweryName = name || 'Hipster Brew Co.'
    4.   // ... 
    5.  
    6. //better code 
    7. function createMicrobrewery(name = 'Hipster Brew Co.') { 
    8.   // ... 

    函数

    1、参数

    一般参数多的话要使用ES6的解构传参的方式

    1. //bad code 
    2. function createMenu(title, body, buttonText, cancellable) { 
    3.   // ... 
    4.  
    5. //better code 
    6. function createMenu({ title, body, buttonText, cancellable }) { 
    7.   // ... 
    8.  
    9. //better code 
    10. createMenu({ 
    11.   title: 'Foo'
    12.   body: 'Bar'
    13.   buttonText: 'Baz'
    14.   cancellable: true 
    15. }); 

    2、单一化处理

    一个方法里面最好只做一件事,不要过多的处理,这样代码的可读性非常高

    1. //bad code 
    2. function emailClients(clients) { 
    3.   clients.forEach((client) => { 
    4.     const clientRecord = database.lookup(client); 
    5.     if (clientRecord.isActive()) { 
    6.       email(client); 
    7.     } 
    8.   }); 
    9.  
    10. //better code 
    11. function emailActiveClients(clients) { 
    12.   clients 
    13.     .filter(isActiveClient) 
    14.     .forEach(email); 
    15. function isActiveClient(client) { 
    16.   const clientRecord = database.lookup(client);     
    17.   return clientRecord.isActive(); 

    3、对象设置默认属性

    1. //bad code 
    2. const menuConfig = { 
    3.   title: null
    4.   body: 'Bar'
    5.   buttonText: null
    6.   cancellable: true 
    7. }; 
    8. function createMenu(config) { 
    9.   config.title = config.title || 'Foo'
    10.   config.body = config.body || 'Bar'
    11.   config.buttonText = config.buttonText || 'Baz'
    12.   config.cancellable = config.cancellable !== undefined ? config.cancellable : true
    13. createMenu(menuConfig); 
    14.  
    15.  
    16. //better code 
    17. const menuConfig = { 
    18.   title: 'Order'
    19.   // 'body' key 缺失 
    20.   buttonText: 'Send'
    21.   cancellable: true 
    22. }; 

    4、避免副作用

    函数接收一个值返回一个新值,除此之外的行为我们都称之为副作用,比如修改全局变量、对文件进行 IO 操作等。

    当函数确实需要副作用时,比如对文件进行 IO 操作时,请不要用多个函数/类进行文件操作,有且仅用一个函数/类来处理。也就是说副作用需要在唯一的地方处理。

    副作用的三大天坑:随意修改可变数据类型、随意分享没有数据结构的状态、没有在统一地方处理副作用。

    1. //bad code 
    2. // 全局变量被一个函数引用 
    3. // 现在这个变量从字符串变成了数组,如果有其他的函数引用,会发生无法预见的错误。 
    4. var name = 'Ryan McDermott'
    5. function splitIntoFirstAndLastName() { 
    6.   name = name.split(' '); 
    7. splitIntoFirstAndLastName(); 
    8. console.log(name); // ['Ryan''McDermott']; 
    9.  
    10.  
    11. //better code 
    12. var name = 'Ryan McDermott'
    13. var newName = splitIntoFirstAndLastName(name
    14.  
    15. function splitIntoFirstAndLastName(name) { 
    16.   return name.split(' '); 
    17.  
    18. console.log(name); // 'Ryan McDermott'
    19. console.log(newName); // ['Ryan''McDermott']; 

    在 JavaScript 中,基本类型通过赋值传递,对象和数组通过引用传递。以引用传递为例:

    假如我们写一个购物车,通过 addItemToCart()方法添加商品到购物车,修改 购物车数组。此时调用 purchase()方法购买,由于引用传递,获取的 购物车数组正好是最新的数据。

    看起来没问题对不对?

    如果当用户点击购买时,网络出现故障, purchase()方法一直在重复调用,与此同时用户又添加了新的商品,这时网络又恢复了。那么 purchase()方法获取到 购物车数组就是错误的。

    为了避免这种问题,我们需要在每次新增商品时,克隆 购物车数组并返回新的数组。

    1. //bad code 
    2. const addItemToCart = (cart, item) => { 
    3.   cart.push({ item, dateDate.now() }); 
    4. }; 
    5.  
    6. //better code 
    7. const addItemToCart = (cart, item) => { 
    8.   return [...cart, {item, dateDate.now()}] 
    9. }; 

    5、全局方法

    在 JavaScript 中,永远不要污染全局,会在生产环境中产生难以预料的 bug。举个例子,比如你在 Array.prototype上新增一个 diff方法来判断两个数组的不同。而你同事也打算做类似的事情,不过他的 diff方法是用来判断两个数组首位元素的不同。很明显你们方法会产生冲突,遇到这类问题我们可以用 ES2015/ES6 的语法来对 Array进行扩展。

    1. //bad code 
    2. Array.prototype.diff = function diff(comparisonArray) { 
    3.   const hash = new Set(comparisonArray); 
    4.   return this.filter(elem => !hash.has(elem)); 
    5. }; 
    6.  
    7. //better code 
    8. class SuperArray extends Array { 
    9.   diff(comparisonArray) { 
    10.     const hash = new Set(comparisonArray); 
    11.     return this.filter(elem => !hash.has(elem));         
    12.   } 

    6、避免类型检查

    JavaScript 是无类型的,意味着你可以传任意类型参数,这种自由度很容易让人困扰,不自觉的就会去检查类型。仔细想想是你真的需要检查类型还是你的 API 设计有问题?

    1. //bad code 
    2. function travelToTexas(vehicle) { 
    3.   if (vehicle instanceof Bicycle) { 
    4.     vehicle.pedal(this.currentLocation, new Location('texas')); 
    5.   } else if (vehicle instanceof Car) { 
    6.     vehicle.drive(this.currentLocation, new Location('texas')); 
    7.   } 
    8.  
    9. //better code 
    10. function travelToTexas(vehicle) { 
    11.   vehicle.move(this.currentLocation, new Location('texas')); 

    如果你需要做静态类型检查,比如字符串、整数等,推荐使用 TypeScript,不然你的代码会变得又臭又长。

    1. //bad code 
    2. function combine(val1, val2) { 
    3.   if (typeof val1 === 'number' && typeof val2 === 'number' || 
    4.       typeof val1 === 'string' && typeof val2 === 'string') { 
    5.     return val1 + val2; 
    6.   } 
    7.  
    8.   throw new Error('Must be of type String or Number'); 
    9.  
    10. //better code 
    11. function combine(val1, val2) { 
    12.   return val1 + val2; 

    复杂条件判断

    我们编写js代码时经常遇到复杂逻辑判断的情况,通常大家可以用if/else或者switch来实现多个条件判断,但这样会有个问题,随着逻辑复杂度的增加,代码中的if/else/switch会变得越来越臃肿,越来越看不懂,那么如何更优雅的写判断逻辑

    1、if/else

    点击列表按钮事件

    1. /** 
    2.  * 按钮点击事件 
    3.  * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消 
    4.  */ 
    5. const onButtonClick = (status)=>{ 
    6.   if(status == 1){ 
    7.     sendLog('processing'
    8.     jumpTo('IndexPage'
    9.   }else if(status == 2){ 
    10.     sendLog('fail'
    11.     jumpTo('FailPage'
    12.   }else if(status == 3){ 
    13.     sendLog('fail'
    14.     jumpTo('FailPage'
    15.   }else if(status == 4){ 
    16.     sendLog('success'
    17.     jumpTo('SuccessPage'
    18.   }else if(status == 5){ 
    19.     sendLog('cancel'
    20.     jumpTo('CancelPage'
    21.   }else { 
    22.     sendLog('other'
    23.     jumpTo('Index'
    24.   } 

    从上面我们可以看到的是通过不同的状态来做不同的事情,代码看起来非常不好看,大家可以很轻易的提出这段代码的改写方案,switch出场:

    2、switch/case

    1. /** 
    2.  * 按钮点击事件 
    3.  * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消 
    4.  */ 
    5. const onButtonClick = (status)=>{ 
    6.   switch (status){ 
    7.     case 1: 
    8.       sendLog('processing'
    9.       jumpTo('IndexPage'
    10.       break 
    11.     case 2: 
    12.     case 3: 
    13.       sendLog('fail'
    14.       jumpTo('FailPage'
    15.       break   
    16.     case 4: 
    17.       sendLog('success'
    18.       jumpTo('SuccessPage'
    19.       break 
    20.     case 5: 
    21.       sendLog('cancel'
    22.       jumpTo('CancelPage'
    23.       break 
    24.     default
    25.       sendLog('other'
    26.       jumpTo('Index'
    27.       break 
    28.   } 

    这样看起来比if/else清晰多了,细心的同学也发现了小技巧,case 2和case 3逻辑一样的时候,可以省去执行语句和break,则case 2的情况自动执行case 3的逻辑。

    3、存放到Object

    将判断条件作为对象的属性名,将处理逻辑作为对象的属性值,在按钮点击的时候,通过对象属性查找的方式来进行逻辑判断,这种写法特别适合一元条件判断的情况。

    1. const actions = { 
    2.   '1': ['processing','IndexPage'], 
    3.   '2': ['fail','FailPage'], 
    4.   '3': ['fail','FailPage'], 
    5.   '4': ['success','SuccessPage'], 
    6.   '5': ['cancel','CancelPage'], 
    7.   'default': ['other','Index'], 
    8. /** 
    9.  * 按钮点击事件 
    10.  * @param {number} status 活动状态:1开团进行中 2开团失败 3 商品售罄 4 开团成功 5 系统取消 
    11.  */ 
    12. const onButtonClick = (status)=>{ 
    13.   let action = actions[status] || actions['default'], 
    14.       logName = action[0], 
    15.       pageName = action[1] 
    16.   sendLog(logName) 
    17.   jumpTo(pageName) 

    4、存放到Map

    1. const actions = new Map([ 
    2.   [1, ['processing','IndexPage']], 
    3.   [2, ['fail','FailPage']], 
    4.   [3, ['fail','FailPage']], 
    5.   [4, ['success','SuccessPage']], 
    6.   [5, ['cancel','CancelPage']], 
    7.   ['default', ['other','Index']] 
    8. ]) 
    9. /** 
    10.  * 按钮点击事件 
    11.  * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消 
    12.  */ 
    13. const onButtonClick = (status)=>{ 
    14.   let action = actions.get(status) || actions.get('default'
    15.   sendLog(action[0]) 
    16.   jumpTo(action[1]) 

    这样写用到了es6里的Map对象,是不是更爽了?Map对象和Object对象有什么区别呢?

    • 一个对象通常都有自己的原型,所以一个对象总有一个"prototype"键。
    • 一个对象的键只能是字符串或者Symbols,但一个Map的键可以是任意值。

    你可以通过size属性很容易地得到一个Map的键值对个数,而对象的键值对个数只能手动确认。

    代码风格

    常量大写

    1. //bad code 
    2. const DAYS_IN_WEEK = 7; 
    3. const daysInMonth = 30; 
    4.  
    5. const songs = ['Back In Black''Stairway to Heaven''Hey Jude']; 
    6. const Artists = ['ACDC''Led Zeppelin''The Beatles']; 
    7.  
    8. function eraseDatabase() {} 
    9. function restore_database() {} 
    10.  
    11. class animal {} 
    12. class Alpaca {} 
    13.  
    14. //better code 
    15. const DAYS_IN_WEEK = 7; 
    16. const DAYS_IN_MONTH = 30; 
    17.  
    18. const SONGS = ['Back In Black''Stairway to Heaven''Hey Jude']; 
    19. const ARTISTS = ['ACDC''Led Zeppelin''The Beatles']; 
    20.  
    21. function eraseDatabase() {} 
    22. function restoreDatabase() {} 
    23.  
    24. class Animal {} 
    25. class Alpaca {} 

    先声明后调用

    1. //bad code 
    2. class PerformanceReview { 
    3.   constructor(employee) { 
    4.     this.employee = employee; 
    5.   } 
    6.  
    7.   lookupPeers() { 
    8.     return db.lookup(this.employee, 'peers'); 
    9.   } 
    10.  
    11.   lookupManager() { 
    12.     return db.lookup(this.employee, 'manager'); 
    13.   } 
    14.  
    15.   getPeerReviews() { 
    16.     const peers = this.lookupPeers(); 
    17.     // ... 
    18.   } 
    19.  
    20.   perfReview() { 
    21.     this.getPeerReviews(); 
    22.     this.getManagerReview(); 
    23.     this.getSelfReview(); 
    24.   } 
    25.  
    26.   getManagerReview() { 
    27.     const manager = this.lookupManager(); 
    28.   } 
    29.  
    30.   getSelfReview() { 
    31.     // ... 
    32.   } 
    33.  
    34. const review = new PerformanceReview(employee); 
    35. review.perfReview(); 
    36.  
    37. //better code 
    38. class PerformanceReview { 
    39.   constructor(employee) { 
    40.     this.employee = employee; 
    41.   } 
    42.  
    43.   perfReview() { 
    44.     this.getPeerReviews(); 
    45.     this.getManagerReview(); 
    46.     this.getSelfReview(); 
    47.   } 
    48.  
    49.   getPeerReviews() { 
    50.     const peers = this.lookupPeers(); 
    51.     // ... 
    52.   } 
    53.  
    54.   lookupPeers() { 
    55.     return db.lookup(this.employee, 'peers'); 
    56.   } 
    57.  
    58.   getManagerReview() { 
    59.     const manager = this.lookupManager(); 
    60.   } 
    61.  
    62.   lookupManager() { 
    63.     return db.lookup(this.employee, 'manager'); 
    64.   } 
    65.  
    66.   getSelfReview() { 
    67.     // ... 
    68.   } 
    69.  
    70. const review = new PerformanceReview(employee); 
    71. review.perfReview(); 
      高级语言的出现使得计算机程序设计语言不再过度地依赖某种特定的机器或环境。这是因为高级语言在不同的平台上会被编译成不同的机器语言,而不是直接被机器执行。最早出现的编程语言之一FORTRAN的一个主要目标,就是实现平台独立。

课课家教育

未登录