LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

优秀的js技巧方法

liguoquan
2024年12月28日 10:41 本文热度 144
:优秀的js技巧方法


🐸优秀的js技巧方法🐸

这篇文章主要介绍了优秀的 JavaScript 技巧方法,包括数组(声明初始化、过滤虚假值、查找等)、逻辑运算(使用逻辑运算符、可选链等)、数字(进制转换、获取随机整数等)、对象(检查是否为空等)、字符串(首字母大写、翻转等)、浏览器相关(复制内容、清除 Cookie 等)以及其他方面(检测函数、防抖节流等),还提到了编码好习惯。

关联问题:数组查找如何优化对象属性动态设置字符串翻转效率怎样

知识点总结系列

📞一文带你速通前端实时通讯☎️

📞前端通信百宝箱📱

🍎常用的Git命令指南🍎

🐥常用CSS技巧总结🐥

🐸优秀的js技巧方法🐸

数组相关

声明和初始化数组

我们可以使用默认值(如""、null或 )初始化特定大小的数组0。您可能已经将这些用于一维数组,但如何初始化二维数组/矩阵呢?

js
代码解读
复制代码
const array = Array(5).fill(''); // 输出 (5) ["", "", "", "", ""] const matrix = Array(5).fill(0).map(()=>Array(5).fill(0)); // 输出 (5) [Array(5), Array(5), Array(5), Array(5), Array(5)] 0: (5) [0, 0, 0, 0, 0] 1: (5) [0, 0, 0, 0, 0] 2: (5) [0, 0, 0, 0, 0] 3: (5) [0, 0, 0, 0, 0] 4: (5) [0, 0, 0, 0, 0] length: 5

从数组中过滤出虚假值

Falsy值喜欢0undefinednullfalse""''可以很容易地通过以下方法省略

js
代码解读
复制代码
const array = [3, 0, 6, 7, '', false]; array.filter(Boolean); // 输出 (3) [3, 6, 7]

数组查找

当对数组进行查找时,indexOf()用于获取查找项的位置。如果未找到该项,则返回值为-1。在JavaScript中,0被视为false,而大于或小于0的数字被视为true。因此,需要这样来写

传统写法:

js
代码解读
复制代码
if(arr.indexOf(item) > -1) { } if(arr.indexOf(item) === -1) { }

简化写法:

js
代码解读
复制代码
if(~arr.indexOf(item)) { } if(!~arr.indexOf(item)) { }

位非(~)运算符对除了-1之外的任何值都返回一个"真"值。对其进行取反就是简单地使用!~即可。另外,也可以使用includes()函数:

js
代码解读
复制代码
if(arr.includes(item)) { }

打乱数组

利用内置Math.random()方法。

js
代码解读
复制代码
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9]; list.sort(() => {    return Math.random() - 0.5; }); // 输出 (9) [2, 5, 1, 6, 9, 8, 4, 3, 7] // Call it again (9) [4, 1, 7, 5, 3, 8, 2, 9, 6]

检测是否为一个安全数组

js
代码解读
复制代码
 // 检测是否为一个安全数组,若不是返回空数组  这里借助isArray 方法  const safeArray = (array) => {    return Array.isArray(array) ? array : []  }

数组清空

  • 对比arr.length=0与arr=[]

arr.length=0的应用点主要是完全清空字面量指向的真实数组
我们知道在js中,引用类型相对应的自变量实际上是在栈内存中储存了地址,指向堆内存中真实的数据 假设现有一个不空的数组arr
当我们使用 arr=[]时,实际上是为arr重新赋值为一个空数组[]
此时arr原先储存的地址所指向的原数组仍然在内存中(可能导致内存泄露)
使用arr.length=0时:命令作用在真实数组,相当于直接将原数组清空

js
代码解读
复制代码
//使用arr作为模版用于循环中接收值: res=arr arr=[] //等同于: res=arr.slice()//copy arr.length=0

实现并集、交集、和差集

js
代码解读
复制代码
let a = new Set([1, 2, 3]); let b = new Set([4, 3, 2]); // 并集 let union = new Set([...a, ...b]); // Set {1, 2, 3, 4} // 交集 let intersect = new Set([...a].filter(x => b.has(x))); // set {2, 3} // (a 相对于 b 的)差集 let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}

map循环

