几个少见却很有用的 JS 技巧

1、“返回”按钮

使用 history.back() 可以创建一个浏览器返回按钮

<button onclick="history.back()">
    返回
</button>  

2、数字分隔符

为了提高数字的可读性,使用下划线作为分隔符

const largeNumber = 1_000_000_000;

console.log(largeNumber); // 1000000000

3、事件监听器只运行一次

想添加一个事件监听器并且只运行一次,使用 once 选项

element.addEventListener('click', () => console.log('I run only once'), {
    
    
    once: true
}); 

4、console.log 变量包装

console.log() 的时候,将参数用大括号括起来,这样可以同时看到变量名和变量值

const myNumber = 123

console.log({
    
    myNumber})  //{myNumber: 123}

5、从数组中获取最小值/最大值

Math.min()Math.max() 结合扩展运算符来查找数组中的最小值或最大值

const numbers = [6, 8, 1, 3, 9];

console.log(Math.max(...numbers)); // 9
console.log(Math.min(...numbers)); // 1 

6、检查 Caps Lock(大小写字母转换键) 是否打开

KeyboardEvent.getModifierState() 来检测 Caps Lock 是否打开

const passwordInput = document.getElementById('password');

passwordInput.addEventListener('keyup', function (event) {
    
    
    if (event.getModifierState('CapsLock')) {
    
    
        // CapsLock 已经打开了
    }
}); 

7、复制到剪贴板

Clipboard API 创建“复制到剪贴板”功能

function copyToClipboard(text) {
    
    
    navigator.clipboard.writeText(text);
}

8、获取鼠标位置

MouseEvent 对象下 clientXclientY 的属性值,获取鼠标的当前位置坐标信息

document.addEventListener('mousemove', (e) => {
    
    
    console.log(`Mouse X: ${
      
      e.clientX}, Mouse Y: ${
      
      e.clientY}`);
}); 

9、缩短数组

设置 length 属性来缩短数组

const numbers = [1, 2, 3, 4, 5]

numbers.length = 3;

console.log(numbers); // [1, 2, 3]

10、简写条件判断语句

仅在判断条件为 true 时才执行函数,使用 && 简写

// 普通写法
if (condition) {
    
    
    doSomething();
}

// 简写
condition && doSomething(); 

11、console.table() 打印特定格式的表格

语法:

// [] 里面指的是可选参数
console.table(data [, columns]);

参数:

  • data 表示要显示的数据。必须是数组或对象
  • columns 表示一个包含列的名称的数组

示例:

// 一个对象数组,只打印 firstName
function Person(firstName, lastName) {
    
    
    this.firstName = firstName;
    this.lastName = lastName;
}

const john = new Person("John", "Smith");
const jane = new Person("Jane", "Doe");
const emily = new Person("Emily", "Jones");

console.table([john, jane, emily], ["firstName"]);

打印结果:打印表格类型的数据

12、数组去重

const numbers = [2, 3, 4, 4, 2];

console.log([...new Set(numbers)]); // [2, 3, 4]  

13、将字符串转换为数字

const str = '404';

console.log(+str) // 404; 

14、将数字转换为字符串

连接空字符串

const myNumber = 403;

console.log(myNumber + ''); // '403'  

15、从数组中过滤所有虚值

const myArray = [1, undefined, NaN, 2, null, '@denicmarko', true, 3, false];

console.log(myArray.filter(Boolean)); // [1, 2, "@denicmarko", true, 3]  

16、妙用 includes

const myTech = 'JavaScript';
const techs = ['HTML', 'CSS', 'JavaScript'];

// 普通写法
if (myTech === 'HTML' || myTech === 'CSS' || myTech === 'JavaScript') {
    
    
    // do something
}

// includes 写法
if (techs.includes(myTech)) {
    
    
    // do something 
} 

17、用 reduce 对数组求和

const myArray = [10, 20, 30, 40];
const reducer = (total, currentValue) => total + currentValue;

console.log(myArray.reduce(reducer)); // 100   

18、console.log() 样式

使用 CSS 语句DevTools 中设置 console.log 输出的样式

console.log('%c success', 'color: green;font-size: 1.5rem');
console.log('%c 11111', 'color: green;font-size: 1.5rem');
console.log('%c waring', 'color: orange;font-size: 2rem');
console.log('%c Error', 'color: red; font-size: 3rem');

设置输出样式

19、元素的 dataset

dataset 属性访问元素的自定义数据属性 (data-*)

<div id="user" data-name="John Doe" data-age="29" data-something="Some Data">
    John Doe
</div>
<script>
    const user = document.getElementById('user');
  
    console.log(user.dataset); 
    // { name: "John Doe", age: "29", something: "Some Data" }
  
    console.log(user.dataset.name); // "John Doe"
    console.log(user.dataset.age); // "29"
    console.log(user.dataset.something); // "Some Data"
