js代码优化

2023-05-16

原文:https://dmitripavlutin.com/unlearn-javascript-bad-coding-habits/ 

一:不要使用隐式类型转换

  • 大多数运算符+-*/==(不包括===)再处理不同类型的操作数时会进行隐式转换
  • 语句 if(condition){};while(condition){}隐式转换为布尔值

使用隐式的一些问题

当你去判断一个对象的某一个属性值是否有值的时候,如果那个属性是有值的且那个值为falue所以if()会拿取到值,但依旧会被判断为false,所以我们会误以为是没有值

例子

现在咱们实现一个获取对象属性的函数。如果属性不存在,函数返回一个默认值

function getProp(object, propertyName, defaultValue) {    
  if (!object[propertyName]) {    
    return defaultValue;    
  }    
  return object[propertyName];    
}    
const hero = {    
  name: 'Batman',    
  isVillian: false    
};    
console.log(getProp(hero, 'name', 'Unknown'));     // => 'Batman'
getProp() 读取 name属性的值,即 'Batman'。

那么试图访问 isVillian属性:

console.log(getProp(hero, 'isVillian', true)); // => true


这是一个错误。即使 hero 的属性 isVillian为 false,函数 getProp()也会返回错误的 true。

这是因为属性存在的验证依赖于 if(!object[propertyName]){...}隐式转换的布尔值。

这些错误很难发现,要修复该函数,就要明确验证值的类型:

function getPropFixed(object, propertyName, defaultValue) {    
   if (object[propertyName] === undefined) {    
     return defaultValue;    
   }    
   return object[propertyName];    
}    
const hero = {    
  name: 'Batman',    
  isVillian: false    
};    
console.log(getPropFixed(hero, 'isVillian', true)); // => false


object[propertyName]===undefined确切地验证属性是否为 undefined。

这里建议避免直接使用 undefined。因此,上述解决方案可以进一步改进:

function getPropFixedBetter(object, propertyName, defaultValue) {    
  if (!(propertyName in object)) {    
    return defaultValue;    
  }    
  return object[propertyName]    
}


原谅作者建议是:尽可能不要使用隐式类型转换。相反,请确保变量和函数参数始终具有相同的类型,必要时使用显式类型转换。

解法问题一方法

  • 始终使用严格的相等运算符 === 进行比较
  • 不要使用松散等式运算符 ==
  • 算数运算符,尤其是加法两边的超字数应该是数字或字符串
  • if(condition){};while(condition){}等语句中的 condition必须是一个booler

问题二:不要使用早期的JavaScript技巧

例如:ES6 中可以使用 array.includes(item) 来代替 array.indexOf(item)!==-1

问题三:不要污染函数作用域

可以在块级中定义的变量就尽可能再块级作用域中定义

例子

function someFunc(array) {	
  var index, item, length = array.length;	
  /*	
   * Lots of code	
   */	
  for (index = 0; index < length; index++) {	
    item = array[index];	
    // Use `item`	
  }	
  return someResult;	
}

修改后

通过引入块级作用域let和const,应该尽可能的限制变量的生命周期

function someFunc(array) {	
  /*	
   * Lots of code	
   */	
  const length = array.length;	
  for (let index = 0; index < length; index++) {	
    const item = array[index];	
    // Use `item`	
  }	
  return someResult;	
}

3-2:if作用域

// 不好	
let message;	
// ...	
if (notFound) {	
  message = 'Item not found';	
  // Use `message`	
}	
// 好	
if (notFound) {	
  const message = 'Item not found';	
  // Use `message`	
}

3-3:for作用域

// 不好	
let item;	
for (item of array) {	
  // Use `item`	
}	
// 好	
for (const item of array) {	
  // Use `item`	
}

问题四:尽量避免undefined和null

未赋值的变量默认被赋值为 undefined

为什么直接使用 undefined是一个不好习惯?因为与 undefined进行比较时,你正在处理未初始化状态的变量。

变量、对象属性和数组在使用前必须用值初始化

JS 提供了很多避免与 undefined进行比较方式。

4-1:判断对象属性是否存在

// 不好	
const object = {	
  prop: 'value'	
};	
if (object.nonExistingProp === undefined) {	
  // ...	
}	
// 好	
const object = {	
  prop: 'value'	
};	
if ('nonExistingProp' in object) {	
  // ...	
}

这里用的是in运算符,这里不单单可以找到自身对象上的属性还可以找到原型上的,如果你不想找原型上的那么就用hasOwnProperty()方法判断是否是含有中国属性

4-2:判断对象默认属性,后的合并问题

// 不好	
function foo(options) {	
  if (object.optionalProp1 === undefined) {	
    object.optionalProp1 = 'Default value 1';	
  }	
  // ...	
}	
// 好	
function foo(options) {	
  const defaultProps = {	
    optionalProp1: 'Default value 1'	
  };	
  options = {	
    ...defaultProps,	
    ...options	
  }	
}

直接用下面的方法,这样就算我defaultProps中添加了原来有的字段,也会被原来的对象给替换掉

4-3定义默认函数参数