map: 只有当arr为基本数据类型时,map方法才不会改变原始数组,arr为引用类型时,还是会改变原数组的

js
代码解读
复制代码
const citys = [{ name: 'shenzhen' }, { name: 'hanghzhou' }]; const newCitys = citys.map((item) => {    item.country = 'china';    return item; }); console.log('citys', citys); //[{ name: 'shenzhen', country: 'china' },{ name: 'hanghzhou', country: 'china' }] console.log('newCitys', newCitys); //[{ name: 'shenzhen', country: 'china' },{ name: 'hanghzhou', country: 'china' }]

逻辑运算

对各种条件使用逻辑运算符

如果你想减少嵌套 if…else 或 switch case,你可以简单地使用基本的逻辑运算符AND/OR

js
代码解读
复制代码
function doSomething(arg1){    arg1 = arg1 || 10; // 如果尚未设置,则将 arg1 设置为 10 作为默认值 return arg1; } let foo = 10;   foo === 10 && doSomething(); // is the same thing as if (foo == 10) then doSomething(); // 输出: 10 foo === 5 || doSomething(); // is the same thing as if (foo != 5) then doSomething(); // 输出: 10

可选链

可选的链接 ?.如果值在 ? 之前,则停止评估。为 undefined 或 null 并返回

js
代码解读
复制代码
undefined const user = {  employee: {    name: "Kapil"  } }; user.employee?.name; // 输出: "Kapil" user.employ?.name; // 输出: undefined user.employ.name // 输出: VM21616:1 Uncaught TypeError: Cannot read property 'name' of undefined

对于动态属性将其更改为:

js
代码解读
复制代码
object?.[index] 

对于方法的调用你可以这样写

js
代码解读
复制代码
object.runsOnlyIfMethodExists?.()

空合并算子

空合并运算符 (??) 是一个逻辑运算符,当其左侧操作数为空或未定义时返回其右侧操作数,否则返回其左侧操作数。

js
代码解读
复制代码
const foo = null ?? 'my school'; // 输出: "my school" const baz = 0 ?? 42; // 输出: 0

||=与??=

||= 和 ??= 是两种不同的赋值运算符,它们分别表示逻辑或赋值和空值合并赋值。

  • ||= 运算符用于给变量赋值,但仅当左侧的变量为假值(false、null、undefined、空字符串等)时才会执行赋值操作。

  • 例如:

js
代码解读
复制代码
let x = null; x ||= 5; console.log(x);  // 输出 5,因为 x 是 null,所以赋值为 5 let y = 10; y ||= 7; console.log(y);  // 输出 10,因为 y 已经有值了,不会执行赋值操作
  • ??= 运算符用于给变量赋值,但仅当左侧的变量为 null 或 undefined 时才会执行赋值操作。

  • 例如:

js
代码解读
复制代码
javascriptCopy Codelet a = null; a ??= 5; console.log(a);  // 输出 5,因为 a 是 null,所以赋值为 5 let b = 10; b ??= 7; console.log(b);  // 输出 10,因为 b 已经有值了,不会执行赋值操作

数字相关

将十进制转换为二进制或十六进制

在解决问题的同时,我们可以使用一些内置的方法,例如.toPrecision().toFixed()来实现许多帮助功能。

js
代码解读
复制代码
const num = 10; num.toString(2); // 输出: "1010" num.toString(16); // 输出: "a" num.toString(8); // 输出: "12"

获取两个整数之间的随机整数

该方法用于获取两个整数之间的随机整数

js
代码解读
复制代码
const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min); random(1, 50);

将一个字符串变成数字

常规操作

js
代码解读
复制代码
let str = '2' console.log(Number(str))   //2 复制代码

骚操作一

js
代码解读
复制代码
let str = '2' console.log(~~str)    //2

骚操作二

js
代码解读
复制代码
let str = '2' console.log(+str)    //2

科学计数法

可以使用科学技术法来表示数字,以省略尾部的零。例如,1e7 实际上表示 1 后面跟着 7 个零。它表示一个十进制,相当于 10,000,000。

传统写法:

js
代码解读
复制代码
for (let i = 0; i < 10000; i++) {}

简化写法:

js
代码解读
复制代码
for (let i = 0; i < 1e7; i++) {} // 下面的所有比较都将返回 true 1e0 === 1; 1e1 === 10; 1e2 === 100; 1e3 === 1000; 1e4 === 10000; 1e5 === 100000;

