ESLint規則中的JavaScript知識

網上關於ESLint的介紹,安裝,配置和使用等文章已經有不少了,寫的都很全面,還不清楚的同窗能夠先去簡單瞭解一下,本文就不做介紹了。javascript

本文的主要內容是經過ESLint的規則(Rules),從中學到 JavaScript 的基礎知識。同時,提早了解這些規則的含義與理由,有助於在之後的開發中提早規避風險,提升代碼質量。java

如下是從官網的 Rules 列表中摘取的部分規則,歡迎你們補充,共同窗習。程序員

Possible Errors

getter-return:強制在 getter 屬性中出現一個 return 語句。每一個 getter 都指望有返回值。正則表達式

no-compare-neg-zero:禁止與 -0 進行比較。像 x === -0 的代碼對於 +0-0 都有效。你可使用 Object.is(x, -0)。例:編程

// incorrect
if (x === -0) {
    // doSomething()...
}

// correct
if (x === 0) {
    // doSomething()...
}
if (Object.is(x, -0)) {
    // doSomething()...
}
複製代碼

no-cond-assign: 禁止在條件語句中出現賦值操做符。在條件語句中,很容易將一個比較運算符(像 ==)錯寫成賦值運算符(如 =)。在條件語句中,使用賦值操做符是有效的。然而,很難判斷某個特定的賦值是不是有意爲之。該規則有兩個可選值:數組

  • except-parens:默認值,容許條件語句中出現賦值操做符,前提是它們被圓括號括起來。
  • always: 禁止條件語句中出現賦值語句。

no-console:禁止調用 console 對象的方法。console 這樣的消息被認爲是用於調試的,生產環境中不該該有關於console 的語句。同時,被console.log的變量是不會被垃圾回收的,一旦多起來會致使內存泄漏。該規則有可配置選項allow,它的值是個字符串數組,包含容許使用的console對象的方法。例如: allow: ["warn", "error"]容許使用console對象上的warnerror方法。promise

no-constant-condition:禁止在條件中使用常量表達式。瀏覽器

no-dupe-args: 禁止在 function 定義中出現重複的參數。安全

no-dupe-keys: 禁止在對象字面量中出現重複的鍵。app

no-duplicate-case: 禁止在 switch 語句中的 case 子句中出現重複的測試表達式。

no-empty: 禁止空語句塊出現,該規則會忽略包含一個註釋的語句塊。例如,在 try 語句中,一個空的 catchfinally 語句塊意味着程序應該繼續執行,不管是否出現錯誤。該規則有個可配置的選項 allowEmptyCatch: true 容許出現空的 catch 子句。

no-ex-assign:禁止對 catch 子句中的異常從新賦值。若是意外地(或故意地)給異常參數賦值,是不可能引用那個位置的錯誤的。因爲沒有 arguments 對象提供額外的方式訪問這個異常,對它進行賦值絕對是毀滅性的。

no-func-assign:禁止對 function 聲明從新賦值。例如:

// incorrect
function foo() {}
foo = bar;

function foo() {
 foo = bar;
}
複製代碼

JavaScript 函數有兩種形式:函數聲明 function foo() { ... } 或者函數表達式 var foo = function() { ... } 。雖然 JavaScript 解釋器能夠容忍對函數聲明進行覆蓋或從新賦值,但一般這是個錯誤,應該避免。

no-inner-declarations:禁止在嵌套的塊中出現變量聲明或 function 聲明。可選值(string):functions(默認)both(禁止 function 和 var 聲明出如今嵌套的語句塊中)。這隻適用於函數聲明,命名的或匿名的函數表達式是能夠出如今任何容許的地方。在 ES6 以前的 JavaScript 中,函數聲明只能在程序或另外一個函數體的頂層。因爲變量聲明提高,把聲明放在程序或函數體的頂部會使代碼更清晰,在任何地方隨意聲明變量的作法一般是不可取的。由於在ES6中的 letconst 不會被提高,所以它們不受此規則影響。

no-irregular-whitespace:禁止在字符串和註釋以外不規則的空白。無效的或不規則的空白會致使 ECMAScript 5 解析問題,也會使代碼難以調試(相似於混合 tab 和空格的狀況)。 引發的問題以及禁止出現的不正常字符

no-obj-calls:禁止把全局對象做爲函數調用,如 MathJSONReflect等。