</script>   

20、并发,避免回调

回调很混乱,会导致代码嵌套过深,使用 Promise 替代回调。

// Don't ❌
getUser(function (err, user) {
    
    
  getProfile(user, function (err, profile) {
    
    
    getAccount(profile, function (err, account) {
    
    
      getReports(account, function (err, reports) {
    
    
        sendStatistics(reports, function (err) {
    
    
          console.error(err);
        });
      });
    });
  });
});

// Do ✅
getUser()
  .then(getProfile)
  .then(getAccount)
  .then(getReports)
  .then(sendStatistics)
  .catch((err) => console.error(err));

// or using Async/Await ✅✅

async function sendUserStatistics() {
    
    
  try {
    
    
    const user = await getUser();
    const profile = await getProfile(user);
    const account = await getAccount(profile);
    const reports = await getReports(account);
    return sendStatistics(reports);
  } catch (e) {
    
    
    console.error(err);
  }
}

21、优先使用 map 而不是 switch 语句

既能减少复杂度又能提升性能

// Don't ❌
const getColorByStatus = (status) => {
    
    
  switch (status) {
    
    
    case "success":
      return "green";
    case "failure":
      return "red";
    case "warning":
      return "yellow";
    case "loading":
    default:
      return "blue";
  }
};

// Do ✅
const statusColors = {
    
    
  success: "green",
  failure: "red",
  warning: "yellow",
  loading: "blue",
};

const getColorByStatus = (status) => statusColors[status] || "blue";

22、使用可选链接

const user = {
    
    
  email: "[email protected]",
  billing: {
    
    
    iban: "...",
    swift: "...",
    address: {
    
    
      street: "Some Street Name",
      state: "CA",
    },
  },
};

// Don't ❌
const email = (user && user.email) || "N/A";
const street =
  (user &&
    user.billing &&
    user.billing.address &&
    user.billing.address.street) ||
  "N/A";
const state =
  (user &&
    user.billing &&
    user.billing.address &&
    user.billing.address.state) ||
  "N/A";

// Do ✅
const email = user?.email ?? "N/A";
const street = user?.billing?.address?.street ?? "N/A";
const street = user?.billing?.address?.state ?? "N/A";

23、尽可能使用简写

// Don't ❌
if (isActive === true) {
    
    
  // ...
}

if (firstName !== "" && firstName !== null && firstName !== undefined) {
    
    
  // ...
}

const isUserEligible = user.isVerified() && user.didSubscribe() ? true : false;

// Do ✅
if (isActive) {
    
    
  // ...
}

if (!!firstName) {
    
    
  // ...
}

const isUserEligible = user.isVerified() && user.didSubscribe();

24、避免过多分支

尽早 return 会使你的代码线性化、更具可读性且不那么复杂

// Don't ❌
function addUserService(db, user) {
    
    
  if (!db) {
    
    
    if (!db.isConnected()) {
    
    
      if (!user) {
    
    
        return db.insert("users", user);
      } else {
    
    
        throw new Error("No user");
      }
    } else {
    
    
      throw new Error("No database connection");
    }
  } else {
    
    
    throw new Error("No database");
  }
}

// Do ✅
function addUserService(db, user) {
    
    
  if (!db) throw new Error("No database");
  if (!db.isConnected()) throw new Error("No database connection");
  if (!user) throw new Error("No user");

  return db.insert("users", user);
}

25、将一个可变值传递给函数,你应该直接克隆一个新值返回,而不是直接改变该它

// Don't ❌
function enrollStudentInCourse(course, student) {
    
    
  course.push({
    
     student, enrollmentDate: Date.now() });
}

// Do ✅
function enrollStudentInCourse(course, student) {
    
    
  return [...course, {
    
     student, enrollmentDate: Date.now() }];
}

26、限制参数的数量

// Don't ❌
function sendPushNotification(title, message, image, isSilent, delayMs) {
    
    
  // ...
}

sendPushNotification("New Message", "...", "http://...", false, 1000);

// Do ✅
function sendPushNotification({
     
      title, message, image, isSilent, delayMs }) {
    
    
  // ...
}

const notificationConfig = {
    
    
  title: "New Message",
  message: "...",
  image: "http://...",
  isSilent: false,
  delayMs: 1000,
};

sendPushNotification(notificationConfig);

27、使用默认参数

默认参数比 && || 或在函数体内使用额外的条件语句更干净


// Don't ❌
function printAllFilesInDirectory(dir) {
    
    
  const directory = dir || "./";
  //   ...
}

// Do ✅
function printAllFilesInDirectory(dir = "./") {
    
    
  // ...
}

猜你喜欢

转载自blog.csdn.net/qiaoqiaohong/article/details/121007694