指数幂运算

指数幂运算可以使用 ** 来简化。

传统写法:

js
代码解读
复制代码
Math.pow(2,3); // 8 Math.pow(2,2); // 4 Math.pow(4,3); // 64

简化写法:

js
代码解读
复制代码
2**3 // 8 2**4 // 16 4**3 // 64

从 ES7(ECMAScript 2016)开始,JavaScript 引入了指数幂运算符 **,使指数幂运算更加简洁。

转为布尔值

可以使用双重逻辑非操作符将任何值转换为布尔值。

js
代码解读
复制代码
!!23 // TRUE !!"" // FALSE !!0 // FALSE !!{} // TRUE

单一的逻辑非操作符已经可以将值转换为布尔类型并对其进行取反,所以第二个逻辑非操作符会再次对其进行取反,从而将其恢复为原始含义,并保持为布尔类型。

对象相关

检查对象是否为空

检查对象是否为空,实际上并不那么简单,即使对象为空,每次检查对象是否等于 {} 也会返回 false

幸运的是,下面的单行代码正是我们想要的。

js
代码解读
复制代码
const isEmpty = obj => Reflect.ownKeys(obj).length === 0 && obj.constructor === Object; isEmpty({}) // true isEmpty({a:"not empty"}) //false

动态属性名称:多功能对象键

可以使用方括号将变量用作对象属性名称:

js
代码解读
复制代码
const key = 'name';   const person = { [key]: 'Alice' };   console.log(person.name); // Output: Alice

检测对象是否为一个安全对象

js
代码解读
复制代码
   // 首先要去判断 当前对象是否为有效对象    const isVaildObject = (obj) => {        return typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length    }    // 这里直接用上面的函数 如果有效就返回本身,无效就返回空对象    const safeObject = obj => isVaildObject(obj) ? obj : {}    

字符串相关

字符串首字母大写

该方法用于将英文字符串的首字母大写处理:

js
代码解读
复制代码
const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1) capitalize("hello world")  // Hello world

翻转字符串

该方法用于将一个字符串进行翻转操作,返回翻转后的字符串:

js
代码解读
复制代码
const reverse = str => str.split('').reverse().join(''); reverse('hello world');   // 'dlrow olleh'

过滤特殊字符