no-sparse-arrays:禁用稀疏數組,也就是逗號以前沒有任何元素的數組。該規則不適用於緊隨最後一個元素的拖尾逗號的狀況。例如:

// incorrect
var arr = [,,];
var colors = [ "red",, "blue" ];

// correct
var arr = [];
var arr = new Array(23);
var colors = [ "red", "blue", ];
複製代碼

no-unexpected-multiline:禁止使用使人困惑的多行表達式。在 JavaScript 中,分號一般是可選的,由於會自動插入分號(ASI)。換行不結束語句,書寫錯誤遺漏了分號,這些異常會致使兩個不相干的連續的行被解釋爲一個表達式。特別是對於一個沒有分號的代碼風格,讀者可能會忽略這些錯誤。儘管語法上是正確的,代碼執行時可能會拋出異常。

no-unreachable:禁止在 returnthrowcontinuebreak 語句後出現不可達代碼。由於這些語句無條件地退出代碼塊,其以後的任何語句都不會被執行。

use-isnan:禁止與 NaN 的比較,要求調用 isNaN()檢查 NaN。在 JavaScript 中,NaNNumber 類型的一個特殊值。它被用來表示非數值(Not A Number),這裏的數值是指在 IEEE 浮點數算術標準中定義的雙精度64位格式的值。

console.log(typeof NaN); // "number"
複製代碼

由於在 JavaScriptNaN 獨特之處在於它不等於任何值,包括它自己,與 NaN 進行比較的結果也使人困惑:

console.log(NaN !== NaN); // true
console.log(NaN === NaN); // false
複製代碼

所以,使用 Number.isNaN() 或 全局的 isNaN() 函數來測試一個值是不是 NaN

valid-typeof:強制 typeof 表達式與有效的字符串進行比較。對於絕大多數用例而言,typeof 操做符的結果是如下字符串字面量中的一個:"undefined""object""boolean""number""string""function""symbol"。把 typeof 操做符的結果與其它字符串進行比較,一般是個書寫錯誤。例:

// incorrect
typeof foo === "strnig"
typeof foo == "undefimed"
typeof bar != "nunber"
typeof bar !== "function"

// correct
typeof foo === "string"
typeof bar == "undefined"
typeof foo === baz
typeof bar === typeof qux
複製代碼

Best Practices

accessor-pairs:強制getter/setter成對出如今對象中。該規則強制一種編碼風格:對於每一個屬性,若是定義了setter,也必須定義相應的 getter。沒有 getter ,你不能讀取這個屬性,該屬性也就不會被用到。

array-callback-return:強制數組某些方法的回調函數中有 return 語句。 Array 有一些方法用來過濾、映射和摺疊。若是你忘記了在它們的回調函數中寫 return 語句,這種狀況多是個錯誤。須要 return 語句的方法有:

  • Array.from
  • Array.prototype.every
  • Array.prototype.filter
  • Array.prototype.find
  • Array.prototype.findIndex
  • Array.prototype.map
  • Array.prototype.reduce
  • Array.prototype.reduceRight
  • Array.prototype.some
  • Array.prototype.sort

default-case:要求 wwitch 語句中有 default 分支,即便默認分支中沒有任何代碼。開發人員可能忘記定義默認分支而致使程序發生錯誤,因此明確規定定義默認分支是很好的選擇。或者也能夠在最後一個 case 分支下,使用 // no default 來代表此處不須要 default 分支。

eqeqeq:要求使用 ===!== 代替 ==!= 操做符。緣由是 ==!= 在比較時會做強制轉型,有時會產生反作用甚至異常。 有兩個可選值:

  • always : 強制在任何狀況下都使用 ===!==
  • smart: 除了如下這些狀況外,強制使用 ===!==
    • 比較兩個字面量的值
    • 比較 typeof 的值
    • null 進行比較

no-alert:禁用 alertconfirmpromptJavaScriptalertconfirmprompt 被普遍認爲是突兀的 UI 元素,應該被一個更合適的自定義的 UI 界面代替。此外, alert 常常被用於調試代碼,部署到生產環境以前應該刪除。所以,當遇到 alertpromptconfirm 時,該規則將發出警告。

no-caller:禁用 arguments.callerarguments.callee。它們的使用使一些代碼優化變得不可能。在 JavaScript 的新版本中它們已被棄用,同時在 ECMAScript 5 的嚴格模式下,它們也是被禁用的。

no-case-declarations:禁止詞法聲明 (letconstfunctionclass) 出如今 casedefault 子句中。詞法聲明在整個 switch 語句塊中是可見的,可是它只有在運行到它定義的 case 語句時,纔會進行初始化操做。 爲了保證詞法聲明語句只在當前 case 語句中有效,將你子句包裹在塊中。例:

// incorrect
switch (foo) {
    case 1:
        let x = 1;
        break;
    case 2:
        const y = 2;
        break;
    case 3:
        function f() {}
        break;
    default:
        class C {}
}

// correct
switch (foo) {
    // 下面的 case 子句使用括號包裹在了塊中
    case 1: {
        let x = 1;
        break;
    }
    case 2: {
        const y = 2;
        break;
    }
    case 3: {
        function f() {}
        break;
    }
    case 4:
        // 由於函數做用域提高,使用 var 聲明而不使用括號包裹是合法的。
        var z = 4;
        break;
    default: {
        class C {}
    }
}
複製代碼

no-else-return:禁止 if 語句中 return 語句以後有 else 塊。若是 if 塊中包含了一個 return 語句,else 塊就成了多餘的了。能夠將其內容移至塊外。例:

// incorrect
function foo() {
    if (x) {
        return y;
    } else {
        return z;
    }
}

// correct
function foo() {
    if (x) {
        return y;
    }

    return z;
}
複製代碼

no-empty-function:禁止出現空函數。空函數能下降代碼的可讀性,若是一個函數包含了一條註釋,它將不會被認爲有問題。該規則有一個選項,配置所容許的空函數列表,默認爲空數組。

no-empty-pattern:禁止使用空解構模式。當使用解構賦值時,可能建立了一個不起做用的模式。把空的花括號放在嵌入的對象的解構模式右邊時,就會產生這種狀況。例:

// incorrect
var {} = foo;
var [] = foo;
var {a: {}} = foo;
var {a: []} = foo;
function foo({}) {}
function foo([]) {}
function foo({a: {}}) {}
function foo({a: []}) {}

// correct
var {a = {}} = foo;
var {a = []} = foo;
function foo({a = {}}) {}
function foo({a = []}) {}
複製代碼

no-eq-null:禁止使用 ==!= 操做符與 null 進行比較。當你進行比較時可能得意想不到的的結果,由於 nullnullundefined 的比較結果都爲 true

no-eval:禁用 eval()JavaScript 中的 eval() 函數是有潛在危險的,並且常常被誤用。eval() 在大多數狀況下能夠被更好的解決問題的方法代替。

no-global-assign:禁止對原生對象或只讀的全局對象進行賦值。JavaScript 環境包含不少內置的全局變量,好比瀏覽器環境的 windowNode.js 中的 process。在幾乎全部狀況下,你都不該該給全局變量賦值,由於這樣作可能會到致使沒法訪問到重要的功能。

no-implicit-globals:禁止在全局範圍下使用 var 和命名的 function 聲明。由於這樣,會做爲 window 對象的一個屬性或方法存在。全局變量應該顯式地賦值給 windowself。不然,局部變量應該包裹在 IIFE 中。該規則不適用於 ESCommonJS 的模塊,由於它們有本身的模塊做用域。

no-invalid-this:禁止 this 關鍵字在類或類對象以外出現。該規則 在嚴格模式下生效,在嚴格模式下,類或者類對象以外的 this 關鍵字多是 undefined 而且引起 TypeError

no-iterator:禁用 __iterator__ 屬性。這個屬性如今廢棄了,因此不該再使用它。如今,應該使用 ES6 迭代器和生成器。

no-lone-blocks:禁用沒必要要的嵌套塊。在 ES6 以前,由花括號分隔開的獨立代碼塊不會建立新的做用域,也就不起什麼做用,代碼塊是多餘的。例:

{ // 該括號對 foo 不起任何做用
    var foo = bar();
}
複製代碼

ES6 中,若是出現一個塊級綁定 (letconst),類聲明或函數聲明(在嚴格模式下),代碼塊就會建立一個新的做用域。在這些狀況下,代碼塊不會被認爲是多餘的。

