龚庆洪 發表於 2026-4-30 11:31:00

JavaScript 的25个高级特性

<h1 data-id="heading-0">🧑‍💻 写在开头</h1>
<p>点赞 + 收藏 === 学会🤣🤣🤣</p>
<div>
<div>
<p>很多前端同学写 JavaScript 写久了,会觉得语言特性都已经用得差不多了:函数、数组、对象、Promise……没什么新鲜感。</p>
<p>但其实,JavaScript 还有不少被低估的语法和技巧。<br>
它们可能是规范里的冷门细节,可能是 ES6+ 新增的语法糖,也可能是一些看似奇怪但非常实用的特性。</p>
<p>本文整理了 <strong>25 个实用又有点“冷门”的 JavaScript 高级特性</strong>,每一个都配有示例和讲解。<br>
如果你想在代码中写出更优雅的实现,或者在面试时展示更深的理解,这篇内容绝对值得收藏。</p>
<h2 data-id="heading-0">1 、 循环和块语句的标签(Labelled Statements)</h2>
<p>JavaScript 允许给循环和代码块加上“标签”,然后可以结合 <code>break</code> 和 <code>continue</code> <strong>精确控制流程</strong>。</p>

</div>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">outerLoop: for (let i = 0; i &lt; 5; i++) { // 定义外层循环,并打上标签 outerLoop
    innerLoop: for (let j = 0; j &lt; 5; j++) { // 定义内层循环,并打上标签 innerLoop
      if (i === 2 &amp;&amp; j === 2) break outerLoop; // 当 i 和 j 都等于 2 时,直接跳出外层循环
      console.log(`i=${i}, j=${j}`); // 打印当前循环的 i 和 j 值
    }
}</pre>
</div>
<h2 data-id="heading-1">2 、 逗号运算符(Comma Operator)</h2>
<p>逗号运算符可以让多个表达式依次执行,并返回最后一个表达式的结果。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">let a = (1, 2, 3); // 执行 1、2、3,最终结果为 3,所以 a = 3</pre>
</div>
</div>
<h2 data-id="heading-2">3 、 超越字符串拼接的标签模板字面量(Tagged Template Literals)</h2>
<p>标签模板不仅能拼接字符串,还可以用于创建 DSL(领域专用语言)、转义用户输入、防止 XSS 或实现国际化。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">function htmlEscape(strings, ...values) { // 定义一个标签函数,接收字符串数组和变量值
    // 示例实现(可以在此处理 values,防止恶意注入)
}</pre>
</div>
<h2 data-id="heading-3">4 、 代码块中的函数声明(Function Declarations Inside Blocks)</h2>
<p>虽然不推荐,但 JavaScript 允许在代码块里声明函数。在严格模式和非严格模式下,行为可能不同。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">if (true) {
    function test() { return "Yes"; } // 在 if 分支里定义函数
} else {
    function test() { return "No"; } // 在 else 分支里定义函数
}
test(); // 在不同环境下结果可能不同,有的环境返回 "Yes",有的报错</pre>
</div>
<h2 data-id="heading-4">5 、 void 运算符</h2>
<p><code>void</code>&nbsp;运算符会执行一个表达式,然后返回&nbsp;<code>undefined</code>,常用于避免链接跳转。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">void (0); // 执行 0,但结果始终是 undefined</pre>
</div>
<h2 data-id="heading-5">6 、 用位运算符加速数学运算(Bitwise Operators for Quick Math)</h2>
<p>位运算符(如&nbsp;<code>|</code>&nbsp;和&nbsp;<code>&amp;</code>)能快速进行一些数学操作,代价是可读性降低。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">let floor = 5.95 | 0; // 使用按位或运算符去掉小数部分,相当于 Math.floor(5.95),结果为 5</pre>
</div>
<h2 data-id="heading-6">7、 with 语句操作对象(with Statement)</h2>
<p><code>with</code>&nbsp;可以把对象添加到作用域链中,让代码更简短。但会降低可读性和性能,因此不推荐。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">with(document.getElementById("myDiv").style) { // 将 myDiv.style 属性加入作用域链
    background = "black"; // 相当于设置 myDiv.style.background = "black"
    color = "white"; // 相当于设置 myDiv.style.color = "white"
}</pre>
</div>
<h2 data-id="heading-7">8 、 自动分号插入(ASI)</h2>
<p>JavaScript 会尝试自动补全缺失的分号,但依赖它可能会导致意料之外的错误。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">let x = 1 // 这里少了分号,JS 会尝试补齐
let y = 2 // 这里同样
= // 如果缺少分号,可能会被解析为函数调用而出错</pre>
</div>
<h2 data-id="heading-8">9 、 in 运算符检查属性存在</h2>
<p><code>in</code>&nbsp;运算符可以判断对象是否拥有某个属性,而无需读取属性值。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">"toString" in {}; // true,因为所有对象都继承自 Object.prototype,它有 toString 方法</pre>
</div>
<h2 data-id="heading-9">10、 instanceof vs typeof</h2>
<p><code>instanceof</code>&nbsp;用于检查对象的原型链,<code>typeof</code>&nbsp;返回操作数的类型字符串。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">function Person() {} // 定义构造函数
let person = new Person(); // 创建实例
console.log(person instanceof Person); // true,person 的原型链包含 Person.prototype
console.log(typeof person); // "object",因为 person 是对象</pre>
</div>
<h2 data-id="heading-10">11 、 ES6 中的块级函数(Block-Level Functions)</h2>
<p>在 ES6 中,函数也可以像&nbsp;<code>let</code>、<code>const</code>&nbsp;一样成为块级作用域。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">{
    function test() {
      return "block scoped"; // 在块中定义函数
    }
}
console.log(typeof test); // 在非严格模式下可能是 "function",严格模式下可能是 "undefined"</pre>
</div>
<h2 data-id="heading-11">12 、 debugger 语句</h2>
<p>使用&nbsp;<code>debugger</code>&nbsp;可以在开发工具打开时中断代码执行,方便调试。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">function problematicFunction() {
    debugger; // 执行到这里会自动暂停,开发者可在控制台调试
}</pre>
</div>
<h2 data-id="heading-12">13、 eval() 动态执行代码</h2>
<p><code>eval</code>&nbsp;可以把字符串当作 JavaScript 代码执行,但有严重的性能和安全隐患。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">eval("let a = 1; console.log(a);"); // 执行字符串代码,输出 1</pre>
</div>
<h2 data-id="heading-13">14、 非标准的&nbsp;proto&nbsp;属性</h2>
<p><code>__proto__</code>&nbsp;可以设置对象的原型,但它是非标准的。推荐使用&nbsp;<code>Object.getPrototypeOf</code>&nbsp;和&nbsp;<code>Object.setPrototypeOf</code>。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">let obj = {}; // 定义一个对象
obj.__proto__ = Array.prototype; // 修改原型为数组原型(不推荐)</pre>
</div>
<h2 data-id="heading-14">15、 document.write() 直接写入页面</h2>
<p><code>document.write()</code>&nbsp;可以直接往页面写内容,但可能影响加载性能和安全。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">document.write("&lt;h1&gt;Hello World!&lt;/h1&gt;"); // 直接往页面写入 h1 标签</pre>
</div>
<h2 data-id="heading-15">16 、链式赋值(Chained Assignment)</h2>
<p>JavaScript 支持链式赋值,可以一次性给多个变量赋同一个值。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">let a, b, c; // 定义变量
a = b = c = 5; // 三个变量都被赋值为 5</pre>
</div>
<h2 data-id="heading-16">17 、in 运算符检测属性是否存在</h2>
<p>再次强调,<code>in</code>&nbsp;可以检测对象属性是否存在,而不必读取值。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">const car = {
    make: 'Toyota', // 定义属性 make
    model: 'Corolla' // 定义属性 model
};
console.log('make' in car); // true,因为 car 对象有 make 属性</pre>
</div>
<h2 data-id="heading-17">18、 对象属性简写(Object Property Shorthand)</h2>
<p>当变量名和对象属性名相同时,可以直接写简写形式。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">const name = 'Alice'; // 定义变量 name
const age = 25; // 定义变量 age
const person = { name, age }; // 简写形式,相当于 { name: name, age: age }</pre>
</div>
<h2 data-id="heading-18">19 、 默认参数值与解构结合</h2>
<p>函数参数可以结合解构和默认值,让函数定义更灵活。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">function createPerson({ name = '匿名', age = 0 } = {}) { // 参数解构,提供默认值
   console.log(`姓名: ${name}, 年龄: ${age}`); // 打印参数
}
createPerson({ name: 'Alice' }); // 姓名: Alice, 年龄: 0
createPerson(); // 姓名: 匿名, 年龄: 0</pre>
</div>
<h2 data-id="heading-19">20 、使用 Array.fill() 初始化数组</h2>
<p><code>fill()</code>&nbsp;方法可以快速初始化数组。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">const initialArray = new Array(5).fill(0); // 创建一个长度为 5 的数组,并用 0 填充,结果 </pre>
</div>
<h2 data-id="heading-20">21 、 Array.includes() 判断元素是否存在</h2>
<p>比&nbsp;<code>indexOf()</code>&nbsp;更直观的方法。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">const fruits = ['apple', 'banana', 'mango']; // 定义数组
console.log(fruits.includes('banana')); // true,数组中包含 banana</pre>
</div>
<h2 data-id="heading-21">22、 解构时使用别名(Destructuring Aliases)</h2>
<p>在对象解构时,可以为属性赋予新的变量名。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">const obj = { x: 1, y: 2 }; // 定义对象
const { x: newX, y: newY } = obj; // 使用别名,x → newX,y → newY
console.log(newX); // 1</pre>
</div>
<h2 data-id="heading-22">23 、 空值合并运算符(Nullish Coalescing Operator)</h2>
<p><code>??</code>&nbsp;仅在值为&nbsp;<code>null</code>&nbsp;或&nbsp;<code>undefined</code>&nbsp;时使用默认值,而不会误判&nbsp;<code>0</code>&nbsp;或&nbsp;<code>false</code>。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">const count = 0; // count 值为 0
console.log(count ?? 10); // 输出 0,因为 count 不是 null 或 undefined</pre>
</div>
<h2 data-id="heading-23">24 、 动态函数名(Dynamic Function Names)</h2>
<p>通过计算属性名,可以定义动态函数。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">const dynamicName = 'func'; // 定义动态方法名
const obj = {
    () { // 使用计算属性名定义方法
      return '动态函数名!';
    }
};
console.log(obj.func()); // 调用 obj.func(),输出 "动态函数名!"</pre>
</div>
<h2 data-id="heading-24">25、 类的私有字段(Private Fields in Classes)</h2>
<p>使用&nbsp;<code>#</code>&nbsp;前缀可以定义私有属性,外部无法直接访问。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">class Counter {
    #count = 0; // 定义私有属性 #count,外部不可访问

    increment() {
      this.#count++; // 内部方法可以访问私有属性
    }

    getCount() {
      return this.#count; // 提供访问方法
    }
}</pre>
</div>
<div>
<h3 id="tid-D8HBxE">如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。</h3>
</div>
<p><em><img src="https://img2024.cnblogs.com/blog/2149129/202501/2149129-20250122165814748-630765389.png" alt="" loading="lazy"></em></p><br><br>
来源:https://www.cnblogs.com/smileZAZ/p/19957510
頁: [1]
查看完整版本: JavaScript 的25个高级特性