// 不好	
function foo(param1, param2) {	
  if (param2 === undefined) {	
    param2 = 'Some default value';	
  }	
  // ...	
}	
// 好	
function foo(param1, param2 = 'Some default value') {	
  // ...	
}

4-4

null是一个缺失对象的指示符。应该尽量避免从函数返回 null,特别是使用 null作为参数调用函数

 

问题五:不要使用随意的编码风格,执行一个标准

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js代码优化 的相关文章

  • 从 (a==1&&a==2&&a==3) 成立中看javascript的隐式类型转换

    几天上班看到一个题目就是 if a 61 61 1 amp amp a 61 61 2 amp amp a 61 61 3 console log 34 a等于什么才会输出这一句话呢 xff1f 34 当a为什么的时候输出 xff1a a等
  • Bootstrap实用功能总结

    导航栏 xff1a navbar 导航栏容器可以包含以下几个常用组成 xff1a 1 品牌LOGO xff08 navbar brand xff09 2 导航菜单 xff08 navbar nav xff09 3 导航文本 xff08 na
  • 微信小程序的AJAX初次体验

    GET请求 微信小程序用GET传送数据 微信小程序通过 wx request发送ajax请求 wx request url app globalData pubSiteUrl 43 39 user information get infor
  • vue总结系列 ------ 组件之间的传值

    原因 半年前开始学Vue学到了今天 xff0c 也没有机会好好整理一下自己的知识点 xff0c 因为上公司的项目不是依赖于Vue xff0c 还是在用JQ 和文件之间来传递代码 xff0c 所以其实在对vue的学习成面上来讲对我的帮助并不大
  • vue总结系列 --- 插槽slot

    前因 这个是我这个系列的第二篇 这一篇文章我也修改过三次 xff08 2019 9 10 xff09 我是想以vue官方文档为基础 xff0c 来进行理解 xff0c 有人说有官方文档 xff0c 还要写自己的文章干嘛 xff0c 我的用意
  • vue总结系列 --- 生命周期

    前言 在总结其他的时候发现还是应该先复习vue的生命周期 xff0c 所以就先把生命周期先复习完了 经过一系列的视频 xff0c 文档我把我的总结写一下生命周期分为3个阶段 xff1a 创建 xff0c 更新 xff0c 和销毁 我们看图说
  • vue总结系列 ---- 响应式原理

    检测变化 vue是数据驱动的视图框架DOM是通过数据映射的 xff0c 只有数据改变 xff0c DOM才改变 那么数据是怎么来的呢 xff1f 1 来自父元素的属性 xff08 prop xff09 2 来自组件的自身状态 xff08 d
  • Object.defineProperty()的学习了解

    背景 最近在总结vue系列的时候是看到响应原理的时候 看到一个新的知识点也就是我们的标题Object defineProperty 的时候 xff0c 好了话不多说 xff0c 我们来看看这个是怎么使用的 开始 strong Object
  • vue总结系列 ----- 单向数据流

    可能很多人都以为vue的双向绑定其实是错误的 xff0c vue真正的是单向数据流 xff0c vue的双向绑定只不过是语法糖 我的理解是 xff1a model层 xff1a data对象中的数据 xff0c 或后台传过来的数据 view
  • vue总结系列 ---- 在组件上的v-model单向数据流

    背景 目前是在复习vue原理的过程中 xff0c 前端负责人知道我最近在复习vue xff0c 跟我说要我看组件上的v model 我一听本来是不想放在心上的 xff0c 刚好那天晚上没什么事干想看一下 xff0c 毕竟负责人 xff0c
  • ES6 函数扩展

    参数默认值 也就是说现在ES6对函数中的参数添加了默认值 我们在ES5种的处理 function Fn a b b 61 b 34 nodeing 34 return a 43 b console log Fn 34 hello 34 这样
  • ES6 对象扩展

    对象简写 对象中又分了属性和方法的简写 在es5中 xff0c 有这样一种写法 var name 61 34 xiaoqiang 34 var age 61 12 var obj 61 name name age age 在es6中 xff
  • Bootstrap基础学习笔记

    网格系统 row定义一行 col均分列数 xff0c 最多一行12列 每列左右间隙各15px col 1到12 定义在所有屏幕下的列宽 col sm md lg xl 1到12 定义在指定屏幕下该列占据的列宽 xff0c sm 屏幕 gt