no-multi-spaces:禁止在邏輯表達式、條件表達式、聲明、數組元素、對象屬性、序列和函數參數周圍使用多個空格。

no-new:禁止使用 new 關鍵字調用構造函數但卻不將結果賦值給一個變量。好比 new Thing() 建立的對象會被銷燬由於它的引用沒有被存儲在任何地方。

no-new-func:禁止對 Function 對象使用 new 操做符。JavaScript 中可使用 Function 構造函數建立一個函數,如 var x = new Function("a", "b", "return a + b");,把一個字符串傳給 Function 構造函數,你須要引擎解析該字符串,這一點同調用 eval 函數同樣,應該避免這樣使用。

no-new-wrappers:禁止對 StringNumberBoolean 使用 new 操做符。在 JavaScript 中有3種原始類型包裝對象:字符串,數字和布爾值。它們所表明的構造器分別爲 StringNumberBoolean。 下面的例子使用 new 操做符後使用 typeof 將返回 "object",而不是 "string", "number"「boolean」,這意味着可能與預期不符。

var stringObject = new String("Hello world");
var numberObject = new Number(33);
var booleanObject = new Boolean(false);
複製代碼

並且,每一個對象的判斷都是真,這意味着每一個 Boolean 的實例都會返回 true,即便它們實際的值是 false。因此,應該避免使用 new 來使用原始包裝類型。通常狀況下,下面這樣使用便可。

var text = String(someValue);
var num = Number(someValue);
var bol = Boolean(someValue);
複製代碼

no-param-reassign:禁止對 function 的參數進行從新賦值。好比:function f(arg) { arg = 1; }function f(obj) { obj.num = 1; }。對函數參數中的變量進行賦值可能會誤導讀者,致使混亂,也會改變 arguments 對象。若是參數是引用類型,好比對象,修改對象的屬性會影響到傳入函數的那個原始對象。若是須要修改能夠複製一份數據再改。

no-proto:禁用 __proto__ 屬性。__proto__ 屬性在 ECMAScript 3.1 中已經被棄用,而且不該該在代碼中使用。應該使用 getPrototypeOf 方法替代 __proto__getPrototypeOf是獲取原型的首選方法。

no-redeclare:禁止屢次聲明同一變量。這會使變量實際聲明和定義的位置混亂不堪。

no-return-assign:禁止在 return 語句中使用賦值語句。由於很難判定 return 語句的意圖。多是賦值,但賦值的意圖也可能不明確,也多是比較。

no-self-assign:禁止自身賦值。自身賦值不起任何做用。

no-self-compare:禁止自身比較。幾乎沒有場景須要你比較變量自己。

no-unmodified-loop-condition:禁用一成不變的循環條件。循環條件中的變量在循環中是要常常改變的。若是不是這樣,那麼多是個錯誤。

no-useless-call:禁止沒必要要的 .call().apply()。例以下面的代碼與 foo(1, 2, 3)效果相同:

foo.call(undefined, 1, 2, 3);
foo.apply(undefined, [1, 2, 3]);
foo.call(null, 1, 2, 3);
foo.apply(null, [1, 2, 3]);
複製代碼

函數的調用能夠寫成 Function.prototype.call()Function.prototype.apply(),可是 Function.prototype.call()Function.prototype.apply() 比正常的函數調用效率低。

no-useless-concat:禁止沒必要要的字符串字面量或模板字面量的鏈接。把兩個字符拼接在一塊兒是沒有必要的,好比: var foo = "a" + "b"; 直接寫做 var foo = "ab"; 便可。

no-useless-escape:禁用沒必要要的轉義字符。對字符串、模板字面量和正則表達式中的常規字符進行轉義,不會對結果產生任何影響,但它是多餘的。

// 沒必要要使用轉義符
"\'";
'\"';
"\#";
"\e";
`\"`;
`\"${foo}\"`;
`\#{foo}`;
/\!/;
/\@/;

// 須要使用轉義符
"\"";
'\'';
"\x12";
"\u00a9";
"\371";
"xs\u2111";
`\``;
`\${${foo}}`;
`$\{${foo}}`;
/\\/g;
/\t/g;
/\w\$\*\^\./;
複製代碼

prefer-promise-reject-errors:要求使用 Error 對象做爲 Promise 拒絕的緣由。Error 對象會自動存儲堆棧跟蹤,在調試時,經過它能夠用來肯定錯誤是從哪裏來的。若是 Promise 使用了非 Error 的值做爲拒絕緣由,那麼就很難肯定 reject 在哪裏產生。

require-await:禁止使用不帶 await 表達式的 async 函數。async 函數不包含 await 函數可能不是重構想要的結果。

vars-on-top:要求全部的 var 聲明出如今它們所在的做用域頂部。默認的,JavaScript 的解析器會隱式的將變量的聲明移到它們所在做用域的頂部("變量提高")。這個規則迫使程序員經過手動移動變量聲明到其做用域的頂部來實現這個行爲,有助於提升可維護性。

wrap-iife:要求 IIFE 使用括號括起來。你能夠當即調用函數表達式,而不是函數聲明。建立一個當即執行函數 (IIFE) 的一個通用技術是用括號包裹一個函數聲明。括號內的函數被解析爲一個表達式,而不是一個聲明。

Variable Declarations

no-delete-var:禁止刪除變量。delete 的目的是刪除對象的屬性。使用 delete 操做刪除一個變量可能會致使意外狀況發生。

no-label-var:不容許標籤與變量同名。

no-shadow:禁止變量聲明與外層做用域的變量同名。例:

var a = 3;
function b() {
    var a = 10;
}
複製代碼

b() 做用域中的 a 覆蓋了全局環境中的 a。這會混淆讀者而且在 b 中不能獲取全局變量。

no-shadow-restricted-names:禁止重定義遮蔽關鍵字。全局對象的屬性值 (NaNInfinityundefined)和嚴格模式下被限定的標識符 evalarguments 也被認爲是關鍵字。重定義關鍵字會產生意想不到的後果且易迷惑其餘讀者。

no-undef-init:禁止將變量初始化爲 undefined。在 JavaScript 中,聲明一個變量但未初始化,變量會自動得到 undefined 做爲初始值,所以,初始化變量值爲 undefined 是多餘的。

no-unused-vars:禁止出現未使用過的變量。已聲明的變量在代碼裏未被使用過,就像是因爲不完整的重構而致使的遺漏錯誤。這樣的變量增長了代碼量,而且混淆讀者。

no-use-before-define:禁止在變量定義以前使用它們。在 ES6 標準以前的 JavaScript 中,某個做用域中變量和函數的聲明會被提早到做用域頂部("變量提高"),因此可能存在這種狀況:此變量在聲明前被使用。這會擾亂讀者。在 ES6 中,塊級綁定 (letconst) 引入"暫時性死區",當企圖使用未聲明的變量會拋出 ReferenceError

Node.js and CommonJS

global-require:要求 require() 出如今頂層模塊做用域中。在 Node.js 中,使用 require() 函數引入依賴的模塊,它在模塊頂層被調用,這樣更容易識別依賴關係。當它們在深層次嵌套在函數和其它語句時,就很難識別依賴。由於 require() 是同步加載的,在其它地方使用時,會致使性能問題。此外,ES6 模塊要求 importexport 語句只能放在模塊頂部。

handle-callback-err:要求回調函數中有容錯處理。在 Node.js 中,最廣泛的處理異步行爲是回調模式。這個模式指望一個 Error 對象或 null 做爲回調的第一個參數。若是忘記處理這些錯誤會致使你的應用程序出現一些很是奇怪的行爲。

no-buffer-constructor:禁用 Buffer() 構造函數。在 Node.js 中,Buffer 構造函數的行爲取決於其參數的類型。將用戶輸入的參數傳遞給 Buffer(),而不驗證其類型,會致使安全漏洞,好比遠程內存泄漏和拒絕服務。所以,Buffer 構造函數已經被棄用,不該該再使用。使用 Buffer.fromBuffer.allocBuffer.allocUnsafe 生成器方法代替。

no-new-require:禁止調用 require 時使用 new 操做符。require 方法被用來引入不一樣文件中模塊。某些模塊可能返回一個構造函數,會出現 var app = new (require(moduleName)); 的狀況,這樣可能會引發潛在的混亂,應該避免這樣的狀況,分紅多行寫會使你的代碼更清晰。

Stylistic Issues

關於空格,換行,聲明,標點符號等風格規則,很是主觀,依據我的或團隊編碼風格自定義,這裏不做介紹。

ECMAScript 6

