<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>NotionNext BLOG</title>
        <link>https://vercel.wuchengran.com/</link>
        <description>这是一个由NotionNext生成的站点</description>
        <lastBuildDate>Sun, 05 Mar 2023 12:59:58 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2023, Wave52</copyright>
        <item>
            <title><![CDATA[当他们讨论 Class Field 的时，他们在讨论什么？]]></title>
            <link>https://vercel.wuchengran.com/article/60eb1722-6406-4981-9635-6357bf5ed04d</link>
            <guid>60eb1722-6406-4981-9635-6357bf5ed04d</guid>
            <pubDate>Thu, 16 Jul 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[总是看到 hax 大佬吐槽 tc39，可是具体在说什么一直不清楚]]></description>
            <content:encoded><![CDATA[<div id="container" class="max-w-5xl font-medium mx-auto undefined"><main class="notion light-mode notion-page notion-block-60eb17226406498196356357bf5ed04d"><div class="notion-viewport"></div><!--$!--><template></template><!--/$--><div class="notion-text notion-block-3c3677aa3d024e1ea69a834114daf321"><div class="notion-text-children"><div class="notion-text notion-block-76b8bb3cb6104bbd820f85866a85ec53">总是看到 hax 大佬吐槽 tc39，可是具体在说什么一直不清楚</div><h2 class="notion-h notion-h1 notion-block-99a74d523f474bb8bb667d26004e66bd" data-id="99a74d523f474bb8bb667d26004e66bd"><span><div id="99a74d523f474bb8bb667d26004e66bd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#99a74d523f474bb8bb667d26004e66bd" title="从原型到 Class"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">从原型到 Class</span></span></h2><h3 class="notion-h notion-h2 notion-block-0483f1ffebea4cd6b143a0178dc8d7ff" data-id="0483f1ffebea4cd6b143a0178dc8d7ff"><span><div id="0483f1ffebea4cd6b143a0178dc8d7ff" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0483f1ffebea4cd6b143a0178dc8d7ff" title="1. 写法对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 写法对比</span></span></h3><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// ES6
class A {  
	constructor() {    
		this.a = 0;  
	}  
	// 具有争议的 private field - https://zhuanlan.zhihu.com/p/46784477  
	#b = 0;  
	// 类方法、静态方法  
	static get1() {    
		console.log(1);  
	}  
	// 原型实例方法  
	get2() {    
		console.log(2);  
	}  
	// 实例方法，会存在在新实例化的对象上，不在原型链上  
	get3 = () =&gt; {    
		console.log(3);  
	}
}

// ES5
function A() {  
	this.a = 0;  
	// 可以视为 private 变量，约定俗成用下划线开头，其实都可以  
	var _b = 0;  
	// 实例方法，会存在在新实例化的对象上，不在原型链上  
	this.get3 = () =&gt; {
    console.log(3);  
	};
}
// 类方法、静态方法
A.get1 = function() {  
	console.log(1);
};
// 原型实例方法
A.prototype.get2 = function() {  
	console.log(2);
};</code></pre><h3 class="notion-h notion-h2 notion-block-548ab73631184bd6b0fd710d8563f1a2" data-id="548ab73631184bd6b0fd710d8563f1a2"><span><div id="548ab73631184bd6b0fd710d8563f1a2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#548ab73631184bd6b0fd710d8563f1a2" title="2. 区别"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 区别</span></span></h3><h4 class="notion-h notion-h3 notion-block-493eba7e36ca481b82c6e5c2480ac2dd" data-id="493eba7e36ca481b82c6e5c2480ac2dd"><span><div id="493eba7e36ca481b82c6e5c2480ac2dd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#493eba7e36ca481b82c6e5c2480ac2dd" title="1. Class 声明会“提升”，但不会初始化赋值。Foo 进入暂时性死区，类似于 let、const 声明变量(提升的说法有争议)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. Class 声明会“提升”，但不会初始化赋值。Foo 进入暂时性死区，类似于 let、const 声明变量(提升的说法有争议)</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">const bar = new Bar(); // it&#x27;s ok
function Bar() {  
	this.bar = 42;
}

const foo = new Foo(); // ReferenceError: Foo is not defined
class Foo {  
	constructor() {    
		this.foo = 42;  
	}
}</code></pre><h4 class="notion-h notion-h3 notion-block-5c1a8586f6c74bd5ba578e1ae5f6db12" data-id="5c1a8586f6c74bd5ba578e1ae5f6db12"><span><div id="5c1a8586f6c74bd5ba578e1ae5f6db12" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5c1a8586f6c74bd5ba578e1ae5f6db12" title="2. Class 声明内部会启用严格模式"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. Class 声明内部会启用严格模式</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// 引用一个未声明的变量
function Bar() {  
	baz = 42; // it&#x27;s ok
}
const bar = new Bar();

class Foo {  
	constructor() {    
		fol = 42; // ReferenceError: fol is not defined  
	}
}
const foo = new Foo();</code></pre><h4 class="notion-h notion-h3 notion-block-4371e55a2ae04f699eedaf4597c667b2" data-id="4371e55a2ae04f699eedaf4597c667b2"><span><div id="4371e55a2ae04f699eedaf4597c667b2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4371e55a2ae04f699eedaf4597c667b2" title="3. Class 的所有方法（包括静态方法和实例方法）都是不可枚举的"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3. Class 的所有方法（包括静态方法和实例方法）都是不可枚举的</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// 引用一个未声明的变量
function Bar() {  
	this.bar = 42;
}
Bar.answer = function() {  
	return 42;
};
Bar.prototype.print = function() {  
	console.log(this.bar);
};
const barKeys = Object.keys(Bar); // [&#x27;answer&#x27;]
const barProtoKeys = Object.keys(Bar.prototype); // [&#x27;print&#x27;]

class Foo {  
	constructor() {    
		this.foo = 42;  
	}  
	static answer() {    
		return 42;  
	}  
	print() {    
		console.log(this.foo);  
	}
}
const fooKeys = Object.keys(Foo); // []
const fooProtoKeys = Object.keys(Foo.prototype); // []</code></pre><h4 class="notion-h notion-h3 notion-block-e445ec7c3d4f409384bda6779f36414b" data-id="e445ec7c3d4f409384bda6779f36414b"><span><div id="e445ec7c3d4f409384bda6779f36414b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e445ec7c3d4f409384bda6779f36414b" title="4. Class 的所有方法（包括静态方法和实例方法）都没有原型对象 prototype，所以也没有[[construct]]，不能使用 new 来调用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4. Class 的所有方法（包括静态方法和实例方法）都没有原型对象 prototype，所以也没有[[construct]]，不能使用 new 来调用</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">function Bar() {
  this.bar = 42;
}
Bar.prototype.print = function() {  
	console.log(this.bar);
};
const bar = new Bar();
const barPrint = new bar.print(); // it&#x27;s ok

class Foo {  
	constructor() {    
		this.foo = 42;  
	}  
	print() {    
		console.log(this.foo);  
	}
}
const foo = new Foo();
const fooPrint = new foo.print(); // TypeError: foo.print is not a constructor</code></pre><h4 class="notion-h notion-h3 notion-block-b5a78299edf94fb0bdbd4e09f9d15a2f" data-id="b5a78299edf94fb0bdbd4e09f9d15a2f"><span><div id="b5a78299edf94fb0bdbd4e09f9d15a2f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b5a78299edf94fb0bdbd4e09f9d15a2f" title="5. 必须使用 new 调用 class"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5. 必须使用 new 调用 class</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">function Bar() {  
	this.bar = 42;
}
const bar = Bar(); // it&#x27;s ok

class Foo {  
	constructor() {    
		this.foo = 42;  
	}
}
const foo = Foo(); // TypeError: Class constructor Foo cannot be invoked without &#x27;new&#x27;</code></pre><h4 class="notion-h notion-h3 notion-block-89917ecd7fe3401ab5976828708262d5" data-id="89917ecd7fe3401ab5976828708262d5"><span><div id="89917ecd7fe3401ab5976828708262d5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#89917ecd7fe3401ab5976828708262d5" title="6. Class 内部无法重写类名"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">6. Class 内部无法重写类名</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">function Bar() {  
	Bar = &#x27;Baz&#x27;; // it&#x27;s ok  
	this.bar = 42;
}
const bar = new Bar();// Bar: &#x27;Baz&#x27;// bar: Bar {bar: 42}

class Foo {  
	constructor() {    
		this.foo = 42;
    Foo = &#x27;Fol&#x27;; // TypeError: Assignment to constant variable  
}}
const foo = new Foo();
Foo = &#x27;Fol&#x27;; // ？</code></pre><h2 class="notion-h notion-h1 notion-block-84a46d7ee3814d25b50afaed9dfbe453" data-id="84a46d7ee3814d25b50afaed9dfbe453"><span><div id="84a46d7ee3814d25b50afaed9dfbe453" class="notion-header-anchor"></div><a class="notion-hash-link" href="#84a46d7ee3814d25b50afaed9dfbe453" title="继承"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">继承</span></span></h2><h3 class="notion-h notion-h2 notion-block-4eda790c865a428297d05b50f4ae5d63" data-id="4eda790c865a428297d05b50f4ae5d63"><span><div id="4eda790c865a428297d05b50f4ae5d63" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4eda790c865a428297d05b50f4ae5d63" title="1. 写法对比"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. 写法对比</span></span></h3><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// ES6
class Super {}
class Sub extends Super {}
const sub = new Sub();
Sub.__proto__ === Super;

// ES5 继承有几种写法http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html
// 常见的有两个，原型链继承、构造函数继承
// 1.原型链继承
function Super() {}
function Sub() {}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
var sub = new Sub();
Sub.__proto__ === Function.prototype;// Object.getPrototypeOf(Sub)

// 2.构造函数继承
function Super() {}
function Sub() {  
	Super.apply(this, arguments);
}
var sub = new Sub();
Sub.__proto__ === Function.prototype;// Object.getPrototypeOf(Sub)</code></pre><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// class
class Super {}
class Sub extends Super {}
var sub = new Sub();
Sub.__proto__ === Super;// Object.getPrototypeOf(Sub)</code></pre><h3 class="notion-h notion-h2 notion-block-6373f54470624360a7fb633c81129bb6" data-id="6373f54470624360a7fb633c81129bb6"><span><div id="6373f54470624360a7fb633c81129bb6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6373f54470624360a7fb633c81129bb6" title="2. 区别"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. 区别</span></span></h3><h4 class="notion-h notion-h3 notion-block-324c248779264f20ac72928f652a75ad" data-id="324c248779264f20ac72928f652a75ad"><span><div id="324c248779264f20ac72928f652a75ad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#324c248779264f20ac72928f652a75ad" title="1. ES6 子类可以直接通过 __proto__ 寻址到父类, 而通过 ES5 的方式，Sub.__proto__ === Function.prototype"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1. ES6 子类可以直接通过 <code class="notion-inline-code">__proto__</code> 寻址到父类, 而通过 ES5 的方式，<code class="notion-inline-code">Sub.__proto__ === Function.prototype</code></span></span></h4><h4 class="notion-h notion-h3 notion-block-c1386449a4954b6ea944634ceb032634" data-id="c1386449a4954b6ea944634ceb032634"><span><div id="c1386449a4954b6ea944634ceb032634" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c1386449a4954b6ea944634ceb032634" title="2. ES5 和 ES6 子类 this 生成顺序不同。ES5 的继承先生成了子类实例，再调用父类的构造函数修饰子类实例，ES6 的继承先生成父类实例，再调用子类的构造函数(constructor中必须先调用super方法)修饰父类实例。这个差别使得 ES6 可以继承内置对象"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2. ES5 和 ES6 子类 this 生成顺序不同。ES5 的继承先生成了子类实例，再调用父类的构造函数修饰子类实例，ES6 的继承先生成父类实例，再调用子类的构造函数(constructor中必须先调用super方法)修饰父类实例。这个差别使得 ES6 可以继承内置对象</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">function MyES5Array() {  
	Array.apply(this, arguments);
}
// it&#x27;s useless
const arrayES5 = new MyES5Array(3); // arrayES5: MyES5Array {}