随机推荐

  • ES6 Symbol用法

    Symbol用法 什么是Symbol Symbol是es6中一种新增加的数据类型 xff0c 它表示独一无二的值 es5中我们把数据类型分为基本数据类型 xff08 字符串 数字 布尔 undefined null xff09 和引用数据类
  • img标签中的src在绝对引用的时候的问题

    昨天晚上我一个朋友目前在培训 xff0c 他在群里问了下img标签如何绝对路径引用 xff0c 我当时就笑了这个就是培训机构的老师 xff0c 就大概看了一下就告诉我朋友那里错了 xff0c 但是却出来不 xff0c 我就想自己写一个dem
  • 在vue-cli中使用vue-router的学习笔记

    以前不会vue cli的时候学过router xff0c 当时的写法和在vue cli中的写法还是有一些不一样的 xff0c 但是我以后应该还是会用vue的单文件写小程序啊什么的所以我就吧我学习的过程全部记录下来 router创建 那么问题
  • js中bind()使用详情

    前言 最近在在搞React的时候有用到bind 的时候 xff0c 因为他的用法其实我还一直不是特别的清楚 xff0c 所以今天我把bind 他的用法和我遇到的结合起来这样来写一个博客 xff0c 这样应该可以加深自己的印象同时可以来跟好的
  • var let const 详细区别

    用了ES6已经有一段事件了 xff0c 也看了很多文档 xff0c 以前觉得不用写一个文档总结 xff0c 但是经过一段时间的接触以后 xff0c 认为自己还是有必要去吧他们的区别详详细细的总结一下 块级作用域 白话一点就是在 中就是一个块
  • Git 速查表

    配置 git config global user name 34 lt 姓名 gt 34 设置提交者姓名 git config global user email 34 lt 邮箱 gt 34 设置提交者邮箱 这个有什么用呢 xff1f
  • async比Promise好在什么地方

    什么是Promise xff1f Promise是ES6中的异步编程解决方案 xff0c 在代码中表现为一个对象 xff0c 可以通过构造函数Promise来实例化 xff0c 有了Promise对象 xff0c 可以将异步操作以同步的流程
  • css面试题----css测试9

    每个星期6都会去去看张鑫旭直播写一些小demo然后再去吧写每天学习到的东西 xff0c 心得记下来 xff0c 并且会长期去完成这个任务 IT这个东西真的是要去强迫自己学学习一些好的东西 xff0c 多去优化代码 xff0c 而不是去停滞不
  • css面试题----DOM基础测试34

    这个其实是上上个星期张鑫旭直播的内容 xff0c 我吧我不会的内容总结一下 xff0c 从而来分享给大家 题目 第一问 document querySelectorAll 39 a 39 第二问 1 有bug当有这个href属性但没属性值
  • fon in 和 for of 的区别

    for 循环 其实他一般情况下是根据数组 xff0c 类数组的length的属性值去循环 for in 一般的作用是枚举把key枚举出来 xff0c 但是当我们枚举数组 xff0c 或者字符串的时候会把原型上的方法枚举出来 Object p
  • 词云图wordcloud学习笔记

    词云图 也叫文字云 是对文本中出现频率较高的 关键词 予以视觉化的展现 词云图过滤掉大量的低频低质的文本信息 使得浏览者只要一眼扫过文本就可领略文本的主旨 github https github com amueller word clou
  • ++a-a++解析

    有题目当a为1的时候 43 43 a a 43 43 为多少答案为0 我们再输出a这个时候a等于3 为什么呢 xff1f 运算顺序 前置递增 减 大于 数字运算和后置递增 减 大于 比较 布 大于 逻辑 或 且 大于 赋值 好当我们把运算顺
  • sync修饰符的使用

    为什么使用sync 再vue中官网的介绍 xff1a 我们可能需要对一个 prop 进行 双向绑定 不幸的是 xff0c 真正的双向绑定会带来维护上的问题 xff0c 因为子组件可以修改父组件 xff0c 且在父组件和子组件都没有明显的改动
  • vue中 methods computed watch filters区别

    在vue中事件 xff0c 计算属性 xff0c 帧听器 xff0c 过滤器的区别 其实共同点 xff1a 修改数据 事件methods和计算属性computed 作用 xff1a 对数据进行逻辑运算 区别 计算属性是基于它们的响应式依赖进
  • 前端面试题----js基础测试35

    得分 这个题目总共8分的我只有3分 xff0c 但是说实话我写这个题目的时候信心爆棚 xff0c 我觉得我自己应该是写出来的的 xff0c 但是可惜 解析 第一题 正解 xff1a 1 encodeURI 函数假设参数是完整的 URIs x
  • 前端面试题----DOM测试35

    得分 这个题目8分我5分 重新复习 HTML lt form id 61 34 loginForm 34 action 61 34 account login 34 method 61 34 POST 34 gt lt p gt 账号 xf
  • 前端小测---css基础测试10

    得分 总共8分得了6分有一个背景样式没处理好 重点 无js使用details和summary组合动画处理 xff0c 使用max height 0来过渡 HTML lt div class 61 34 container 34 gt lt
  • 前端小测试---- 图片上传

    得分 8分我自己得了4分 第一问 xhr onprogress和xhr upload onprogress的区别 xff1a 这两个都能显示进度百分比 xff0c 但是 xff0c 前者显示的是服务器返回的数据 xff0c 后者是发送给服务
  • js 部分代码注释规范

    普通注释 单行 单行注释 文字和 有一个空格 多行 多行注释 1 总是再多行注释的结束符前留一个空格 使星号对齐 2 不要把注释写再多行注释的开始符 xff0c 和结束符所在行 文档注释 Core模块提供最基础 最核心的接口 文档说明 64
  • js代码优化

    原文 xff1a https dmitripavlutin com unlearn javascript bad coding habits 一 xff1a 不要使用隐式类型转换 大多数运算符 43 61 61 不包括 61 61 61 再