JavaScript 一直在更新,变得越来越好用。从 ES6 开始,加入了很多新写法,能让你的代码更短、更清楚,也常常运行得更快。掌握这些技巧,不仅能让你写代码更快,还能让代码更容易让别人看懂和维护,代码质量也更好。
下面直接介绍 25 个现代 JavaScript 中很实用的技巧和写法,学会它们,写代码真的会轻松很多!
// 老方法
let age = 18;
let canVote;
if (age >= 18) {
canVote = "Yes";
} else {
canVote = "No";
}
console.log(canVote); // 输出: Yes
// 新方法 (三元运算符)
let age = 18;
let canVote = (age >= 18) ? "Yes" : "No"; // 一行搞定
console.log(canVote); // 输出: Yes
// 老方法 (检查空值)
function greet(name) {
let displayName;
if (name === null || name === undefined || name === "") {
displayName = "Guest";
} else {
displayName = name;
}
console.log(`Hello, ${displayName}!`);
}
// 新方法 (|| 短路)
function greet(name) {
const displayName = name || "Guest"; // name 为假值就用 "Guest"
console.log(`Hello, ${displayName}!`);
}
greet("Alice"); // Hello, Alice!
greet(null); // Hello, Guest!
greet(""); // Hello, Guest! (注意:空字符串也被认为是假值)
// 老方法
let isAdmin = true;
if (isAdmin) {
console.log("Admin privileges granted.");
}
// 新方法 (&& 短路)
let isAdmin = true;
isAdmin && console.log("Admin privileges granted."); // 输出: Admin privileges granted.
let isGuest = false;
isGuest && console.log("Guest access."); // 没输出,因为 isGuest 是 false
// 老方法 (加号拼接)
const name = "Bob";
const age = 30;
console.log("My name is " + name + " and I am " + age + " years old.");
// 新方法 (模板字符串)
const name = "Bob";
const age = 30;
console.log(`My name is ${name} and I am ${age} years old.`); // 输出: My name is Bob and I am 30 years old.
注意:箭头函数没有自己的 this,它会用外面函数的 this。
// 老方法
const numbers = [1, 2, 3];
const doubled = numbers.map(function(num) {
return num * 2;
});
// 新方法 (箭头函数)
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2); // 一行,自动返回结果
console.log(doubled); // 输出: [2, 4, 6]
// this 的区别 (重要)
function Timer() {
this.seconds = 0;
// 普通函数:里面的 this 可能指向 window 或 undefined (严格模式)
setInterval(function() {
// console.log(this.seconds); // 错误!this 不对
}, 1000);
// 箭头函数:里面的 this 就是 Timer 实例的 this
setInterval(() => {
this.seconds++;
console.log(this.seconds); // 正确:每秒+1
}, 1000);
}
const myTimer = new Timer();
// 老方法
const colors = ["red", "green", "blue"];
const firstColor = colors[0];
const secondColor = colors[1];
// 新方法 (数组解构)
const colors = ["red", "green", "blue"];
const [firstColor, secondColor] = colors; // 按顺序提取
console.log(firstColor, secondColor); // 输出: red green
const [,, thirdColor] = colors; // 跳过前两个
console.log(thirdColor); // 输出: blue
// 老方法
const user = { name: "Charlie", age: 25, city: "NYC" };
const userName = user.name;
const userAge = user.age;
// 新方法 (对象解构)
const user = { name: "Charlie", age: 25, city: "NYC" };
const { name, age } = user; // 提取 name 和 age
console.log(name, age); // 输出: Charlie 25
const { name: fullName, city } = user; // 把 name 提取到 fullName 变量
console.log(fullName, city); // 输出: Charlie NYC
// 老方法
const arr1 = [1, 2];
const arr2 = [3, 4];
const copiedArr = arr1.slice(); // 复制
const combinedArr = arr1.concat(arr2); // 合并
// 新方法 (展开语法 ...)
const arr1 = [1, 2];
const arr2 = [3, 4];
const copiedArr = [...arr1]; // 复制 arr1
const combinedArr = [...arr1, ...arr2]; // 合并 arr1 和 arr2
console.log(copiedArr, combinedArr); // 输出: [1, 2] [1, 2, 3, 4]
// 老方法
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const copiedObj = Object.assign({}, obj1); // 复制
const mergedObj = Object.assign({}, obj1, obj2); // 合并
// 新方法 (展开语法 ...)
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const copiedObj = { ...obj1 }; // 复制 obj1
const mergedObj = { ...obj1, ...obj2 }; // 合并 obj1 和 obj2
console.log(copiedObj, mergedObj); // 输出: {a:1, b:2} {a:1, b:2, c:3, d:4}
// 覆盖属性
const original = { x: 1, y: 2 };
const updated = { ...original, y: 3, z: 4 }; // 覆盖 y, 添加 z
console.log(updated); // 输出: {x:1, y:3, z:4}
// 老方法 (用 arguments)
function sumAll() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
// 新方法 (剩余参数 ...)
function sumAll(...numbers) { // numbers 是个数组
return numbers.reduce((total, num) => total + num, 0); // 用 reduce 求和
}
console.log(sumAll(1, 2, 3, 4)); // 输出: 10
// 老方法 (用 ||)
function greet(name, greeting) {
name = name || "Guest";
greeting = greeting || "Hello";
console.log(`${greeting}, ${name}!`);
}
// 新方法 (默认参数)
function greet(name = "Guest", greeting = "Hello") {
console.log(`${greeting}, ${name}!`);
}
greet(); // 输出: Hello, Guest! (两个都用默认值)
greet("Frank"); // 输出: Hello, Frank! (greeting 用默认值)
greet("Grace", "Hi"); // 输出: Hi, Grace! (都不用默认值)
// 老方法 (层层检查)
const user = {
profile: {
address: {
street: "Main St"
}
}
};
let streetName;
if (user && user.profile && user.profile.address) {
streetName = user.profile.address.street;
}
console.log(streetName); // 输出: Main St
const invalidUser = {}; // 没有 profile
let invalidStreet;
// 下面如果直接访问 invalidUser.profile.address 会报错!
if (invalidUser && invalidUser.profile && invalidUser.profile.address) {
invalidStreet = invalidUser.profile.address.street; // 不会执行到这里
}
console.log(invalidStreet); // 输出: undefined
// 新方法 (可选链 ?.)
const streetName = user.profile?.address?.street; // 安全访问
console.log(streetName); // 输出: Main St
const invalidStreet = invalidUser.profile?.address?.street; // 遇到 null/undefined 就停,返回 undefined
console.log(invalidStreet); // 输出: undefined
// || 的问题 (会把 0, "", false 也当成无效值)
const count = 0;
const defaultCount_OR = count || 10; // 0 是假值,所以用了 10
console.log(defaultCount_OR); // 输出: 10 (但 0 可能是有效值)
// ?? 正确解决
const count = 0;
const defaultCount_NC = count ?? 10; // 0 不是 null/undefined,保留 0
console.log(defaultCount_NC); // 输出: 0
const emptyString = "";
const defaultString_NC = emptyString ?? "Default"; // "" 不是 null/undefined,保留 ""
console.log(defaultString_NC); // 输出: ""
const undefinedValue = undefined;
const defaultValue_NC = undefinedValue ?? "Fallback"; // undefined 是 nullish,用 "Fallback"
console.log(defaultValue_NC); // 输出: Fallback
// 老方法 (for 循环)
const items = ["apple", "banana", "cherry"];
for (let i = 0; i < items.length; i++) {
console.log(items[i]);
}
// 新方法 (forEach)
const items = ["apple", "banana", "cherry"];
items.forEach(item => console.log(item)); // 对每个 item 执行 console.log
// 输出:
// apple
// banana
// cherry
// 老方法 (for 循环 + push)
const numbers = [1, 2, 3];
const squaredNumbers = [];
for (let i = 0; i < numbers.length; i++) {
squaredNumbers.push(numbers[i] * numbers[i]);
}
// 新方法 (map)
const numbers = [1, 2, 3];
const squaredNumbers = numbers.map(num => num * num); // 计算平方
console.log(squaredNumbers); // 输出: [1, 4, 9]
// 老方法 (for 循环 + if + push)
const ages = [10, 20, 15, 30];
const adults = [];
for (let i = 0; i < ages.length; i++) {
if (ages[i] >= 18) {
adults.push(ages[i]);
}
}
// 新方法 (filter)
const ages = [10, 20, 15, 30];
const adults = ages.filter(age => age >= 18); // 只保留 >=18 的
console.log(adults); // 输出: [20, 30]
// 老方法 (for 循环求和)
const prices = [10, 20, 5];
let totalPrice = 0;
for (let i = 0; i < prices.length; i++) {
totalPrice += prices[i];
}
// 新方法 (reduce 求和)
const prices = [10, 20, 5];
const totalPrice = prices.reduce((sum, price) => sum + price, 0); // 从0开始累加
console.log(totalPrice); // 输出: 35
// 复杂例子: 拍平数组 (把二维数组变一维)
const nestedArrays = [[1, 2], [3, 4], [5]];
const flattened = nestedArrays.reduce(
(acc, currentArray) => [...acc, ...currentArray], // 把当前数组展开拼接到累加器后面
[] // 初始累加器是空数组
);
console.log(flattened); // 输出: [1, 2, 3, 4, 5]
const car = {
make: "Toyota",
model: "Camry",
year: 2020
};
// 获取所有属性名 (keys)
console.log(Object.keys(car)); // 输出: ["make", "model", "year"]
// 获取所有属性值 (values)
console.log(Object.values(car)); // 输出: ["Toyota", "Camry", 2020]
// 获取键值对数组 (entries) - 每个元素是 [key, value]
console.log(Object.entries(car));
/* 输出:
[
["make", "Toyota"],
["model", "Camry"],
["year", 2020]
]
*/
// 用 entries 遍历对象
Object.entries(car).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
/* 输出:
make: Toyota
model: Camry
year: 2020
*/
// 显式返回
const add = (a, b) => {
return a + b;
};
// 隐式返回 (一行表达式)
const add = (a, b) => a + b; // 自动返回 a + b 的结果
console.log(add(5, 3)); // 输出: 8
// 隐式返回对象 (必须加括号)
const createUser = (name, age) => ({ name, age }); // 返回 {name: name, age: age}
console.log(createUser("Dora", 28)); // 输出: { name: 'Dora', age: 28 }
// 老方法 (if 判断赋值)
const value = "hello";
let isTruthy;
if (value) {
isTruthy = true;
} else {
isTruthy = false;
}
// 新方法 (!! 转换)
const value1 = "hello";
const isTruthy1 = !!value1; // !!'hello' -> true
console.log(isTruthy1); // 输出: true
const value2 = 0;
const isTruthy2 = !!value2; // !!0 -> false
console.log(isTruthy2); // 输出: false
const value3 = null;
const isTruthy3 = !!value3; // !!null -> false
console.log(isTruthy3); // 输出: false
// 老方法 (parseInt/parseFloat)
const numStr = "123";
const num = parseInt(numStr, 10);
// 新方法 (+ 转换)
const numStr = "123";
const num = +numStr; // 字符串转整数
console.log(num, typeof num); // 输出: 123 'number'
const floatStr = "123.45";
const floatNum = +floatStr; // 字符串转浮点数
console.log(floatNum, typeof floatNum); // 输出: 123.45 'number'
// 老方法
const firstName = "John";
const lastName = "Doe";
const age = 40;
const user = {
firstName: firstName, // 属性名: 变量名
lastName: lastName,
age: age
};
// 新方法 (属性简写)
const firstName = "John";
const lastName = "Doe";
const age = 40;
const user = {
firstName, // 等同于 firstName: firstName
lastName, // 等同于 lastName: lastName
age // 等同于 age: age
};
console.log(user); // 输出: { firstName: 'John', lastName: 'Doe', age: 40 }
// 老方法 (for 循环遍历值)
const fruits = ["apple", "banana", "orange"];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// 新方法 (for...of)
const fruits = ["apple", "banana", "orange"];
for (const fruit of fruits) { // fruit 直接是数组元素
console.log(fruit);
}
/*
输出:
apple
banana
orange
*/
// 遍历字符串
for (const char of "hello") {
console.log(char);
}
/*
输出:
h
e
l
l
o
*/
// 老方法 (需要 temp 变量)
let a = 1;
let b = 2;
let temp = a;
a = b;
b = temp;
// 新方法 (解构交换)
let a = 1;
let b = 2;
[a, b] = [b, a]; // 右边创建 [2, 1], 左边解构赋值给 a, b
console.log(a, b); // 输出: 2 1
const users = [
{ id: 1, name: "Alice", age: 28 },
{ id: 2, name: "Bob", age: 35 },
{ id: 3, name: "Charlie", age: 22 }
];
console.table(users);
/* 浏览器控制台输出类似表格:
(index) | id | name | age
--------|----|---------|----
0 | 1 | "Alice" | 28
1 | 2 | "Bob" | 35
2 | 3 | "Charlie"| 22
*/
const person = {
firstName: "Jane",
lastName: "Doe",
occupation: "Developer"
};
console.table(person);
/* 浏览器控制台输出类似表格:
(index) | Value
-----------|-----------
firstName | "Jane"
lastName | "Doe"
occupation | "Developer"
*/
这 25 个 JavaScript 技巧,都是现代开发中天天能用上的好东西。学会它们,能实实在在地帮你省下敲代码的时间,让代码看起来更整洁,写起来也更顺手。它们代表了 JavaScript 高效编程的核心方法。
别光看,赶紧在你下一个项目里试试这些技巧!用得越多,它们就越自然地成为你的编程习惯。坚持下去,你很快就能写出更专业、更漂亮的 JavaScript 代码了。收藏这篇文章,随时翻看备查吧!
一直以来进行了比较多的微信小程序开发... 总会接触到一些和官方组件或 api 相关或其无法解决的需求,于是决定在这里小小的整理一下微信小程序开发的一些技巧
小程序提供onShareAppMessage 函数,此函数只支持分享给我微信朋友,小程序如何分享到朋友圈呢?使用canvas绘制一张图片,并用wx.previewImage预览图片,然后长按图片保存图片到手机。
前端新手程序员不知道的 20个小技巧:作为前端开发者,使用双显示器能大幅提高开发效率、学编程最好的语言不是PHP,是English、东西交付之前偷偷测试一遍、问别人之前最好先自己百度,google一下、把觉得不靠谱的需求放到最后做,很可能到时候需求就变了...
本地的 IP 地址是分配给你计算机上的内部硬件或虚拟网卡的本地/私有 IP 地址。根据你的 LAN 配置,上述 IP 地址可能是静态或动态的。公共的 IP 地址是你的 Internet 服务提供商(ISP)为你分配的公共/外部 IP 地址。
使用 :not() 在菜单上应用/取消应用边框;给body添加行高;所有一切都垂直居中;逗号分隔的列表;使用负的 nth-child 选择项目;对图标使用SVG;优化显示文本;对纯CSS滑块使用 max-height;继承 box-sizing
禁用右键点击;禁用搜索文本框;新窗口打开链接;检测浏览器;预加载图片;样式筛选;列高度相同;字体大小调整;返回页面顶部;获取鼠标的xy坐标;验证元素是否为空;替换元素
为你网站的用户留下良好的第一印象是非常必要的。随着商业领域的竞争,拥有一个吸引人的网站可以帮助你脱颖而出。研究表明,如果加载时间超过3秒,会有 40% 的用户放弃访问你的网站
清除浮动主要用于子元素浮动(float)之后,父元素无法撑起高度和宽度。文字少时居中,多时靠左因为div嵌套着p,所以p的尺寸并不会超过div。但是要注意,当p的内容为英文单词组成的时候
这次我们主要来分享11个在日常教程中不常被提及的JavaScript小技巧,他们往往在我们的日常工作中经常出现,但是我们又很容易忽略。Set类型是在ES6中新增的,它类似于数组,但是成员的值都是唯一的
为什么要在JavaScript里写CSS?避免命名全局污染,条件和动态样式(比如选择主题色之类的),在框架层面进行限制或补充(比如补全供应商前缀),避免业务人员使用奇技淫巧
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!