class MyES6Array extends Array {}// it&#x27;s ok
const arrayES6 = new MyES6Array(3); // arrayES6: MyES6Array(3) []</code></pre><h3 class="notion-h notion-h2 notion-block-d334bd9758ae44f3a37f97251293db33" data-id="d334bd9758ae44f3a37f97251293db33"><span><div id="d334bd9758ae44f3a37f97251293db33" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d334bd9758ae44f3a37f97251293db33" title="Class field 提案"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Class field 提案</span></span></h3><ul class="notion-list notion-list-disc notion-block-c7a7f279d9a34f1a98e50765fb8ecc40"><li>declarations</li></ul><ul class="notion-list notion-list-disc notion-block-9159ddfe012f437da2ecab013fe9724a"><li>static</li></ul><ul class="notion-list notion-list-disc notion-block-7278775b165e4716a961436b6db20f34"><li>private #</li><ul class="notion-list notion-list-disc notion-block-7278775b165e4716a961436b6db20f34"><li>private fields</li><li>private method</li></ul></ul><div class="notion-text notion-block-bcd13cbbce8e489ea3339f17e1b411d3"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/tc39/proposal-class-fields">class field 提案</a></div><ul class="notion-list notion-list-disc notion-block-aaa8d1d2e14e442995776a583466a8e1"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/tc39/proposal-class-fields/issues/100">#100</a></li></ul><ul class="notion-list notion-list-disc notion-block-23745eaa547c437b8134cb201bf42764"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/tc39/proposal-class-fields/issues/150">#150</a></li></ul><div class="notion-text notion-block-bf0683830fc144c386747d1da081b544"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/tc39/proposal-class-fields/blob/master/PRIVATE_SYNTAX_FAQ.md">PRIVATE_SYNTAX_FAQ</a></div><div class="notion-text notion-block-9f9ae47befaf4dd5a9ccb1e66f308eb4"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/JSCIG/js-class-fields-chinese-discussion/blob/master/README.md">提案中文讨论会20190908</a></div><div class="notion-text notion-block-4189ce56d1ad4a0abdb9836fd626c1ce"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#ecmascript-private-fields">TypeScript</a></div><div class="notion-text notion-block-961d1b9c63a04a86a8fcaa7d57e172db"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://babeljs.io/docs/en/babel-plugin-proposal-class-properties#references">Babel</a> - babel 叫 class properties ？</div></div></div></main><!--$!--><template></template><!--/$--></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[【译】无线局域网中采用组播模式的低速率DoS攻击性能评估]]></title>
            <link>https://vercel.wuchengran.com/article/7124ff9c-d5db-4f5b-90a6-1a6be95f0e66</link>
            <guid>7124ff9c-d5db-4f5b-90a6-1a6be95f0e66</guid>
            <pubDate>Mon, 15 Jun 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[日本名古屋大学 Yuya Sato，Tutomu Murase]]></description>
            <content:encoded><![CDATA[<div id="container" class="max-w-5xl font-medium mx-auto undefined"><main class="notion light-mode notion-page notion-block-7124ff9cd5db4f5b90a61a6be95f0e66"><div class="notion-viewport"></div><!--$--><div class="notion-collection-page-properties"></div><!--/$--><div class="notion-text notion-block-b451579262cb47af8ebca469485649f4"><div class="notion-text-children"><h3 class="notion-h notion-h2 notion-block-f876a7f5d7a948b98a012d761eed415d" data-id="f876a7f5d7a948b98a012d761eed415d"><span><div id="f876a7f5d7a948b98a012d761eed415d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f876a7f5d7a948b98a012d761eed415d" title="Performance Evaluation of Low Rate DoS Attack Using Multicast Mode in Wireless LAN 无线局域网中采用组播模式的低速率DoS攻击性能评估"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Performance Evaluation of Low Rate DoS Attack Using Multicast Mode in Wireless LAN 无线局域网中采用<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://baike.baidu.com/item/%E7%BB%84%E6%92%AD/8946116?fromtitle=Multicast&amp;fromid=10779283&amp;fr=aladdin">组播</a>模式的低速率DoS攻击性能评估</span></span></h3><div class="notion-text notion-block-b627cde63b82417ca722249e34213efc">日本名古屋大学 Yuya Sato，Tutomu Murase</div><h4 class="notion-h notion-h3 notion-block-377343a9a1b042a1ab97f7564f8ca00e" data-id="377343a9a1b042a1ab97f7564f8ca00e"><span><div id="377343a9a1b042a1ab97f7564f8ca00e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#377343a9a1b042a1ab97f7564f8ca00e" title="摘要"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">摘要</span></span></h4><div class="notion-text notion-block-3b8d0fdcdefb4641b0805907e360755b">本文讨论和研究了IEEE802.11无线局域网中利用普通消费者无线设备配备的组播模式进行低速率DoS(拒绝服务)攻击的可能性。我们不使用可以控制任意传输速率的专用设备，而是使用普通的消费类设备，并通过其组播模式获得最低的传输速率。我们解释了组播模式如何执行低速率DoS攻击。然后，在消费类设备上进行的实验表明，该方法是有效的，受害者的吞吐量被攻击降低到原来吞吐量的31%。</div><h4 class="notion-h notion-h3 notion-block-c47cfcb29b214a1d8af726d14d7bcec5" data-id="c47cfcb29b214a1d8af726d14d7bcec5"><span><div id="c47cfcb29b214a1d8af726d14d7bcec5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c47cfcb29b214a1d8af726d14d7bcec5" title="关键词"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">关键词</span></span></h4><div class="notion-text notion-block-2f09af462e354dc188769750f4ddb4c1">DoS攻击、传输率、多播、无线LAN、IEEE802.11</div><h4 class="notion-h notion-h3 notion-block-87a20ec8dea944aa9b8abf6e50571ba9" data-id="87a20ec8dea944aa9b8abf6e50571ba9"><span><div id="87a20ec8dea944aa9b8abf6e50571ba9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#87a20ec8dea944aa9b8abf6e50571ba9" title="I. 介绍"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">I. 介绍</span></span></h4><div class="notion-text notion-block-7d3694028a46440f82c2f4d41c808d97">拒绝服务(DoS)攻击是802.11无线局域网通信面临的主要威胁之一，也是噪声或干扰的主要威胁之一。由于IEEE802.11无线局域网(WLAN)的CSMA/CA，WLAN在吞吐量方面具有性能异常的性质。因此，通过在攻击者的WLAN的终端中使用低传输速率，可以合法地执行导致受害者WLAN的系统吞吐量降低的低速率DoS攻击。然而，为了获得有效的攻击结果，我们需要一种特殊的设备来发送离受害者任意距离的低传输率数据。本文讨论和研究了一种利用组播方式进行攻击的方法，并对攻击的可能性进行了讨论。通过使用组播模式，我们不需要特殊的设备，而使用当前的消费设备，如Android/Apple智能手机。我们研究了组播方法对低速率DoS攻击的有效性。</div><h3 class="notion-h notion-h2 notion-block-75a0181c81fb4afdbe5fb6c873c8d198" data-id="75a0181c81fb4afdbe5fb6c873c8d198"><span><div id="75a0181c81fb4afdbe5fb6c873c8d198" class="notion-header-anchor"></div><a class="notion-hash-link" href="#75a0181c81fb4afdbe5fb6c873c8d198" title="II. LOW RATE DOS ATTACK"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">II. LOW RATE DOS ATTACK</span></span></h3><div class="notion-text notion-block-afafea7b86c24c7e95718390cc433af7">当几乎所有终端都使用较高的传输速率，但即使其中一个终端使用较低的传输速率时[1][2]，性能异常会导致所有终端的性能下降。这不仅发生在WLAN内，而且发生在共享相同信道的多个WLAN之间，即使用相同信道号的多个WLAN之间。这称为覆盖BSS或OBSS中的性能异常。造成性能异常的原因是每个终端在WLAN的CSMA/CA中都有平等的发送机会。这意味着在WLAN中每个终端的吞吐量是相等的，而与每个终端的传输速率无关。研究表明[3]，每个无线局域网的吞吐量上限是由所有终端的谐波平均值来估计的。如果OBSS的某个终端的速率很低，则所有WLAN的吞吐量都会很低。</div><div class="notion-text notion-block-ac3619bc313d49e9b0f96a5fc38753d2">如上所述，低传输速率不利于每个终端获得更高的吞吐量。因此，这被低速DoS攻击利用。在攻击中，我们使用了一个故意使用低传输速率和消耗大量资源的终端。请注意，攻击者可以使其他WLAN吞吐量降低一种方式，即攻击者仅使用其自己的传输速率非常低的WLAN。</div><div class="notion-text notion-block-3eb24b2ef56c4236a44caf4ad33aaa7c">到目前为止，人们认为低速率DoS攻击是非常特殊的攻击。对于用户来说，在我们可以在市场上购买的消费设备中手动控制传输速率是非常困难的。这是因为传输速率由AP和终端之间的距离自动调整。因此，使用了一种特殊的装置来停止自动速率调整并固定传输速率。我们在这里研究一种简单易用的攻击方法，不是使用这样一种特殊的设备，而是使用一种消费设备。</div><div class="notion-text notion-block-45a24b2e3e284193b825cbae95b58cd1">该方法的思想是使用所有设备都配备的组播模式。在组播模式下，发送终端必须使用最低速率才能到达最远的终端。例如，IEEE802.11g具有最高传输速率54 Mbp和最低传输6 Mbps。单播模式根据距离的不同使用54到6 Mbps，但组播模式仅使用6 Mbps。</div><div class="notion-text notion-block-71c3b04e518448a28290fdbc57f1016b">为了执行攻击，攻击者通过使用组播向攻击者的WLAN内的另一个终端发送一些通信量。这不需要入侵受害者的WLAN，不需要破解密码，也不需要任何其他欺骗。</div><h4 class="notion-h notion-h3 notion-block-dfddc9a1b72d41d8908675badbe5e2fe" data-id="dfddc9a1b72d41d8908675badbe5e2fe"><span><div id="dfddc9a1b72d41d8908675badbe5e2fe" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dfddc9a1b72d41d8908675badbe5e2fe" title="III. PERFORMANCE EVALUATION WITH REAL DEVICE EXPERIMENTS 用真实设备实验进行性能评估"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">III. PERFORMANCE EVALUATION WITH REAL DEVICE EXPERIMENTS 用真实设备实验进行性能评估</span></span></h4><div class="notion-text notion-block-0634b50da54c4bce973f34d7b9758271">我们在这里调查如何使用攻击者的组播流量执行有效的低速DoS攻击。在我们的实验中，如图1所示，使用了两个IEEE802.11g无线局域网系统。受害者自己的受害者WLAN和攻击者自己的攻击者WLAN，这两个WLAN使用相同的信道。受害者WLAN有一个终端，攻击者WLAN也有一个终端。受害者终端和攻击者终端分别以54 Mbps的单播传输速率和6 Mbps的组播传输速率发送饱和的UDP流量。观察攻击前后受害者的WLAN吞吐量。根据谐波平均的理论计算方法[3]，攻击后吞吐量的上限应该是5.4 Mbps/WLAN。</div><div class="notion-text notion-block-ce2b9026048b407ca1a6ce4b31219488">图2显示了攻击前后受害者WLAN的吞吐量。首先，XperiaZ1被用作攻击者设备。当攻击者终端未发送流量时，受攻击的WLAN吞吐量约为23 Mbps(通常命名为XperiaZ1)。在低速率DoS攻击后，即组播流量发送后，受害者WLAN(XperiaZ1(攻击))的吞吐量下降到原来吞吐量的15~31%。XperiaZ1的低速DoS攻击非常有效。通过使用Nexus S，我们得到了几乎相同的结果。另一方面，当我们使用XperiaZ3作为攻击者时，我们看不到有效的结果。该设备仅将速率从23 Mbps降低到18 Mbps。虽然原因不清楚，但发现一些设备的工作方式与逻辑行为不同，但另一些设备对低率DoS攻击是有效的。</div><h4 class="notion-h notion-h3 notion-block-b647130d26de47fd97b8f0c6ffe53a3b" data-id="b647130d26de47fd97b8f0c6ffe53a3b"><span><div id="b647130d26de47fd97b8f0c6ffe53a3b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b647130d26de47fd97b8f0c6ffe53a3b" title="IV. CONCLUSION"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">IV. CONCLUSION</span></span></h4><div class="notion-text notion-block-338e5c760df44e66b4cfba19fad3c316">利用智能手机等普通消费类设备，研究了组播模式下低速率DoS攻击的性能。通过实验我们发现，在消费者设备上使用组播模式可以大大降低受害者的吞吐量。例如，我们观察到受害者的吞吐量减少到原始吞吐量的31%。我们得出的结论是，由于所有消费者设备都必须具有组播模式，所以很容易进行低速率DoS攻击。</div><h4 class="notion-h notion-h3 notion-block-89e3ad0411ca4f40972f10aebcb5671b" data-id="89e3ad0411ca4f40972f10aebcb5671b"><span><div id="89e3ad0411ca4f40972f10aebcb5671b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#89e3ad0411ca4f40972f10aebcb5671b" title="REFERENCES"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">REFERENCES</span></span></h4><div class="notion-text notion-block-c794789209c449f2bc789e89c9b06891">[1] Y. Sugiyama, et. al., “Performance evaluation and experiments on QoS for positioon of APs in densely deployed wireless LANs,” 2015 Tokai- Section Joint Conference on Electrical, Electronics, Information, and Related Engineering, K3-1, Sep. 2015. [2] M. Heusse, et. al., “Performance anomaly of 802.11b,” INFOCOM 2003, Mar. 2003 [3] K. Medepalli, et. al., “Throughput analysis of IEEE 802.11 wireless LANs using an average cycle time approach,” GLOBECOM2005, Dec. 2005..</div></div></div></main><!--$--><!--/$--></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[前端路由]]></title>
            <link>https://vercel.wuchengran.com/article/37088b60-882d-4895-9fc3-80d8e488ccb5</link>
            <guid>37088b60-882d-4895-9fc3-80d8e488ccb5</guid>
            <pubDate>Mon, 11 May 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[window.history 与 history 库的介绍]]></description>
            <content:encoded><![CDATA[<div id="container" class="max-w-5xl font-medium mx-auto undefined"><main class="notion light-mode notion-page notion-block-37088b60882d48959fc380d8e488ccb5"><div class="notion-viewport"></div><!--$--><div class="notion-collection-page-properties"></div><!--/$--><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-3afc76ae13f644888968b717d4d31ab8" data-id="3afc76ae13f644888968b717d4d31ab8"><span><div id="3afc76ae13f644888968b717d4d31ab8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3afc76ae13f644888968b717d4d31ab8" title="抛砖引玉"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">抛砖引玉</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-20d25a52b6a6471fadef90d403b8391b"><li>window.location | window.history | history 库 | react-router | react-router-redux(connected-react-router)</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-d2b8ac3e323d453da08d126ada56beb5"><li>history.listen 什么时候触发？变化时触发？我调用history.replace()，但是 location 参数没变化会触发吗？</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-faf0ec97d171447c84061fd3ae5e1beb"><li>dispatch(routerRedux.push(…)) 为什么要这样写？history.push(…)可以吗？routerRedux 我们用对了吗？</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-14f85e5f63e246a69f6be0cdf1776c16"><li>搞这么多 API 真复杂，使用浏览器原生 API 解析 url 和跳转，不香吗？香，但要避免踩坑（兼容：浏览器的兼容、hashHistory 和 browserHistory 的兼容）</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-7cfd6b9fa16e4968b8a0c84f3968de6b" data-id="7cfd6b9fa16e4968b8a0c84f3968de6b"><span><div id="7cfd6b9fa16e4968b8a0c84f3968de6b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7cfd6b9fa16e4968b8a0c84f3968de6b" title="浏览器 API"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">浏览器 API</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e3b6abb3bc0e4505919360fda4d41705" data-id="e3b6abb3bc0e4505919360fda4d41705"><span><div id="e3b6abb3bc0e4505919360fda4d41705" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e3b6abb3bc0e4505919360fda4d41705" title="location"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">location</span></span></h4><div class="notion-text notion-block-2782034dea044f17b063294a1a79bbf6"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://dev.to/samanthaming/window-location-cheatsheet-4edl">https://dev.to/samanthaming/window-location-cheatsheet-4edl</a></div><div class="notion-text notion-block-0180374cdc5c4d2287cf162394f1b2ba"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.mozilla.org/en-US/docs/Web/API/Location">https://developer.mozilla.org/en-US/docs/Web/API/Location</a></div><div class="notion-text notion-block-2e59ce7abeac4d87a529c228e45b866f">小结：</div><ol start="1" class="notion-list notion-list-numbered notion-block-8b9903f35a56417a8a309050d254ba55"><li>window.location 与 location 是一个东西，甚至与 window.document.location 和 document.location 都是一个东西</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-07ba9ab3ce784285a171c8fb72090a1f"><li>掌握读写操作，读 - 知道字段含义，写 - 知道方法区别</li><ol class="notion-list notion-list-numbered notion-block-07ba9ab3ce784285a171c8fb72090a1f"><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">ancestorOrigins: DOMStringList {length: 0}
assign: ƒ assign()
fragmentDirective: FragmentDirective {}
hash: &quot;#components-table-demo-virtual-list&quot;
host: &quot;ant.design&quot;
hostname: &quot;ant.design&quot;
href: &quot;https://ant.design/components/table-cn/?useless=1&amp;test=2#components-table-demo-virtual-list&quot;
origin: &quot;https://ant.design&quot;
pathname: &quot;/components/table-cn/&quot;
port: &quot;&quot;
protocol: &quot;https:&quot;
reload: ƒ reload()
replace: ƒ replace()
search: &quot;?useless=1&amp;test=2&quot;
toString: ƒ toString()
valueOf: ƒ valueOf()
Symbol(Symbol.toPrimitive): undefined
__proto__: Location</code></pre></ol></ol><ol start="3" class="notion-list notion-list-numbered notion-block-435dbac20dc34b4892f44b36301cdc19"><li>location.origin 会有老版浏览器兼容问题</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-e7fb00ec8c134a6dba2e14ff8b609028" data-id="e7fb00ec8c134a6dba2e14ff8b609028"><span><div id="e7fb00ec8c134a6dba2e14ff8b609028" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e7fb00ec8c134a6dba2e14ff8b609028" title="window.history"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">window.history</span></span></h4><div class="notion-text notion-block-759ccf2a6be64385b9a86ec80945aeb9"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://developer.mozilla.org/zh-CN/docs/Web/API/History">https://developer.mozilla.org/zh-CN/docs/Web/API/History</a></div><div class="notion-text notion-block-d04fa4d222e44d5fbe2b2c4fc72d7875">window.history、history 一个东西</div><div class="notion-text notion-block-5600019ff65440fdb706126c0ce0e83d">为了与 history 库区分，以下都叫 window.history</div><div class="notion-text notion-block-96b9afa42b78497aa28d9355fea800a9">小结：</div><ol start="1" class="notion-list notion-list-numbered notion-block-82f7ce0d0bd24f2c85ba26d7eb13f162"><li>出于隐私考虑，不会获取到详细的浏览历史</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-37c467dbd5b14747b0cd5522df5d2c36"><li><code class="notion-inline-code">window.history.pushState</code>、<code class="notion-inline-code">window.history.replaceState</code>：相同之处是两个 API 都会操作浏览器的历史记录，而不会引起页面的刷新；不同之处在于，pushState会增加一条新的历史记录，而replaceState则会替换当前的历史记录。</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-930acf049e0a440e8635fe670ab9a22f" data-id="930acf049e0a440e8635fe670ab9a22f"><span><div id="930acf049e0a440e8635fe670ab9a22f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#930acf049e0a440e8635fe670ab9a22f" title="前端路由解决方案"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">前端路由解决方案</span></span></h3><div class="notion-text notion-block-ee0655fb14f44a6da4f435742947d1b2">什么叫前端路由：改变 URL，不会请求后端（不刷新），但是页面内容会发生变化</div><div class="notion-text notion-block-a939f1602ca7449ab54815f4d5960786">那么有哪些情况改变 URL，不会请求后端：</div><ol start="1" class="notion-list notion-list-numbered notion-block-90018bffa3a1426196eb72b69e085c30"><li>hash 变化（无论使用js、还是在地址栏输入），不会请求后端</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-cc7dc30750364b579b6341866ce96686"><li><code class="notion-inline-code">window.history.pushState()</code></li></ol><div class="notion-text notion-block-6f2ee8ab410943daad1c97b7e525f98e">怎么让页面内容变化：</div><div class="notion-text notion-block-4bd08550ce04448f9976fd7aca2b624d">就是要让 js 知道 url 变化了，怎么搞？</div><ol start="1" class="notion-list notion-list-numbered notion-block-45b55dc6b83e4d81b71ee4124cff0b72"><li>对于方案 1 <code class="notion-inline-code">window.addEventListener(&#x27;hashchange&#x27;, ...)</code></li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-87e3e2d8304e41b3b1cbc389c1328f91"><li>对于方案 2 <code class="notion-inline-code">window.addEventListener(&#x27;popstate&#x27;, ...)</code></li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5a1320e9e31245f1a738f27178b603d1" data-id="5a1320e9e31245f1a738f27178b603d1"><span><div id="5a1320e9e31245f1a738f27178b603d1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5a1320e9e31245f1a738f27178b603d1" title="history 库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">history 库</span></span></h4><div class="notion-text notion-block-b339587a7c9a491d8091b561da61128e"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ReactTraining/history">https://github.com/ReactTraining/history</a></div><div class="notion-text notion-block-b0867899ac0143e2a151f8b1771f3828">它封装了上面两种方案，统一了浏览器差异</div><div class="notion-text notion-block-12119a0110804b29ac3c772c1cdf9840">小结：</div><ol start="1" class="notion-list notion-list-numbered notion-block-e12dcd06066840529702681a60bb92f0"><li>改变 URL，不会请求后端</li><ol class="notion-list notion-list-numbered notion-block-e12dcd06066840529702681a60bb92f0"><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">history.push(path, [state]);
history.replace(path, [state]);
history.go(n);
history.goBack();
history.goForward();</code></pre></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-ba5526be2b5b4934b65b916405f95d6e"><li>让 js 知道 url 变化了</li><ol class="notion-list notion-list-numbered notion-block-ba5526be2b5b4934b65b916405f95d6e"><div class="notion-text notion-block-fb714f1ae040405bb25a7db5eb437592"><code class="notion-inline-code">history.listen((location, action) =&gt; ...)</code>，这里的 location 可不是 window.location，但是对字段使用了相同的命名 <code class="notion-inline-code">{ pathname, search, hash, state }</code>，你一定记得 history@2.x 有个 query 参数，在 history@3.x 中可以通过使用 useQueries 参数，让 location 有 query 参数，但在 history@4.x 完全取消了 query，为的是<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ReactTraining/history/issues/364#issuecomment-246751904">保证 history.location 是 window.location 的严格子集</a></div></ol></ol><ol start="3" class="notion-list notion-list-numbered notion-block-3e534f4073654c849944ed6713f083a4"><li>你可能不知道</li><ol class="notion-list notion-list-numbered notion-block-3e534f4073654c849944ed6713f083a4"><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">const history = createHistory({
    basename: &#x27;/the/base&#x27;
});</code></pre></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-f6ae029554134118ab5ea6381ed7e08f"><li>你可能不知道</li><ol class="notion-list notion-list-numbered notion-block-f6ae029554134118ab5ea6381ed7e08f"><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// Register a simple prompt message that will be shown the
// user before they navigate away from the current page.
const unblock = history.block(&#x27;Are you sure you want to leave this page?&#x27;);

// Or use a function that returns the message when it&#x27;s needed.
history.block((location, action) =&gt; {
// The location and action arguments indicate the location
// we&#x27;re transitioning to and how we&#x27;re getting there.

// A common use case is to prevent the user from leaving the
// page if there&#x27;s a form they haven&#x27;t submitted yet.
if (input.value !== &#x27;&#x27;) return &#x27;Are you sure you want to leave this page?&#x27;;
});

// To stop blocking transitions, call the function returned from block().
unblock();</code></pre></ol></ol><ol start="5" class="notion-list notion-list-numbered notion-block-d7c0a7d800254329b065f1793c98d816"><li>browserHistory 需要服务端做什么？把所有请求（或视情况而定）转发到 index.html 举一个实际的例子，现在的前端 nginx，只做了域名和静态资源简单的映射 如：只做了 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://zyh.group.com/">https://zyh.group.com/</a> -&gt; <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://static.group.com/zyh/index.html">https://static.group.com/zyh/index.html</a></li><ol class="notion-list notion-list-numbered notion-block-d7c0a7d800254329b065f1793c98d816"><div class="notion-text notion-block-9510ab18bea242bca94c21246c52baaf">于是你访问 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://zyh.group.com/#/list">https://zyh.group.com/#/list</a> -&gt; <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://static.group.com/zyh/index.html#/list">https://static.group.com/zyh/index.html#/list</a></div><div class="notion-text notion-block-5e8bc5bf5fff4c8499a0dda55cc53d60">但你访问 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://zyh.group.com/table">https://zyh.group.com/table</a> -&gt; <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://static.group.com/zyh/index.html/table">https://static.group.com/zyh/index.html/table</a> 就出错了</div><div class="notion-text notion-block-f341514806ac40b7bfe83fbb8e8dfd5f">需要如下配置</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-json">location / {
    try_files $uri /index.html;
}</code></pre><div class="notion-text notion-block-276f586ef4c547d5abf39830036076b3">这样你访问 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://zyh.group.com/xxx/xxx">https://zyh.group.com/xxx/xxx</a> 都会返回 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://static.group.com/zyh/index.html">https://static.group.com/zyh/index.html</a></div><div class="notion-text notion-block-6d77963422b0454ba180e3db9b6b7b08">也可以 node 做，谁都可以做</div></ol></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-7c186f8e5eb341b9aa700bcf63828100" data-id="7c186f8e5eb341b9aa700bcf63828100"><span><div id="7c186f8e5eb341b9aa700bcf63828100" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7c186f8e5eb341b9aa700bcf63828100" title="react-router"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">react-router</span></span></h4><div class="notion-text notion-block-61920da627504771a8435cb7b232ac98"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ReactTraining/react-router">https://github.com/ReactTraining/react-router</a></div><ol start="1" class="notion-list notion-list-numbered notion-block-c4adbd8d527442269798baab0f435d22"><li>注意大版本升级的 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ReactTraining/react-router/blob/8365d4b2e91084265a1da7de911766169fb9e96e/CHANGES.md">breaking changes</a>，印象中 @2.x 升 @3.x 和 @3.x 升 @4.x 时，网上都是一片<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://zhuanlan.zhihu.com/p/27433116">哀嚎</a>，据说 @4.x 升 @5.x 很<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.oschina.net/news/105339/react-router-5-released">平稳</a></li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-acd64e94d4744df489a9ce0c4efadd68"><li>@4.x 是有一波大的重构，有了<code class="notion-inline-code">&lt;Switch /&gt;</code>，一开始还不明白这是干嘛的，其实就如同 js 中的 switch， 依次匹配，匹配成功则停止，是为了防止 url 匹配到多个符合条件的路由</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-28fcb52b5678470c9264690cb156ba18"><li><code class="notion-inline-code">&lt;Link /&gt;</code> 组件和 <code class="notion-inline-code">&lt;a /&gt;</code> 标签一样吗？</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-96d6d28f7aac4c87bd0ad2db79d52233"><li>官方说的 react-router-redux 已经不支持 react-router@4.x 了</li></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-45e26ada0ee948c7b500520ad7ed0966" data-id="45e26ada0ee948c7b500520ad7ed0966"><span><div id="45e26ada0ee948c7b500520ad7ed0966" class="notion-header-anchor"></div><a class="notion-hash-link" href="#45e26ada0ee948c7b500520ad7ed0966" title="react-router-redux"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">react-router-redux</span></span></h4><div class="notion-text notion-block-84bd2f9b486d44918b0544849df066e0"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/reactjs/react-router-redux">https://github.com/reactjs/react-router-redux</a></div><div class="notion-text notion-block-982b3346dd914e0798c76aafbc6a0597">同步 router 和 redux</div><div class="notion-text notion-block-097c93a1f66148ff880038824f883e7c">小结：</div><ol start="1" class="notion-list notion-list-numbered notion-block-44d00b9fa55a4c1996e6f3f972f8689d"><li>为什么不维护？很多依赖的 react api 即将废弃，需要一波重构，结果社区已经有人搞好了。用的时候也会看到很多 warning，并且放到 react-router 中维护了，但是只维护 @4.x，@5.x 以上可以看到都删掉了，之后得改用 connected-react-router，dva <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/dvajs/dva/blob/master/packages/dva/src/index.js">最新的代码</a>中都改了</li><ol class="notion-list notion-list-numbered notion-block-44d00b9fa55a4c1996e6f3f972f8689d"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-5f9810a6e5ec4d9e98b3c5b79e262b9e"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3.us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F1292b4fa-fb96-4618-9c94-db2711f611e5%2Fh-1.jpeg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3DAKIAT73L2G45EIPT3X45%252F20230305%252Fus-west-2%252Fs3%252Faws4_request%26X-Amz-Date%3D20230305T125957Z%26X-Amz-Expires%3D86400%26X-Amz-Signature%3D6bbc5a83773409bc469b2e859bbdab88491e30662d4664c665557857a4ce526c%26X-Amz-SignedHeaders%3Dhost%26x-id%3DGetObject?table=block&amp;id=5f9810a6-e5ec-4d9e-98b3-c5b79e262b9e" alt="notion image" loading="lazy" decoding="async"/></div></figure></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-fca1949db0d84882ba44eb36d9066121"><li>都已经不维护了，才发现之前根本没用对</li><ol class="notion-list notion-list-numbered notion-block-fca1949db0d84882ba44eb36d9066121"><div class="notion-text notion-block-ec15f82fd71e46678363af7fed607096"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ReactTraining/react-router/blob/v4.3.1/packages/react-router-redux/README.md">https://github.com/ReactTraining/react-router/blob/v4.3.1/packages/react-router-redux/README.md</a> <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/dvajs/dva/blob/2.4/packages/dva/src/index.js">https://github.com/dvajs/dva/blob/2.4/packages/dva/src/index.js</a></div></ol></ol><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-80383b0a00dd43c0a8461e4dc5818a67" data-id="80383b0a00dd43c0a8461e4dc5818a67"><span><div id="80383b0a00dd43c0a8461e4dc5818a67" class="notion-header-anchor"></div><a class="notion-hash-link" href="#80383b0a00dd43c0a8461e4dc5818a67" title="connected-react-router"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">connected-react-router</span></span></h4><div class="notion-text notion-block-255d8b78f2364e828c1b07652804ca0f"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/supasate/connected-react-router">https://github.com/supasate/connected-react-router</a></div><div class="notion-text notion-block-acb29566ac8d49b7a7091cf5ac51bf3f">小结：</div><ol start="1" class="notion-list notion-list-numbered notion-block-1b79f64216b149139c7eff17cd211c16"><li>用 hooks api 做了重构，用法和 react-router-redux 差不多</li></ol><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-2c24474ce0444d419d44a79ee70873b7" data-id="2c24474ce0444d419d44a79ee70873b7"><span><div id="2c24474ce0444d419d44a79ee70873b7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2c24474ce0444d419d44a79ee70873b7" title="回到开始的问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">回到开始的问题</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-2f849ae8832f4ab8995e6908c408c944"><li>…</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-e6a3a2f1b60c464d9740d072b5b8d7ac"><li><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ReactTraining/history/blob/master/modules/createBrowserHistory.js">看源码实现</a></li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-f8d3f83d74a8450ea2a2b28e6bf0f2e7"><li><code class="notion-inline-code">routerRedux.push(...)</code> 返回的是 <code class="notion-inline-code">action</code>，所以要 <code class="notion-inline-code">dispatch</code>，<code class="notion-inline-code">history.push(...)</code> 其实可以满足相同的需求。 区别是前者需要注入 <code class="notion-inline-code">dispatch</code>，使用 <code class="notion-inline-code">connect</code> 注入；后者需要注入 <code class="notion-inline-code">history</code>，要么 <code class="notion-inline-code">react-router</code> 已注入，要么使用 <code class="notion-inline-code">withRouter</code></li><ol class="notion-list notion-list-numbered notion-block-f8d3f83d74a8450ea2a2b28e6bf0f2e7"><div class="notion-text notion-block-05083d5a079e49f78ddec3380688ba4b">在 model 中跳转需使用前者</div></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-3b2ca32c992242ee9981628d4cc0654b"><li>小心下面情况</li><ol class="notion-list notion-list-numbered notion-block-3b2ca32c992242ee9981628d4cc0654b"><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// &quot;https://zyh.group.com/#/list?key=1&amp;value=2&quot;
console.log(window.location)
// ...
hash: &quot;#/list?key=1&amp;value=2&quot;
search: &quot;&quot;
// ...</code></pre><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// &quot;https://zyh.group.com/list?key=1&amp;value=2#hash&quot;
// ...
hash: &quot;#hash&quot;
search: &quot;?key=1&amp;value=2&quot;
// ...</code></pre><div class="notion-blank notion-block-d69debadd04e49308ce0bf58bff508a0"> </div></ol></ol></main><!--$--><!--/$--></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dva Effects 进阶]]></title>
            <link>https://vercel.wuchengran.com/article/fe898dfd-6201-421c-a503-e35e8454ffd0</link>
            <guid>fe898dfd-6201-421c-a503-e35e8454ffd0</guid>
            <pubDate>Fri, 01 May 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[这是去年写的一篇总结了，一直没搬到我的博客上来，最近才想起。]]></description>
            <content:encoded><![CDATA[<div id="container" class="max-w-5xl font-medium mx-auto undefined"><main class="notion light-mode notion-page notion-block-fe898dfd6201421ca503e35e8454ffd0"><div class="notion-viewport"></div><!--$--><div class="notion-collection-page-properties"></div><!--/$--><div class="notion-text notion-block-80236c2213554ac586a9e15f421a7e97"><div class="notion-text-children"><div class="notion-text notion-block-cbde746b365942ac86977fd7de538326">这是去年写的一篇总结了，一直没搬到我的博客上来，最近才想起。</div><div class="notion-text notion-block-000d7d7ecdde4eacade79d884cc8473e">本文相关代码 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/wave52/react-practise/blob/master/src/redux/dvaApp/index.js">https://github.com/wave52/react-practise/blob/master/src/redux/dvaApp/index.js</a></div><h3 class="notion-h notion-h2 notion-block-102a421577544bb69de450208663f224" data-id="102a421577544bb69de450208663f224"><span><div id="102a421577544bb69de450208663f224" class="notion-header-anchor"></div><a class="notion-hash-link" href="#102a421577544bb69de450208663f224" title="问题："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">问题：</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-1d4e934cc42e4c82a352478d1457a288"><li>使用最新的请求结果</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-c893796c6714407da92ad7244b698b72"><li>取消一个耗时很长的请求（手动/超时自动）</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-bb9975423e614c1f8f3fab78663a1a6b"><li>轮询（循环定时发起）</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-97a5102867a94ef0be1b7a6b6943eec2"><li>排队请求（循环排队发起）</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-5d944a0e03604b81b4713196ddc1d748"><li>跨 model 时序问题</li></ol><h3 class="notion-h notion-h2 notion-block-366e64b66f464977a5658f144b1932d0" data-id="366e64b66f464977a5658f144b1932d0"><span><div id="366e64b66f464977a5658f144b1932d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#366e64b66f464977a5658f144b1932d0" title="分析："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">分析：</span></span></h3><h4 class="notion-h notion-h3 notion-block-0082348629b14171b2b430e86e805e8b" data-id="0082348629b14171b2b430e86e805e8b"><span><div id="0082348629b14171b2b430e86e805e8b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0082348629b14171b2b430e86e805e8b" title="一.redux-saga"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一.redux-saga</span></span></h4><h4 class="notion-h notion-h3 notion-block-5f5e82a32242486ba95d63ccffb63c9b" data-id="5f5e82a32242486ba95d63ccffb63c9b"><span><div id="5f5e82a32242486ba95d63ccffb63c9b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5f5e82a32242486ba95d63ccffb63c9b" title="1.redux-saga是个中间件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.redux-saga是个中间件</span></span></h4><div class="notion-text notion-block-a2c874fbf8ee4c5ba9bba22306416dd7">那源码是否可以找到 redux-thunk 这样的中间件写法？(redux-thunk 源码简析之前文章做过了，14 行代码很简单)</div><div class="notion-text notion-block-b669eea6bf624cdeac8750d8cd326ca7">可以，就在 /packages/core/src/internal/middleware.js（0.16.0 src/internal/middleware.js）</div><div class="notion-text notion-block-228567629bf346b58d17701045822088">sagaMiddlewareFactory 这个函数等同于 createThunkMiddleware</div><div class="notion-text notion-block-0df9da83961b4c21a3c66a81ac4afc41">其主要逻辑是</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">return next =&gt; action =&gt; {
    if (sagaMonitor &amp;&amp; sagaMonitor.actionDispatched) {
        sagaMonitor.actionDispatched(action)    
	}    
	const result = next(action) // hit reducers    
	channel.put(action)    
	return result
}</code></pre><div class="notion-text notion-block-ea5cfb6e1e7740ec9833e34feb39407f">使用时，对比thunk:</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// thunk
const store = createStore(
  rootReducer,  
	applyMiddleware(thunk)
);</code></pre><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// saga
const sagaMiddleware = createSagaMiddleware()
createStore(rootReducer, applyMiddleware(sagaMiddleware))
sagaMiddleware.run(rootSaga)</code></pre><div class="notion-text notion-block-36fda974a8094ddabd2e43e0f2f225ae">上面的 thunk 中间件这样用以后，变化的是 reducer，本来 action 是一个 plainObject，现在的 action 可以是个方法了；而用了 saga 中间件以后，之前的 reducer 没有变化，action 还是一个 plainObject 表示 state 的变化，而异步的都放在 sagas（上面的 rootSaga）中处理了，至于 channel.put(action) 可以理解成 channel 是一个发布订阅模式，channel.put 就是发布，而 saga 中会订阅（take）</div><div class="notion-text notion-block-932f0b347d6b4a49a26acb1553bfc948">也就是说 saga 的程序逻辑会存在两个位置：</div><ul class="notion-list notion-list-disc notion-block-494ee900e73a4c17bd904e591b81bad2"><li>Reducers 负责处理 action 的 state 转换</li></ul><ul class="notion-list notion-list-disc notion-block-1fc35e8d11214c3c9097b1d8938fd9f1"><li>Sagas 负责策划统筹合成和异步操作</li></ul><div class="notion-text notion-block-845777cc322f4712a6eed61b748ad6d3">源码中也能体现 <code class="notion-inline-code">const result = next(action)</code>，不像 thunk 还做了拦截处理，而 saga 的处理其实是在 run 函数， run 函数源码对应 runSaga/packages/core/src/internal/runSaga.js</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">const iterator = saga(...args)</code></pre><div class="notion-text notion-block-4f6b7320626645648abfd35a8052c378">这里 saga 的 args 参数可能有各种情况，本例 saga 对应 rootSaga，<code class="notion-inline-code">...args</code> 是空的。</div><div class="notion-text notion-block-fc86a290b0e74b02a6c290fbfe2d24e5">确实，rootSaga 是一个 generator，他执行后返回一个 IterableIterator 类型的对象 iterator</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">export default function* root() {
  yield all([
		fork(getAllProducts), 
		fork(watchGetProducts), 
		fork(watchCheckout)
	])
}</code></pre><div class="notion-text notion-block-fd23001ccd154125800b42dd07fa3323">那我们看看怎么处理这个 iterator 的</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-plain text">return immediately(() =&gt; {    const task = proc(env, iterator, context, effectId, getMetaInfo(saga), /* isRoot */ true, noop)    if (sagaMonitor) {       sagaMonitor.effectResolved(effectId, task)    }    return task})</code></pre><div class="notion-text notion-block-9ad92b322a0d433c8588d7edd5a0e3de">作为参数传给了 proc 函数，外面包的这层函数先不用管，这里可以看成 <code class="notion-inline-code">((）=&gt;{proc})()</code> 一个立即执行函数，再看看 proc，这是重点了 <code class="notion-inline-code">run（rootSaga）</code>执行的调用栈（从proc开始，前面的都分析了） <code class="notion-inline-code">proc()</code></div><ul class="notion-list notion-list-disc notion-block-02bd03117d7044ceae9a7637d90478e1"><li>&gt; <code class="notion-inline-code">next()</code></li></ul><ul class="notion-list notion-list-disc notion-block-0f23949b834e4f2f8bbdd5b90cd417f9"><li>&gt; <code class="notion-inline-code">result = iterator.next(arg)</code> - (看过 generator 应该知道此时来到了第一个 <code class="notion-inline-code">yield all()</code>, 打印一下<code class="notion-inline-code">{value：{type: ALL,....},done: false}</code>，判断 done 还不为 true，直接打印 <code class="notion-inline-code">console.log(all());</code> 也会看到这个结构)</li></ul><ul class="notion-list notion-list-disc notion-block-b294339184154eafba119c59a77d434a"><li>&gt; <code class="notion-inline-code">digestEffect()</code></li></ul><ul class="notion-list notion-list-disc notion-block-9fd6fc20fd34487080a8645d0bbba2da"><li>&gt; <code class="notion-inline-code">finalRunEffect()</code> - (finalRunEffect()是在runSaga中封装了runeffect，runsaga可以接受一个effectMiddlewares参数进行封装TODO1)</li></ul><ul class="notion-list notion-list-disc notion-block-a8a4b6d464d44361a63f74ca80d5ef80"><li>&gt; <code class="notion-inline-code">runEffect()</code></li></ul><ul class="notion-list notion-list-disc notion-block-908f9aeea5a34864a1647c3808192e49"><li>&gt; 然后去 effectRunnerMap.js</li></ul><ul class="notion-list notion-list-disc notion-block-07051d08ae694cddbe6b10358bf1cd07"><li>&gt; <code class="notion-inline-code">runAllEffect()</code> -&gt; forEach 调用 <code class="notion-inline-code">digestEffect()</code> 同上第一个是 fork -&gt; <code class="notion-inline-code">runForkEffect()</code> -&gt; proc</li></ul><div class="notion-text notion-block-7df5da3cbc42479689f1cb29a0e6b003">当前 iterator 就变成了 getAllProducts</div><div class="notion-text notion-block-1093f26fdad4499381716bcf38e08994">更多 saga 原理与实现 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="http://frontend.dev-ag.xxx.com/blog/2018/08/28/redux-saga.html">http://frontend.dev-ag.xxx.com/blog/2018/08/28/redux-saga.html</a></div><div class="notion-text notion-block-4d87684714344bd7a0ecb4ed9b3b0eb0">我们主要关注 redux-saga 的使用与 dva 的原理和实现</div><div class="notion-text notion-block-d289b66a02fd4f989a983544260b9456">只需强调几个地方帮助我们理解： 1.watch-and-fork 模式 2.阻塞（take，call…）与非阻塞（fork，put…） 3.saga-helper</div><h4 class="notion-h notion-h3 notion-block-8bca072621b1405bb24709e76f7cfcf3" data-id="8bca072621b1405bb24709e76f7cfcf3"><span><div id="8bca072621b1405bb24709e76f7cfcf3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8bca072621b1405bb24709e76f7cfcf3" title="2.dva 封装了啥"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.dva 封装了啥</span></span></h4><div class="notion-text notion-block-2568d7a8444240f9ab35fbceb93ae65d">dva 调用 run <code class="notion-inline-code">store.runSaga = sagaMiddleware.run;</code> injectModel 中 <code class="notion-inline-code">store.runSaga</code> 参数应该是 rootSaga，那 dva 中是啥 是一个 getSaga 方法 dva/packages/dva-core/src/getSaga.js 返回是一个 funtion*() 就像 rootSaga 一样但里面没有用 all() 包装，而是一个 for 循环，毕竟 all() 中也是 forEach，然后</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-plain text">const watcher = getWatcher(key, effects[key], model, onError, onEffect, opts);const task = yield sagaEffects.fork(watcher);</code></pre><div class="notion-text notion-block-a38dd7d86ddf4b85aa86bca1f96a12a9">第一行每一个 saga 我们都用一个 sagaHelper 包装一下</div><div class="notion-text notion-block-bd3b54fbaeb44a97a869c62eb070c79f">第二行包装后的 saga 我们 fork 一下，就像前面的例子一样</div><div class="notion-text notion-block-e22ce1358ac7435997a0298ec86d2d04">这里就需要理解一下 sagaHelper 和 fork 的意义了</div><div class="notion-text notion-block-860b09fd99fa45f8a82b19ed1b8c1f25"><b>fork</b> 是非阻塞的 call(<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://redux-saga-in-chinese.js.org/docs/api/">https://redux-saga-in-chinese.js.org/docs/api/</a>)</div><div class="notion-text notion-block-eb64fa9227684089bc9671a14b68f71f">另外，<code class="notion-inline-code">createEffects return { ...sagaEffects, put, take };</code> 这里可以发现，dva 中是可以使用 redux-saga 中所有的 effects 的，不过要注意版本</div><h4 class="notion-h notion-h3 notion-block-0f9700dee82d42c6a8d891450490c66d" data-id="0f9700dee82d42c6a8d891450490c66d"><span><div id="0f9700dee82d42c6a8d891450490c66d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0f9700dee82d42c6a8d891450490c66d" title="3.saga helper(saga辅助函数)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.saga helper(saga辅助函数)</span></span></h4><div class="notion-text notion-block-a7c7853d528b45baaf9064ff36a452fc">saga helper 对应源码 io-helpers <code class="notion-inline-code">debounce</code>， <code class="notion-inline-code">retry</code>， <code class="notion-inline-code">takeEvery</code>， <code class="notion-inline-code">takeLatest</code>， <code class="notion-inline-code">takeLeading</code>， <code class="notion-inline-code">throttle</code>，saga 辅助函数是由effect创建器组合而来的高级API</div><div class="notion-text notion-block-341989c3724447ccab9fc16254690c43"><code class="notion-inline-code">takeEvery</code> 是一个使用 <code class="notion-inline-code">take</code> 和 <code class="notion-inline-code">fork</code> 构建的高级 API。下面演示了这个辅助函数是如何由低级 Effect 实现的</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-plain text">const takeEvery = (patternOrChannel, saga, ...args) =&gt; fork(function*() {  while (true) {    const action = yield take(patternOrChannel)    yield fork(saga, ...args.concat(action))  }})</code></pre><div class="notion-text notion-block-588579dae3174d15afcba9ffd903eedb">dva 的 <code class="notion-inline-code">&quot;redux-saga&quot;: &quot;^0.16.0&quot;</code>，包含的 saga helper 只有 <code class="notion-inline-code">takeEvery</code>， <code class="notion-inline-code">takeLatest</code>， <code class="notion-inline-code">throttle</code>，对应 sagaHelpers 这个目录</div><div class="notion-text notion-block-978a44a96c724fd68f583df4098eb86c">dva 中的 saga helper 作为 effects type 存在</div><div class="notion-text notion-block-a01bf011db684154b8e61476fa9536b9"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/wangweiren_get/article/details/89043113#_1">https://blog.csdn.net/wangweiren_get/article/details/89043113#_1</a></div><div class="notion-text notion-block-7340eceac93e4cb287f809d778fd56c6">getWatcher 源码中默认用 takeEvery 包裹，所以一般没有写，问题 3 就可以用takeLatest来解决</div><div class="notion-text notion-block-77b54e1dad304205ad5b88e0147eaa34">我们具体来看看每一个 saga helper 的用途</div><h4 class="notion-h notion-h3 notion-block-2a313c9a60c741a8a341aabddadace9e" data-id="2a313c9a60c741a8a341aabddadace9e"><span><div id="2a313c9a60c741a8a341aabddadace9e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2a313c9a60c741a8a341aabddadace9e" title="1).先看看 redux-saga 本身的"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1).先看看 redux-saga 本身的</span></span></h4><div class="notion-text notion-block-b260dfa256d64ab69fdeacab335c42cd"><b>takeEvery：</b> 每次 dispatch action 都会触发</div><div class="notion-text notion-block-754a4f51ef4b42e3ac0bf8b622e28bc3"><b>takeLatest：</b> 每次 dispatch action 会销毁之前的，再触发</div><div class="notion-text notion-block-2fb1008bbf174c9b9f48f17afcbe6e87"><b>throttle：</b> 节流，不多解释</div><h4 class="notion-h notion-h3 notion-block-25bcf06a06244cab85cf45c38113fac1" data-id="25bcf06a06244cab85cf45c38113fac1"><span><div id="25bcf06a06244cab85cf45c38113fac1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#25bcf06a06244cab85cf45c38113fac1" title="2).dva依赖redux-saga@0.16.x，下面这些新的saga-helper你用dva时应该没有见过："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2).dva依赖redux-saga@0.16.x，下面这些新的saga-helper你用dva时应该没有见过：</span></span></h4><div class="notion-text notion-block-079ee491ffe6467dbc0d700b1168bb63"><b>takeLeading：</b> 每次dispatch触发一次，当执行完了才能在被触发，中间dispatch不会触发</div><div class="notion-text notion-block-f27dafd4583f49e08de824047066c6bd"><b>debounce：</b> 防抖，不多解释</div><div class="notion-text notion-block-ba57869e119f43e18dca7e3dcdde8b5c"><b>retry：</b> 失败自动重试</div><h4 class="notion-h notion-h3 notion-block-afe3c9f9119f4350bb99c62311cd6130" data-id="afe3c9f9119f4350bb99c62311cd6130"><span><div id="afe3c9f9119f4350bb99c62311cd6130" class="notion-header-anchor"></div><a class="notion-hash-link" href="#afe3c9f9119f4350bb99c62311cd6130" title="3).另外由于 saga helper 就是简单的 effects 创建器组合而成的高级API，所以 dva 在封装时也自己做了几个 saga helper（在dva里叫effect type）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3).另外由于 saga helper 就是简单的 effects 创建器组合而成的高级API，所以 dva 在封装时也自己做了几个 saga helper（在dva里叫effect type）</span></span></h4><div class="notion-text notion-block-c1461bedfeac4979916690bb69befc5c"><b>watcher：</b> 其实就就是没有用 saga-helper，初始化启动，这个名字来源是由于 saga 常见模式 watch-and-fork 模式，dva 只对其做了简单的 <code class="notion-inline-code">try catch</code> 封装</div><div class="notion-text notion-block-750ed42380564c5da0fab2a3d305ceeb"><b>poll（2.6beta版）：</b> 顾名思义是做轮询用的（解决了开头的问题），现在我们用的是 dva@2.4 版本还没有这个 effect，可以看下他怎么做的，总之是由简单的 effect 创建器组合而成，solvay 中就自己实现过</div><h4 class="notion-h notion-h3 notion-block-ec0e7ae84f1d4c41b1043bca5c61ccf5" data-id="ec0e7ae84f1d4c41b1043bca5c61ccf5"><span><div id="ec0e7ae84f1d4c41b1043bca5c61ccf5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ec0e7ae84f1d4c41b1043bca5c61ccf5" title="4.effect 创建器"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.effect 创建器</span></span></h4><div class="notion-text notion-block-4ffebdab91d0423b9620d7383af160b0"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://redux-saga-in-chinese.js.org/docs/basics/DeclarativeEffects.html">https://redux-saga-in-chinese.js.org/docs/basics/DeclarativeEffects.html</a></div><div class="notion-text notion-block-e7944b3d34fd4c93affb35d944c5ff94">作用：为了方便测试，把直接调用改为使用 effect 创建器包装调用</div><div class="notion-text notion-block-6b613de334004c03900f5d3765f15a61">take、fork</div><h4 class="notion-h notion-h3 notion-block-8c217028368d4b958e14df63d5b8ce3f" data-id="8c217028368d4b958e14df63d5b8ce3f"><span><div id="8c217028368d4b958e14df63d5b8ce3f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8c217028368d4b958e14df63d5b8ce3f" title="5.channel"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.channel</span></span></h4><div class="notion-text notion-block-783f183f44ca405ba737724118258ad0">…</div><div class="notion-text notion-block-791c77f8913a4108ab258892f326792d">本文相关代码 https://github.com/wave52/react-practise/blob/master/src/redux/dvaApp/index.js</div></div></div></main><!--$--><!--/$--></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ESLint Checklist]]></title>
            <link>https://vercel.wuchengran.com/article/df983d6a-701b-4e83-b4d6-2ce5abc0d71b</link>
            <guid>df983d6a-701b-4e83-b4d6-2ce5abc0d71b</guid>
            <pubDate>Wed, 01 Apr 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[eslint 规则很多，大家肯定也没有一一看过，但是很多规则我们平时却已经在”遵守“着了，这正可谓是道者，人之所蹈，使万物不知其所由
我们今天就来探寻下 eslint 的”道“]]></description>
            <content:encoded><![CDATA[<div id="container" class="max-w-5xl font-medium mx-auto undefined"><main class="notion light-mode notion-page notion-block-df983d6a701b4e83b4d62ce5abc0d71b"><div class="notion-viewport"></div><!--$--><div class="notion-collection-page-properties"><div class="notion-collection-row"><div class="notion-collection-row-body"><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M7 13A6 6 0 107 1a6 6 0 000 12zM3.751 5.323A.2.2 0 013.909 5h6.182a.2.2 0 01.158.323L7.158 9.297a.2.2 0 01-.316 0L3.751 5.323z"></path></svg><div class="notion-collection-column-title-body">type</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-select"><div class="notion-property-select-item notion-item-purple">Post</div></span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M7 13A6 6 0 107 1a6 6 0 000 12zM3.751 5.323A.2.2 0 013.909 5h6.182a.2.2 0 01.158.323L7.158 9.297a.2.2 0 01-.316 0L3.751 5.323z"></path></svg><div class="notion-collection-column-title-body">status</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-select"><div class="notion-property-select-item notion-item-red">Published</div></span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M10.889 5.5H3.11v1.556h7.778V5.5zm1.555-4.444h-.777V0H10.11v1.056H3.89V0H2.333v1.056h-.777c-.864 0-1.548.7-1.548 1.555L0 12.5c0 .856.692 1.5 1.556 1.5h10.888C13.3 14 14 13.356 14 12.5V2.611c0-.855-.7-1.555-1.556-1.555zm0 11.444H1.556V3.944h10.888V12.5zM8.556 8.611H3.11v1.556h5.445V8.61z"></path></svg><div class="notion-collection-column-title-body">date</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-date">Apr 1, 2020</span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M7 4.568a.5.5 0 00-.5-.5h-6a.5.5 0 00-.5.5v1.046a.5.5 0 00.5.5h6a.5.5 0 00.5-.5V4.568zM.5 1a.5.5 0 00-.5.5v1.045a.5.5 0 00.5.5h12a.5.5 0 00.5-.5V1.5a.5.5 0 00-.5-.5H.5zM0 8.682a.5.5 0 00.5.5h11a.5.5 0 00.5-.5V7.636a.5.5 0 00-.5-.5H.5a.5.5 0 00-.5.5v1.046zm0 3.068a.5.5 0 00.5.5h9a.5.5 0 00.5-.5v-1.045a.5.5 0 00-.5-.5h-9a.5.5 0 00-.5.5v1.045z"></path></svg><div class="notion-collection-column-title-body">slug</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-text"></span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M7 4.568a.5.5 0 00-.5-.5h-6a.5.5 0 00-.5.5v1.046a.5.5 0 00.5.5h6a.5.5 0 00.5-.5V4.568zM.5 1a.5.5 0 00-.5.5v1.045a.5.5 0 00.5.5h12a.5.5 0 00.5-.5V1.5a.5.5 0 00-.5-.5H.5zM0 8.682a.5.5 0 00.5.5h11a.5.5 0 00.5-.5V7.636a.5.5 0 00-.5-.5H.5a.5.5 0 00-.5.5v1.046zm0 3.068a.5.5 0 00.5.5h9a.5.5 0 00.5-.5v-1.045a.5.5 0 00-.5-.5h-9a.5.5 0 00-.5.5v1.045z"></path></svg><div class="notion-collection-column-title-body">summary</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-text">eslint 规则很多，大家肯定也没有一一看过，但是很多规则我们平时却已经在”遵守“着了，这正可谓是道者，人之所蹈，使万物不知其所由
我们今天就来探寻下 eslint 的”道“</span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M4 3a1 1 0 011-1h7a1 1 0 110 2H5a1 1 0 01-1-1zm0 4a1 1 0 011-1h7a1 1 0 110 2H5a1 1 0 01-1-1zm0 4a1 1 0 011-1h7a1 1 0 110 2H5a1 1 0 01-1-1zM2 4a1 1 0 110-2 1 1 0 010 2zm0 4a1 1 0 110-2 1 1 0 010 2zm0 4a1 1 0 110-2 1 1 0 010 2z"></path></svg><div class="notion-collection-column-title-body">tags</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-multi_select"><div class="notion-property-multi_select-item notion-item-red">Web dev</div></span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M7 13A6 6 0 107 1a6 6 0 000 12zM3.751 5.323A.2.2 0 013.909 5h6.182a.2.2 0 01.158.323L7.158 9.297a.2.2 0 01-.316 0L3.751 5.323z"></path></svg><div class="notion-collection-column-title-body">category</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-select"><div class="notion-property-select-item notion-item-purple">技术分享</div></span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M7 4.568a.5.5 0 00-.5-.5h-6a.5.5 0 00-.5.5v1.046a.5.5 0 00.5.5h6a.5.5 0 00.5-.5V4.568zM.5 1a.5.5 0 00-.5.5v1.045a.5.5 0 00.5.5h12a.5.5 0 00.5-.5V1.5a.5.5 0 00-.5-.5H.5zM0 8.682a.5.5 0 00.5.5h11a.5.5 0 00.5-.5V7.636a.5.5 0 00-.5-.5H.5a.5.5 0 00-.5.5v1.046zm0 3.068a.5.5 0 00.5.5h9a.5.5 0 00.5-.5v-1.045a.5.5 0 00-.5-.5h-9a.5.5 0 00-.5.5v1.045z"></path></svg><div class="notion-collection-column-title-body">icon</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-text"></span></div></div><div class="notion-collection-row-property"><div class="notion-collection-column-title"><svg viewBox="0 0 14 14" class="notion-collection-column-title-icon"><path d="M7 4.568a.5.5 0 00-.5-.5h-6a.5.5 0 00-.5.5v1.046a.5.5 0 00.5.5h6a.5.5 0 00.5-.5V4.568zM.5 1a.5.5 0 00-.5.5v1.045a.5.5 0 00.5.5h12a.5.5 0 00.5-.5V1.5a.5.5 0 00-.5-.5H.5zM0 8.682a.5.5 0 00.5.5h11a.5.5 0 00.5-.5V7.636a.5.5 0 00-.5-.5H.5a.5.5 0 00-.5.5v1.046zm0 3.068a.5.5 0 00.5.5h9a.5.5 0 00.5-.5v-1.045a.5.5 0 00-.5-.5h-9a.5.5 0 00-.5.5v1.045z"></path></svg><div class="notion-collection-column-title-body">password</div></div><div class="notion-collection-row-value"><span class="notion-property notion-property-text"></span></div></div></div></div></div><!--/$--><div class="notion-text notion-block-1cc715f1869c40e3ab1281be3d4223f5"><div class="notion-text-children"><div class="notion-text notion-block-2753b9623d564db1b7b0f1a150bd4d04">ESLint 规则很多，大家肯定也没有一一看过，但是很多规则我们平时却已经在”遵守“着了，这正可谓是</div><blockquote class="notion-quote notion-block-9cd64b612cac4a77b6476bb3d621c3c3"><div>道者，人之所蹈，使万物不知其所由 —— 张元浩</div></blockquote><div class="notion-text notion-block-a10a00113c074771801f3197da22dc90">我们今天就来探寻下 ESLint 的”道“</div><h3 class="notion-h notion-h2 notion-block-a973a3c7b2964555907c41813736acc7" data-id="a973a3c7b2964555907c41813736acc7"><span><div id="a973a3c7b2964555907c41813736acc7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a973a3c7b2964555907c41813736acc7" title="Q：你可能会遇到 ESLint 报了个错，但不知道什么原因，那么你该怎么办呢？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Q：你可能会遇到 ESLint 报了个错，但不知道什么原因，那么你该怎么办呢？</span></span></h3><h4 class="notion-h notion-h3 notion-block-6136886da6c04d0e85336e7d1a43637c" data-id="6136886da6c04d0e85336e7d1a43637c"><span><div id="6136886da6c04d0e85336e7d1a43637c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6136886da6c04d0e85336e7d1a43637c" title="一.了解规则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一.了解规则</span></span></h4><div class="notion-text notion-block-552ea572eae0497c991346ecd2fe62e5">ESLint 自带的规则<b>(没有带前缀的)</b></div><div class="notion-text notion-block-932f0ed9fb46413889e1e2760c19b648"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="http://eslint.cn/docs/rules/">http://eslint.cn/docs/rules/</a></div><div class="notion-text notion-block-01b69aff168e48bba98bb494c8d2943e"><b>import/xxx：</b>该插件旨在支持 ES2015+（ES6+）导入/导出语法，并防止文件路径和导入名称拼写错误的问题。</div><div class="notion-text notion-block-90d1942bfa8d4d2b9e560ebb798e7029"> <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.npmjs.com/package/eslint-plugin-import">https://www.npmjs.com/package/eslint-plugin-import</a></div><div class="notion-text notion-block-6ff436cbe33343b4b49e5087d8a87087"><b>jsx-a11y/xxx：</b>Static AST checker for accessibility rules on JSX elements. （静态 AST 检查器，用于 JSX 元素上的可访问性规则。） 不用这个插件的，ESLint parse 时到 ASTNode 为 JSXxxx 就跳过去了? 不一定，比如 ESLint 自带<code class="notion-inline-code">jsx-quotes</code>。 （具体涉及 ESLint 实现，见后文）</div><div class="notion-text notion-block-3b32d7964ad24ac8ade41d9de34de479"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.npmjs.com/package/eslint-plugin-jsx-a11y">https://www.npmjs.com/package/eslint-plugin-jsx-a11y</a></div><div class="notion-text notion-block-329601ba4ce14e8693e51cafc4d7fd37"><b>react/xxx：</b>react 相关</div><div class="notion-text notion-block-9ee58402d8614d41a01e3de0addf905f"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.npmjs.com/package/eslint-plugin-react">https://www.npmjs.com/package/eslint-plugin-react</a></div><div class="notion-text notion-block-37f920c4c0b84680910a521aab0ec67c"><b>react-hooks/xxx：</b>react-hooks 相关</div><div class="notion-text notion-block-f9ba4202d28d4e768e343a7a6a2349c9"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.npmjs.com/package/eslint-plugin-react-hooks">https://www.npmjs.com/package/eslint-plugin-react-hooks</a></div><div class="notion-text notion-block-cb68c854c46e40b98b949b37d91832c7"><b>@typescript-eslint/xxx：</b>typescript 相关</div><div class="notion-text notion-block-deeb163823844fcb8caa3a6eb2221b94"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://www.npmjs.com/package/@typescript-eslint/eslint-plugin">https://www.npmjs.com/package/@typescript-eslint/eslint-plugin</a></div><div class="notion-text notion-block-c174504a0c1f409e84cd78596aecd047">没必要一个个规则都看，但是我们可以给这些规则分个类</div><h4 class="notion-h notion-h3 notion-block-2813c103bf8f4a4cb835442b5b7740a3" data-id="2813c103bf8f4a4cb835442b5b7740a3"><span><div id="2813c103bf8f4a4cb835442b5b7740a3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2813c103bf8f4a4cb835442b5b7740a3" title="1.风格"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.风格</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">&#x27;quotes&#x27;: &#x27;single&#x27;;
// &quot;double&quot; (默认) 要求尽可能地使用双引号
// &quot;single&quot; 要求尽可能地使用单引号
// &quot;backtick&quot; 要求尽可能地使用反勾号</code></pre><h4 class="notion-h notion-h3 notion-block-775abbed376f4e599cfd9c9f694a9091" data-id="775abbed376f4e599cfd9c9f694a9091"><span><div id="775abbed376f4e599cfd9c9f694a9091" class="notion-header-anchor"></div><a class="notion-hash-link" href="#775abbed376f4e599cfd9c9f694a9091" title="2.code review"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.code review</span></span></h4><div class="notion-text notion-block-685a029432294653a9a5dceb0991fb3f">不太清晰</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">var foo = {
-   bar: &quot;baz&quot;,
-   qux: &quot;quux&quot;
+   bar: &quot;baz&quot; 
};</code></pre><div class="notion-text notion-block-dcefc67eef874a278cdaa3e39177166a">更清晰：</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">var foo = {     
		bar: &quot;baz&quot;,
-   qux: &quot;quux&quot;, 
};</code></pre><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">&#x27;comma-dangle&#x27;: [    
	&#x27;error&#x27;,    
	{        
		arrays: &#x27;always-multiline&#x27;,        
		objects: &#x27;always-multiline&#x27;,        
		imports: &#x27;always-multiline&#x27;,        
		exports: &#x27;always-multiline&#x27;,        
		functions: &#x27;always-multiline&#x27;,    
	},
],
// &quot;never&quot; (默认) 禁用拖尾逗号
// &quot;always&quot; 要求使用拖尾逗号
// &quot;always-multiline&quot; 当最后一个元素或属性与闭括号 ] 或 } 在 不同的行时，要求使用拖尾逗号；当在 同一行时，禁止使用拖尾逗号。
// &quot;only-multiline&quot; 当最后一个元素或属性与闭括号 ] 或 } 在 不同的行时，允许（但不要求）使用拖尾逗号；当在 同一行时，禁止使用拖尾逗号。</code></pre><h4 class="notion-h notion-h3 notion-block-c8811fd1e42147d9b6bebc4a2832cb4b" data-id="c8811fd1e42147d9b6bebc4a2832cb4b"><span><div id="c8811fd1e42147d9b6bebc4a2832cb4b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c8811fd1e42147d9b6bebc4a2832cb4b" title="3.防止出错"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.防止出错</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// 禁用不必要的转义字符
&#x27;no-useless-escape&#x27;: &#x27;error&#x27;</code></pre><div class="notion-text notion-block-b84e20b869cc493aa09e7a2d11868b5e">真人真事：本地没问题，线上打包 js 中的正则字符串会转成了 unicode (我也不知为啥会转，可能和 webpack 有关)，不必要的字符不能正确识别，导致一个正则失效了。造成公司巨大损失！（这句我瞎编的）</div><div class="notion-text notion-block-1ad9a0ecb26a468e8c6b01537c12e9e7"><b>正则字符组</b>中：会改变字符组含义的才需要转义</div><div class="notion-text notion-block-3dae483d9f9344a2a70556c5b34e14b3">1、反斜线必须转义 2、方括号必须转义 3、[^] 在首和[-]在中必须转义</div><div class="notion-text notion-block-3939d5f9b2d340d1aad733def9680038">所以以下常见的字符在字符组中是不需要转义的</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">[aeiou][$.*+?{}()|][abs^123-]</code></pre><h4 class="notion-h notion-h3 notion-block-19aba95898f046b7bd82c2ca35d196a3" data-id="19aba95898f046b7bd82c2ca35d196a3"><span><div id="19aba95898f046b7bd82c2ca35d196a3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#19aba95898f046b7bd82c2ca35d196a3" title="4.性能"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.性能</span></span></h4><div class="notion-text notion-block-5fffc8ea62e3469fb1c1f3f46b5617be">…</div><h4 class="notion-h notion-h3 notion-block-4244217b763d474b85c3738d8baf471b" data-id="4244217b763d474b85c3738d8baf471b"><span><div id="4244217b763d474b85c3738d8baf471b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4244217b763d474b85c3738d8baf471b" title="5.宿主环境"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.宿主环境</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">&#x27;no-console&#x27;: &#x27;warn&#x27;</code></pre><div class="notion-text notion-block-a9dd1a5acbc24bb5b74beb180b193a0a">…</div><div class="notion-text notion-block-757c22dd911948368a1768e9865f7eb4">其实，看看这些规则也可以了解一些 js 基础</div><h4 class="notion-h notion-h3 notion-block-1e377dd3eda6473fb81b6e994e1bd244" data-id="1e377dd3eda6473fb81b6e994e1bd244"><span><div id="1e377dd3eda6473fb81b6e994e1bd244" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1e377dd3eda6473fb81b6e994e1bd244" title="二. eslint –fix"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二. eslint –fix</span></span></h4><div class="notion-text notion-block-b8fb0ed3f65848bdb55325366bdb44c4">为什么有些可以 fix，有些不能呢？ 取决于相应规则的实现 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="http://eslint.cn/docs/developer-guide/working-with-rules#applying-fixes">http://eslint.cn/docs/developer-guide/working-with-rules#applying-fixes</a> [看源码]</div><h4 class="notion-h notion-h3 notion-block-02e1db6ac3c74f0fb91a2bb2d5c2a5a1" data-id="02e1db6ac3c74f0fb91a2bb2d5c2a5a1"><span><div id="02e1db6ac3c74f0fb91a2bb2d5c2a5a1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#02e1db6ac3c74f0fb91a2bb2d5c2a5a1" title="三. eslint-disable"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三. eslint-disable</span></span></h4><h4 class="notion-h notion-h3 notion-block-196fc98744bf4a0c873a4fc958886099" data-id="196fc98744bf4a0c873a4fc958886099"><span><div id="196fc98744bf4a0c873a4fc958886099" class="notion-header-anchor"></div><a class="notion-hash-link" href="#196fc98744bf4a0c873a4fc958886099" title="1.在文件中临时禁止规则出现警告"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.在文件中临时禁止规则出现警告</span></span></h4><div class="notion-text notion-block-0798f13d95a2407f87520c0891604517">将需要忽略的代码块用注释包裹起来</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">/* eslint-disable */
alert(&#x27;foo&#x27;);
/* eslint-enable */</code></pre><h4 class="notion-h notion-h3 notion-block-0e8b2851d2614867a10d4c66452a66c5" data-id="0e8b2851d2614867a10d4c66452a66c5"><span><div id="0e8b2851d2614867a10d4c66452a66c5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0e8b2851d2614867a10d4c66452a66c5" title="2.对指定规则的启用或者禁用警告"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.对指定规则的启用或者禁用警告</span></span></h4><div class="notion-text notion-block-c1fa428282d249aebb3d9d2c9d53d546">将需要忽略的代码块用注释包裹起来</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">/* eslint-disable no-alert, no-console */
alert(&#x27;foo&#x27;);
console.log(&#x27;bar&#x27;);
/* eslint-enable no-alert, no-console */</code></pre><h4 class="notion-h notion-h3 notion-block-c474259372cb43a89642354d1996661a" data-id="c474259372cb43a89642354d1996661a"><span><div id="c474259372cb43a89642354d1996661a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c474259372cb43a89642354d1996661a" title="3.对指定行禁用规则警告"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.对指定行禁用规则警告</span></span></h4><div class="notion-text notion-block-842e8126f9e64f7492147ce6969393a7">有两种形式</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">alert(&#x27;foo&#x27;); // eslint-disable-line
// eslint-disable-next-line
alert(&#x27;foo&#x27;);</code></pre><h4 class="notion-h notion-h3 notion-block-59c86901279c4c4a983b10f246a16248" data-id="59c86901279c4c4a983b10f246a16248"><span><div id="59c86901279c4c4a983b10f246a16248" class="notion-header-anchor"></div><a class="notion-hash-link" href="#59c86901279c4c4a983b10f246a16248" title="4.在指定行上禁用指定的某个规则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">4.在指定行上禁用指定的某个规则</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">alert(&#x27;foo&#x27;); // eslint-disable-line no-alert
// eslint-disable-next-line no-alert
alert(&#x27;foo&#x27;);</code></pre><h4 class="notion-h notion-h3 notion-block-015d99051dee4b2f96003b1920abb6bd" data-id="015d99051dee4b2f96003b1920abb6bd"><span><div id="015d99051dee4b2f96003b1920abb6bd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#015d99051dee4b2f96003b1920abb6bd" title="5.在某个特定的行上禁用多个规则"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">5.在某个特定的行上禁用多个规则</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">alert(&#x27;foo&#x27;); // eslint-disable-line no-alert, quotes, semi
// eslint-disable-next-line no-alert, quotes, semi
alert(&#x27;foo&#x27;);</code></pre><h4 class="notion-h notion-h3 notion-block-20156ee3e4a04e42bf6f40006645c578" data-id="20156ee3e4a04e42bf6f40006645c578"><span><div id="20156ee3e4a04e42bf6f40006645c578" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20156ee3e4a04e42bf6f40006645c578" title="四.使用 overrides"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">四.使用 overrides</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">&quot;overrides&quot;: [    
	{      
		&quot;files&quot;: [&quot;*-test.js&quot;,&quot;*.spec.js&quot;],      
		&quot;rules&quot;: {        
			&quot;no-unused-expressions&quot;: &quot;off&quot;      
		}    
	}
]</code></pre><h3 class="notion-h notion-h2 notion-block-c39e7ddf1ba748a59333317bef47e121" data-id="c39e7ddf1ba748a59333317bef47e121"><span><div id="c39e7ddf1ba748a59333317bef47e121" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c39e7ddf1ba748a59333317bef47e121" title="Q：一个项目，我该如何配置它的 ESLint 规则？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Q：一个项目，我该如何配置它的 ESLint 规则？</span></span></h3><div class="notion-text notion-block-42bf5d07b78b439ca61544023c6324c5"><b>plugin:</b> 扩展 ESLint 规则的定义 </div><div class="notion-text notion-block-5907d37e6a914cdabb873658fc67a10d"><b>extends:</b> 现成的设置好的规则，可覆盖 plugin 的默认配置，存在多个时后面的覆盖前面的</div><div class="notion-text notion-block-828448b5ea9b487bba5a23c29f77bd0e"><b>rules:</b> 用户配置，可覆盖 extends 中的配置 </div><div class="notion-text notion-block-7858bcb421564c0b8d3be9204be9164a"><b>overrides:</b> 可针对特定文件进行校验规则的覆盖</div><div class="notion-text notion-block-b191f8b9ce6f44149d08c865521b9e89"><b>env:</b> 指定脚本的运行环境。每种环境都有一组特定的预定义全局变量。</div><div class="notion-text notion-block-a60ad9142ad94e1fad2f752186057321"><b>globals:</b> 脚本在执行期间访问的额外的全局变量。</div><div class="notion-text notion-block-99011b3d6264439181c6e1f67052c497"><b>parser:</b> <a target="_blank" rel="noopener noreferrer" class="notion-link" href="http://eslint.cn/docs/user-guide/configuring#specifying-parser">http://eslint.cn/docs/user-guide/configuring#specifying-parser</a> </div><div class="notion-text notion-block-5e0e09405a734b2da23b9e03447433bb"><b>parserOptions:</b> <a target="_blank" rel="noopener noreferrer" class="notion-link" href="http://eslint.cn/docs/user-guide/configuring#specifying-parser-options">http://eslint.cn/docs/user-guide/configuring#specifying-parser-options</a> …</div><h4 class="notion-h notion-h3 notion-block-0aab4748dab9481aa93548456a2fb54f" data-id="0aab4748dab9481aa93548456a2fb54f"><span><div id="0aab4748dab9481aa93548456a2fb54f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0aab4748dab9481aa93548456a2fb54f" title="一.复杂配置–"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一.复杂配置–</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// 原教旨主义者
{    
	plugins: [
		&#x27;import&#x27;, 
		&#x27;jsx-a11y&#x27;, 
		&#x27;react&#x27;, 
		&#x27;react-hooks&#x27;, 
		&#x27;@typescript-eslint&#x27;
	],    
	extends: [        
		&#x27;eslint:recommended&#x27;,        
		&#x27;plugin:import/errors&#x27;,        
		&#x27;plugin:import/warnings&#x27;,        
		&#x27;plugin:import/typescript&#x27;,        
		&#x27;plugin:jsx-a11y/recommended&#x27;,        
		&#x27;plugin:react/recommended&#x27;,        
		&#x27;plugin:@typescript-eslint/recommended&#x27;,        
		&#x27;prettier&#x27;,        
		&#x27;prettier/react&#x27;,        
		&#x27;prettier/@typescript-eslint&#x27;,    
	],    
	rules: {        
		// 太严格了！改规则，改规则...    
	}
};
// or 照搬西方那套
{    
	plugins: [&#x27;react-hooks&#x27;, &#x27;@typescript-eslint&#x27;],    
	extends: [        
		&#x27;airbnb&#x27;,        
		&#x27;plugin:@typescript-eslint/recommended&#x27;,        
		&#x27;prettier&#x27;,        
		&#x27;prettier/react&#x27;,        
		&#x27;prettier/@typescript-eslint&#x27;,    
	],    
	rules: {        
		// 不适合我！改规则，改规则...    
	}
};
{    
	plugins: [&#x27;react-hooks&#x27;, &#x27;@typescript-eslint&#x27;],    
	extends: [        
		&#x27;airbnb&#x27;,        
		&#x27;airbnb-typescript&#x27;,        
		&#x27;prettier&#x27;,        
		&#x27;prettier/react&#x27;,        
		&#x27;prettier/@typescript-eslint&#x27;,    
	],    
	rules: {       
		// 不适合我！改规则，改规则...    
	}
};</code></pre><h4 class="notion-h notion-h3 notion-block-10dfd1f15537479a97f1d39cc93c695e" data-id="10dfd1f15537479a97f1d39cc93c695e"><span><div id="10dfd1f15537479a97f1d39cc93c695e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#10dfd1f15537479a97f1d39cc93c695e" title="二.简单配置++"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二.简单配置++</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// 自立根生，艰苦奋斗
{    
	plugins: [
		&#x27;import&#x27;, 
		&#x27;jsx-a11y&#x27;, 
		&#x27;react&#x27;, 
		&#x27;react-hooks&#x27;, 
		&#x27;@typescript-eslint&#x27;
	],    
	extends: [        
		&#x27;prettier&#x27;,        
		&#x27;prettier/react&#x27;,        
		&#x27;prettier/@typescript-eslint&#x27;,    
	],    
	rules: {        
		// ...        
		// ...        
		// ...        
		// ...        
		// ...        
		// ...        
		// ...    
	}
};</code></pre><h4 class="notion-h notion-h3 notion-block-bb5ad22937ab4b2ba8e27fb77f10b705" data-id="bb5ad22937ab4b2ba8e27fb77f10b705"><span><div id="bb5ad22937ab4b2ba8e27fb77f10b705" class="notion-header-anchor"></div><a class="notion-hash-link" href="#bb5ad22937ab4b2ba8e27fb77f10b705" title="三.总结适合自己团队的配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三.总结适合自己团队的配置</span></span></h4><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">// 走自己的特色道路
{    
	plugins: [&#x27;react-hooks&#x27;, &#x27;@typescript-eslint&#x27;],
  extends: [        
		&#x27;eslint-config-xxx&#x27;,        
		&#x27;prettier&#x27;,        
		&#x27;prettier/react&#x27;,        
		&#x27;prettier/@typescript-eslint&#x27;,    
	]
};
// 那些自己特别在意的 rule 可以记下来，搞一套自己的配置 eslint-config-52wa
{    
	plugins: [/* ... */],    
	extends: [        
		// ...    
	],    
	rules: {        
		&#x27;no-useless-escape&#x27;: &#x27;error&#x27;    
	}
};</code></pre><div class="notion-text notion-block-dc845314c9fa4274bbba570c43d5fb98"><code class="notion-inline-code">@umijs/fabric</code>: <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/umijs/fabric/blob/master/src/eslint.ts">https://github.com/umijs/fabric/blob/master/src/eslint.ts</a></div><div class="notion-text notion-block-159bb28ad1304cf991a61a4ce119c356"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/umijs/umi/blob/master/packages/babel-preset-umi/src/index.ts">https://github.com/umijs/umi/blob/master/packages/babel-preset-umi/src/index.ts</a></div><h3 class="notion-h notion-h2 notion-block-8a5efc5379c44e03a747aa28ff99c102" data-id="8a5efc5379c44e03a747aa28ff99c102"><span><div id="8a5efc5379c44e03a747aa28ff99c102" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8a5efc5379c44e03a747aa28ff99c102" title="Q：为什么 Prettier 的配置总是写在后面？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Q：为什么 Prettier 的配置总是写在后面？</span></span></h3><div class="notion-text notion-block-09fa8926f0354f44947d449396677deb">在我们现在的工作流里，有个 lint-staged</div><pre class="notion-code"><div class="notion-code-copy"><div class="notion-code-copy-button"><svg fill="currentColor" viewBox="0 0 16 16" width="1em" version="1.1"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg></div></div><code class="language-javascript">&quot;lint-staged&quot;: {   
	&quot;linters&quot;: {      
		&quot;*.{js,jsx,ts,tsx}&quot;: [        
			&quot;prettier --write&quot;,        
			&quot;git add&quot;,        
			&quot;eslint&quot;      
		]    
	},
}</code></pre><div class="notion-text notion-block-bff833bcd6674dbdadf2c4c8fa8ff7d8">如果 Prettier 配置优先级不是最高的，会导致 Prettier 完了，ESLint 却通不过，陷入死循环。</div><div class="notion-text notion-block-d907679c24124407846f325051f85cbd">当然，在保证相关配置相同的情况下这个顺序是无所谓的。</div><div class="notion-text notion-block-449ea3a7d88f4d3b96fa6c2ea4273a89">Prettier 中的 rule 并不多，多是些“代码风格”类型的规则 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://prettier.io/playground/">https://prettier.io/playground/</a></div><h3 class="notion-h notion-h2 notion-block-67adc97049f94e36877d7000e459309d" data-id="67adc97049f94e36877d7000e459309d"><span><div id="67adc97049f94e36877d7000e459309d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#67adc97049f94e36877d7000e459309d" title="Q：ESLint 如何工作的？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Q：ESLint 如何工作的？</span></span></h3><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c274a84d4b3f41cb84f31b1ec07ed413"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3.us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F54080fca-0da0-4df7-bcde-78cbd306103a%2Feslint.jpg%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Content-Sha256%3DUNSIGNED-PAYLOAD%26X-Amz-Credential%3DAKIAT73L2G45EIPT3X45%252F20230305%252Fus-west-2%252Fs3%252Faws4_request%26X-Amz-Date%3D20230305T125958Z%26X-Amz-Expires%3D86400%26X-Amz-Signature%3Df40f9501126b3f0f0a153acefe8919e0c31bfacc9fc663457419196f7ad7ca5e%26X-Amz-SignedHeaders%3Dhost%26x-id%3DGetObject?table=block&amp;id=c274a84d-4b3f-41cb-84f3-1b1ec07ed413" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-b2892331e08040298e42d9602fe8cf36">Node 命令行工具 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/eslint/eslint">https://github.com/eslint/eslint</a></div><div class="notion-text notion-block-0bc87fda99b548058efeef2591cb15ce">VSCode 插件 <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/microsoft/vscode-eslint">https://github.com/microsoft/vscode-eslint</a></div><h3 class="notion-h notion-h2 notion-block-9d3f8a96a2c943d790d75980e78f7214" data-id="9d3f8a96a2c943d790d75980e78f7214"><span><div id="9d3f8a96a2c943d790d75980e78f7214" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9d3f8a96a2c943d790d75980e78f7214" title="Q：怎么搞一套自己的 config？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Q：怎么搞一套自己的 config？</span></span></h3><div class="notion-text notion-block-6e27a261b7c047c894c0cf1208a62654"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://eslint.bootcss.com/docs/developer-guide/shareable-configs">https://eslint.bootcss.com/docs/developer-guide/shareable-configs</a></div><div class="notion-text notion-block-c71378c6972a49dca1e19aad60de7a4e">以 <code class="notion-inline-code">eslint-config-xxx</code> 为例</div><h3 class="notion-h notion-h2 notion-block-ebdfc4a959d74c64bb54a2d12107dfb2" data-id="ebdfc4a959d74c64bb54a2d12107dfb2"><span><div id="ebdfc4a959d74c64bb54a2d12107dfb2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ebdfc4a959d74c64bb54a2d12107dfb2" title="Q：怎么搞个自己的规则？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Q：怎么搞个自己的规则？</span></span></h3><div class="notion-text notion-block-18ea7887dd9a4fa4a20ab70cb1dfe8e0"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://eslint.bootcss.com/docs/developer-guide/working-with-plugins">https://eslint.bootcss.com/docs/developer-guide/working-with-plugins</a></div><div class="notion-text notion-block-bcae3d632d534c3eb5729c9d1619df97">以 <code class="notion-inline-code">import/no-unresolved</code> 为例 可以自动 fix: 以 <code class="notion-inline-code">jsx-quotes</code> 为例</div></div></div></main><!--$--><!--/$--></div>]]></content:encoded>
        </item>
    </channel>
</rss>