這些規則只與 ES6 有關,即一般所說的 ES2015

arrow-body-style:要求箭頭函數體使用大括號。爲了規避箭頭函數語法可能帶來的錯誤,當函數體只有一行的時候,若不加大括號,會默認把這行代碼的返回結果給隱式 return。當函數體有多行的時候,必須使用大括號,而且須要本身寫 return 語句。可選值有:

  • always--強制始終用大括號
  • as-needed--當大括號是能夠省略的,強制不使用它們
  • never--禁止在函數體周圍出現大括號

arrow-parens:要求箭頭函數的參數使用圓括號。箭頭函數體只有一個參數時,能夠省略圓括號。其它任何狀況,參數都應被圓括號括起來。該規則強制箭頭函數中圓括號的使用的一致性。可選值有:

  • always--要求在全部狀況下使用圓括號將參數括起來。
  • as-needed--當只有一個參數時容許省略圓括號。

constructor-super:要求在構造函數中有 super() 的調用。派生類中的構造函數必須調用 super()。非派生類的構造函數不能調用 super(), 不然 JavaScript 引擎將引起一個運行時錯誤。

no-class-assign:禁止修改類聲明的變量。大多數狀況下,class A {}; A = 0;這樣的修改是個錯誤。

no-const-assign:禁止修改 const 聲明的變量。

no-dupe-class-members:禁止類成員中出現重複的名稱。若是類成員中有同名的聲明,最後一個聲明將會默默地覆蓋其它聲明,它可能致使意外的行爲。

no-duplicate-imports:禁止重複模塊導入。爲每一個模塊使用單一的 import 語句會是代碼更加清新,由於你會看到從該模塊導入的全部內容都在同一行。import { A } from 'module'; import { B } from 'module'; 應該合併爲 import { A, B } from 'module'; 會使導入列表更加簡潔。

no-new-symbol:禁止 Symbolnew 一塊兒使用。Symbol 應該做爲函數調用。

no-this-before-super:禁止在構造函數中,在調用 super() 以前使用 thissuper。在派生類的構造函數中,若是在調用 super() 以前使用 thissuper,它將會引起一個引用錯誤。

no-useless-rename:禁止在 importexport 和解構賦值時將引用重命名爲相同的名字。ES2015 容許在 importexport 和解構賦值時對引用進行重命名。引用有可能被重命名成相同的名字。import { foo as foo } from "bar"; 這和沒有重命名是等價的,所以這種操做徹底冗餘。

no-var:要求使用 letconst 而不是 var。塊級做用域在不少其餘編程語言中很廣泛,能幫助程序員避免錯誤。

object-shorthand:要求或禁止對象字面量中方法和屬性使用簡寫語法。ECMAScript 6 提供了簡寫的形式去定義對象中的方法和屬性。你能夠配置該規則來要求或禁止簡寫。

// 屬性
var foo = {
    x: x,
    y: y,
    z: z,
};
// 等效於
var foo = { x, y, z }

// 方法
var foo = {
    a: function() {},
    b: function() {}
};

//等效於
var foo = {
    a() {},
    b() {}
}
複製代碼

prefer-const:要求使用 const 聲明那些聲明後再也不被修改的變量。若是一個變量不會被從新賦值,最好使用 const 進行聲明。從而減小認知負荷,提升可維護性。

prefer-rest-params:要求使用剩餘參數而不是 arguments。剩餘參數獲得的是真正的數組,而 arguments是類數組,沒有 Array.prototype 方法,有時候還須要再轉化一步。剩餘參數的語義更明確,即聲明的形參以外的實參會被歸進數組。

prefer-spread:要求使用擴展運算符而非 .apply()。在 ES2015 以前,必須使用 Function.prototype.apply() 調用可變參數函數。如 var args = [1, 2, 3, 4]; Math.max.apply(Math, args);,在 ES2015 中,可使用擴展運算符調用可變參數函數。var args = [1, 2, 3, 4]; Math.max(...args);

prefer-template:要求使用模板字面量而非字符串鏈接。

require-yield:要求 generator 函數內有 yield

import/no-mutable-exports:禁止 export 暴露可更改的數據。也就是說 export 出的必須用 const 定義,如:const name = 'a'; export default name;

未完待續 歡迎你們補充……

相關文章
相關標籤/搜索