js
代码解读
复制代码
   function filterCharacter(str){        // 首先设置一个模式        let pattern = new RegExp("[`~!@#$^&*()=:”“'。,、?|{}':;'%,\[\].<>/?~!@#¥……&*()&;—|{ }【】‘;]")        let resultStr = "";        for (let i = 0; i < str.length; i++) {            // 主要通过 replace ,pattern 规则 去把字符替换成空 最后拼接在 resultStr            resultStr = resultStr + str.substr(i, 1).replace(pattern, '');        }        // 当循环结束的时候返回最后结果 resultStr        return resultStr;    }        // 示例    filterCharacter('gyaskjdhy12316789#$%^&!@#1=123,./[') // 结果:gyaskjdhy123167891123

浏览器相关

复制内容到剪切板

该方法使用 navigator.clipboard.writeText 来实现将文本复制到剪贴板:

js
代码解读
复制代码
const copyToClipboard = (text) => navigator.clipboard.writeText(text); copyToClipboard("Hello World");

兼容性方案

js
代码解读
复制代码
const copyText = async (val) => {  try {    // 使用现代 API 尝试复制    if (navigator.clipboard && navigator.permissions) {      await navigator.clipboard.writeText(val);      return; // 如果成功,直接返回    }    // 降级方案   const textArea = document.createElement('textArea')   textArea.value = val   textArea.style.width = 0   textArea.style.position = 'fixed'   textArea.style.left = '-999px'   textArea.style.top = '10px'   textArea.setAttribute('readonly', 'readonly')   document.body.appendChild(textArea)   textArea.select()    // 尝试执行复制操作    const success = document.execCommand('copy');    if (!success) {      throw new Error('无法复制文本');    }    // 清理    document.body.removeChild(textArea);  } catch (err) {    console.error('复制失败:', err);  } };

清除所有cookie

该方法可以通过使用 document.cookie 来访问 cookie 并清除存储在网页中的所有 cookie:

js
代码解读
复制代码
const clearCookies = document.cookie.split(';').forEach(                    cookie => document.cookie = cookie.replace(/^ +/,'')                    .replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`));

获取选中的文本

该方法通过内置的 getSelection 属性获取用户选择的文本:

js
代码解读
复制代码
const getSelectedText = () => window.getSelection().toString(); getSelectedText();

滚动到页面顶部

该方法用于在页面中返回顶部:

js
代码解读
复制代码
const goToTop = () => window.scrollTo(0, 0); // function goTop() { window.scrollTo({ top: 0, behavior: "smooth" }); } goToTop();

是否滚动到页面底部

该方法用于判断页面是否已经底部:

js
代码解读
复制代码
const scrolledToBottom = () => document.documentElement.clientHeight + window.scrollY                                        >= document.documentElement.scrollHeight;

判断当前标签页是否激活

该方法用于检测当前标签页是否已经激活:

js
代码解读
复制代码
const isTabInView = () => !document.hidden;

重定向到一个URL

该方法用于重定向到一个新的URL:

js
代码解读
复制代码
const redirect = url => location.href = url redirect("https://www.google.com/")

打开浏览器打印框

该方法用于打开浏览器的打印框: js

js
代码解读
复制代码
const showPrintDialog = () => window.print()

检测元素是否处于焦点

activeElement 属性返回文档中当前获得焦点的元素。

js
代码解读
复制代码
const elementIsInFocus = (el) => (el === document.activeElement); elementIsInFocus(anyElement) // 元素处于焦点返回true,反之返回false

url相关

从url获取参数并转为对象

网页路径经常是:www.baidu.com?search=js&xxx=kkk这种形式的,我们是经常需要取参数的,可以使用第三方的qs包实现,如果你只是要实现去参数,这一句代码就可以实现,不用再引入qs了。

js
代码解读
复制代码
const getParameters = URL => JSON.parse(`{"${decodeURI(URL.split("?")[1]).replace(/"/g, '\"').replace(/&/g, '","').replace(/=/g, '":"')}"}`  ) getParameters("https://www.google.com.hk/search?q=js+md&newwindow=1"); // {q: 'js+md', newwindow: '1'}

重定向到一个URL

该方法用于重定向到一个新的URL:

js
代码解读
复制代码
const redirect = url => location.href = url redirect("https://www.google.com/")

其他

检测是否是一个函数

js
代码解读
复制代码
   // 检测是否是一个函数  其实写法以后直接 isFunction 就好了,避免重复写判断    const isFunction = (obj) => {        return typeof obj === "function" && typeof obj.nodeType !== "number" && typeof obj.item !== "function";    };

防抖/节流

简单介绍

  • 防抖:指定时间内 频繁触发一个事件,以最后一次触发为准
  • 节流:指定时间内 频繁触发一个事件,只会触发一次

应用场景有很多比如:

防抖是: input搜索,用户在不断输入内容的时候,用防抖来减少请求的次数并且节约请求资源

节流:场景普遍就是按钮点击,一秒点击 10 下会发起 10 次请求,节流以后 1 秒点再多次,都只会触发一次

下面我们来实现

js
代码解读
复制代码
   // 防抖    // fn 需要防抖的函数,delay 为定时器时间    function debounce(fn,delay){        let timer =  null  // 用于保存定时器        return function () {            // 如果timer存在 就清除定时器,重新计时            if(timer){                clearTimeout(timeout);            }            //设置定时器,规定时间后执行真实要执行的函数            timeout = setTimeout(() => {               fn.apply(this);            }, delay);        }    }        // 节流    function throttle(fn) {      let timer = null; // 首先设定一个变量,没有执行定时器时,默认为 null      return function () {        if (timer) return; // 当定时器没有执行的时候timer永远是false,后面无需执行        timer = setTimeout(() => {          fn.apply(this, arguments);           // 最后在setTimeout执行完毕后再把标记设置为true(关键)           // 表示可以执行下一次循环了。          timer = null;        }, 1000);      };    }

常用正则判断

js
代码解读
复制代码
   // 校验2-9位文字 不符合为 false  符合为 true    const validateName = (name) => {      const reg = /^[\u4e00-\u9fa5]{2,9}$/;      return reg.test(name);    };    // 校验手机号    const validatePhoneNum = (mobile) => {      const reg = /^1[3,4,5,6,7,8,9]\d{9}$/;      return reg.test(mobile);    };    // 校验6到18位大小写字母数字下划线组成的密码    const validatePassword = (password) => {      const reg = /^[a-zA-Z0-9_]{6,18}$/;      return reg.test(password);    };

高级技巧

模拟点击

vue.js

1,给另一个按钮添加ref

<el-button size="small" type="primary" ref="import">导入</el-button>

2,事件触发

this.$refs.import.$el.click()

利用函数给对象赋值

js
代码解读
复制代码
eventDic.closeCase = (() => {    var ary = e.applicationSettle ? e.applicationSettle.split(',') : []    var dary = ary.map(o => this.eventDict.applicationSettle.get(o))    return dary.join(',') })()

 酷炫控制台技巧:调试的乐趣

使用console.table()console.groupCollapsed()超越console.log()

js
代码解读
复制代码
const users = [{ name'Alice' }, { name'Bob' }];   console.table(users);   console.groupCollapsed(’Details’);   console.log(’NameAlice’);   console.log(’Age30’);   console.groupEnd();

编码好习惯

console.log({name})取代console.log('name', name)

当我们有一个变量名需要在控制台打印的时候,很多人都习惯于这样写:

js
代码解读
复制代码
console.log('name', name)

这种写法本身没有问题,但是会有一些小问题:

  1. 代码长度较长,字符串无法自动补全需要复制粘贴,变量名较长的情况更为明显。
  2. 表现不直观,如果name是一个对象,展开的时候占位太高我们会经常找不到开头的name在哪。

有了ES6,我们其实完全可以这样写:

js
代码解读
复制代码
console.log({name})

这种写法在结果上,可以和上面的写法达到一样的目的。但是不管是代码简洁程度、还是可读性上,都可以得到更友好的提升。尤其是name是一个对象的时候,效果更为明显。

虽然是很简单的一行代码,但是效果还是比较实用的。

巧用JS隐式类型转换

JS是一门弱类型语言,不同type的变量可以相互转化。我们可以巧妙的利用这一特性,让我们的代码在做类型转换的时候,变得更简洁更优雅。直接上代码:

  • 快速转换Number类型:
js
代码解读
复制代码
// 字符串转数字代码对比 const price = parseInt('32'); //传统方式 const price = Number('32'); //传统方式 const price = +'32'; //新方式 // 日期转换为时间戳代码对比 const timeStamp = new Date().getTime(); //传统方式 const timeStamp = +new Date(); //新方式 //布尔转数字新方式 console.log(+true); // Return: 1 console.log(+false); // Return: 0
  • 快速转换Boolean类型:
js
代码解读
复制代码
// 各种类型转布尔代码对比 const isTrue = Boolean('') //传统方式 const isTrue = !!'' //新方式 const isTrue = Boolean(0) //传统方式 const isTrue = !!0 //新方式 const isTrue = Boolean(null) //传统方式 const isTrue = !!null //新方式 const isTrue = Boolean(undefined) //传统方式 const isTrue = !!undefined //新方式
  • 快速转换String类型:
js
代码解读
复制代码
// 数字转string代码对比 const num = 1; const str = num.toString(); //传统方式 const str = num + ''; //新方式

return取代if...else

假如我们有以下代码:

js
代码解读
复制代码
if (condition1) {  // do condition1 } else if (condition2) {  // do condition2 } else if(condition3) {  // do condition3 }

这个写法逻辑上没有问题,但是当日后if条件增加的时候,越来越多的if else 阅读起来费劲不说,更难受的是,当我们需要删除一个条件的时候,我们需要很小心的找到每一个if else对应的{},更没办法直接选中代码直接删除。其实我们完全可以改成return形式让代码变得更简洁、更易读,且更容易编辑

js
代码解读
复制代码
if (condition1) {  // do condition1  return; } if (condition2) {  // do condition2  return; } if (condition3) {  // do condition3    return; }

可能你会说,这么简单的东西,还要写出来,谁不会呢?

但是看起来是很简单,大家都一眼就能看懂的改动,其实根据笔者的经验,很多有经验的老手,都会时常忘记这个小细节。


该文章在 2024/12/28 10:41:03 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved