久草视频2-久草视-久草社区视频-久草色在线-久草色视频-久草软件

前端編碼風格規范(3)—— JavaScript 規范 – WEB前端開發

我是創始人李巖:很抱歉!給自己產品做個廣告,點擊進來看看。  
原文: Web Styleguide – Style guide to harmonize HTML, Javascript and CSS / SASS coding style

JavaScript 規范


全局命名空間污染與 IIFE

總是將代碼包裹成一個 IIFE(Immediately-Invoked Function Expression),用以創建獨立隔絕的定義域。這一舉措可防止全局命名空間被污染。

IIFE 還可確保你的代碼不會輕易被其它全局命名空間里的代碼所修改(i.e. 第三方庫,window 引用,被覆蓋的未定義的關鍵字等等)。

不推薦

			var x = 10,
			y = 100;
			// Declaring variables in the global scope is resulting in global scope pollution. All variables declared like this
			// will be stored in the window object. This is very unclean and needs to be avoided.
			console.log(window.x + ' ' + window.y);
		

推薦

			// We declare a IIFE and pass parameters into the function that we will use from the global space
			(function(log, w, undefined){
			'use strict';
			var x = 10,
			y = 100;
			// Will output 'true true'
			log((w.x === undefined) + ' ' + (w.y === undefined));
			}(window.console.log, window));
		

IIFE(立即執行的函數表達式)

無論何時,想要創建一個新的封閉的定義域,那就用 IIFE。它不僅避免了干擾,也使得內存在執行完后立即釋放。

所有腳本文件建議都從 IIFE 開始。

立即執行的函數表達式的執行括號應該寫在外包括號內。雖然寫在內還是寫在外都是有效的,但寫在內使得整個表達式看起來更像一個整體,因此推薦這么做。

不推薦

(function(){})();

推薦

(function(){}());

so,用下列寫法來格式化你的 IIFE 代碼:

			(function(){
			'use strict';
			// Code goes here
			}());
		

如果你想引用全局變量或者是外層 IIFE 的變量,可以通過下列方式傳參:

			(function($, w, d){
			'use strict';
			$(function() {
			w.alert(d.querySelectorAll('div').length);
			});
			}(jQuery, window, document));
		

嚴格模式

ECMAScript 5 嚴格模式可在整個腳本或獨個方法內被激活。它對應不同的 javascript 語境會做更加嚴格的錯誤檢查。嚴格模式也確保了 javascript 代碼更加的健壯,運行的也更加快速。

嚴格模式會阻止使用在未來很可能被引入的預留關鍵字。

你應該在你的腳本中啟用嚴格模式,最好是在獨立的 IIFE 中應用它。避免在你的腳本第一行使用它而導致你的所有腳本都啟動了嚴格模式,這有可能會引發一些第三方類庫的問題。

不推薦

			// Script starts here
			'use strict';
			(function(){
			// Your code starts here
			}());
		

推薦

			(function(){
			'use strict';
			// Your code starts here
			}());
		

變量聲明

總是使用 var 來聲明變量。如不指定 var,變量將被隱式地聲明為全局變量,這將對變量難以控制。如果沒有聲明,變量處于什么定義域就變得不清(可以是在 Document 或 Window 中,也可以很容易地進入本地定義域)。所以,請總是使用 var 來聲明變量。

采用嚴格模式帶來的好處是,當你手誤輸入錯誤的變量名時,它可以通過報錯信息來幫助你定位錯誤出處。

不推薦

			x = 10;
			y = 100;
		

推薦

			var x = 10,
			y = 100;
		

理解 JavaScript 的定義域和定義域提升

在 JavaScript 中變量和方法定義會自動提升到執行之前。JavaScript 只有 function 級的定義域,而無其他很多編程語言中的塊定義域,所以使得你在某一 function 內的某語句和循環體中定義了一個變量,此變量可作用于整個 function 內,而不僅僅是在此語句或循環體中,因為它們的聲明被 JavaScript 自動提升了。

我們通過例子來看清楚這到底是怎么一回事:

原 function

			(function(log){
			'use strict';
			var a = 10;
			for(var i = 0; i
			< a; i++) {
			var b = i * i;
			log(b);
			}
			if(a === 10) {
			var f = function() {
			log(a);
			};
			f();
			}
			function x() {
			log('Mr. X!');
			}
			x();
			}(window.console.log));
		

被 JS 提升過后

			(function(log){
			'use strict';
			// All variables used in the closure will be hoisted to the top of the function
			var a,
			i,
			b,
			f;
			// All functions in the closure will be hoisted to the top
			function x() {
			log('Mr. X!');
			}
			a = 10;
			for(i = 0; i
			< a; i++) {
			b = i * i;
			log(b);
			}
			if(a === 10) {
			// Function assignments will only result in hoisted variables but the function body will not be hoisted
			// Only by using a real function declaration the whole function will be hoisted with its body
			f = function() {
			log(a);
			};
			f();
			}
			x();
			}(window.console.log));
		

根據以上提升過程,你是否可理解以下代碼?

有效代碼

			(function(log){
			'use strict';
			var a = 10;
			i = 5;
			x();
			for(var i; i
			< a; i++) {
			log(b);
			var b = i * i;
			}
			if(a === 10) {
			f = function() {
			log(a);
			};
			f();
			var f;
			}
			function x() {
			log('Mr. X!');
			}
			}(window.console.log));
		

正如你所看到的這段令人充滿困惑與誤解的代碼導致了出人意料的結果。只有良好的聲明習慣,也就是下一章節我們要提到的聲明規則,才能盡可能的避免這類錯誤風險。


提升聲明

為避免上一章節所述的變量和方法定義被自動提升造成誤解,把風險降到最低,我們應該手動地顯示地去聲明變量與方法。也就是說,所有的變量以及方法,應當定義在 function 內的首行。

只用一個 var 關鍵字聲明,多個變量用逗號隔開。

不推薦

			(function(log){
			'use strict';
			var a = 10;
			var b = 10;
			for(var i = 0; i
			< 10; i++) {
			var c = a * b * i;
			}
			function f() {
			}
			var d = 100;
			var x = function() {
			return d * d;
			};
			log(x());
			}(window.console.log));
		

推薦

			(function(log){
			'use strict';
			var a = 10,
			b = 10,
			i,
			c,
			d,
			x;
			function f() {
			}
			for(i = 0; i
			< 10; i++) {
			c = a * b * i;
			}
			d = 100;
			x = function() {
			return d * d;
			};
			log(x());
			}(window.console.log));
		

把賦值盡量寫在變量申明中。

不推薦

			var a,
			b,
			c;
			a = 10;
			b = 10;
			c = 100;
		

推薦

			var a = 10,
			b = 10,
			c = 100;
		

總是使用帶類型判斷的比較判斷

總是使用 === 精確的比較操作符,避免在判斷的過程中,由 JavaScript 的強制類型轉換所造成的困擾。

如果你使用 === 操作符,那比較的雙方必須是同一類型為前提的條件下才會有效。

如果你想了解更多關于強制類型轉換的信息,你可以讀一讀 Dmitry Soshnikov 的這篇文章 。

在只使用 == 的情況下,JavaScript 所帶來的強制類型轉換使得判斷結果跟蹤變得復雜,下面的例子可以看出這樣的結果有多怪了:

			(function(log){
			'use strict';
			log('0' == 0); // true
			log('' == false); // true
			log('1' == true); // true
			log(null == undefined); // true
			var x = {
			valueOf: function() {
			return 'X';
			}
			};
			log(x == 'X');
			}(window.console.log));
		

明智地使用真假判斷

當我們在一個 if 條件語句中使用變量或表達式時,會做真假判斷。 if(a == true) 是不同于 if(a) 的。后者的判斷比較特殊,我們稱其為真假判斷。這種判斷會通過特殊的操作將其轉換為 true 或 false,下列表達式統統返回 false: false , 0 , undefined , null , NaN , '' (空字符串).

這種真假判斷在我們只求結果而不關心過程的情況下,非常的有幫助。

以下示例展示了真假判斷是如何工作的:

			(function(log){
			'use strict';
			function logTruthyFalsy(expr) {
			if(expr) {
			log('truthy');
			} else {
			log('falsy');
			}
			}
			logTruthyFalsy(true); // truthy
			logTruthyFalsy(1); // truthy
			logTruthyFalsy({}); // truthy
			logTruthyFalsy([]); // truthy
			logTruthyFalsy('0'); // truthy
			logTruthyFalsy(false); // falsy
			logTruthyFalsy(0); // falsy
			logTruthyFalsy(undefined); // falsy
			logTruthyFalsy(null); // falsy
			logTruthyFalsy(NaN); // falsy
			logTruthyFalsy(''); // falsy
			}(window.console.log));
		

變量賦值時的邏輯操作

邏輯操作符 ||&& 也可被用來返回布爾值。如果操作對象為非布爾對象,那每個表達式將會被自左向右地做真假判斷?;诖瞬僮鳎罱K總有一個表達式被返回回來。這在變量賦值時,是可以用來簡化你的代碼的。

不推薦

			if(!x) {
			if(!y) {
			x = 1;
			} else {
			x = y;
			}
			}
		

推薦

x = x || y || 1;

這一小技巧經常用來給方法設定默認的參數。

			(function(log){
			'use strict';
			function multiply(a, b) {
			a = a || 1;
			b = b || 1;
			log('Result ' + a * b);
			}
			multiply(); // Result 1
			multiply(10); // Result 10
			multiply(3, NaN); // Result 3
			multiply(9, 5); // Result 45
			}(window.console.log));
		

分號

總是使用分號,因為隱式的代碼嵌套會引發難以察覺的問題。當然我們更要從根本上來杜絕這些問題 [1] 。以下幾個示例展示了缺少分號的危害:

			// 1.
			MyClass.prototype.myMethod = function() {
			return 42;
			}  // No semicolon here.
			(function() {
			// Some initialization code wrapped in a function to create a scope for locals.
			})();
			var x = {
			'i': 1,
			'j': 2
			}  // No semicolon here.
			// 2.  Trying to do one thing on Internet Explorer and another on Firefox.
			// I know you'd never write code like this, but throw me a bone.
			[ffVersion, ieVersion][isIE]();
			var THINGS_TO_EAT = [apples, oysters, sprayOnCheese]  // No semicolon here.
			// 3. conditional execution a la bash
			-1 == resultOfOperation() || die();
		

So what happens?

  1. JavaScript 錯誤 —— 首先返回 42 的那個 function 被第二個 function 當中參數傳入調用,接著數字 42 也被“調用”而導致出錯。
  2. 八成你會得到 ‘no such property in undefined’ 的錯誤提示,因為在真實環境中的調用是這個樣子: x[ffVersion, ieVersion][isIE]() .
  3. die 總是被調用。因為數組減 1 的結果是 NaN ,它不等于任何東西(無論 resultOfOperation 是否返回 NaN )。所以最終的結果是 die() 執行完所獲得值將賦給 THINGS_TO_EAT .

Why?

JavaScript 中語句要以分號結束,否則它將會繼續執行下去,不管換不換行。以上的每一個示例中,函數聲明或對象或數組,都變成了在一句語句體內。要知道閉合圓括號并不代表語句結束,JavaScript 不會終結語句,除非它的下一個 token 是一個中綴符 [2] 或者是圓括號操作符。

這真是讓人大吃一驚,所以乖乖地給語句末加上分號吧。

澄清:分號與函數

分號需要用在表達式的結尾,而并非函數聲明的結尾。區分它們最好的例子是:

			var foo = function() {
			return true;
			};  // semicolon here.
			function foo() {
			return true;
			}  // no semicolon here.
		

嵌套函數

嵌套函數是非常有用的,比如用在持續創建和隱藏輔助函數的任務中。你可以非常自由隨意地使用它們。


語句塊內的函數聲明

切勿在語句塊內聲明函數,在 ECMAScript 5 的嚴格模式下,這是不合法的。函數聲明應該在定義域的頂層。但在語句塊內可將函數申明轉化為函數表達式賦值給變量。

不推薦

			if (x) {
			function foo() {}
			}
		

推薦

			if (x) {
			var foo = function() {};
			}
		

異常

基本上你無法避免出現異常,特別是在做大型開發時(使用應用開發框架等等)。

在沒有自定義異常的情況下,從有返回值的函數中返回錯誤信息一定非常的棘手,更別提多不優雅了。不好的解決方案包括了傳第一個引用類型來接納錯誤信息,或總是返回一個對象列表,其中包含著可能的錯誤對象。以上方式基本上是比較簡陋的異常處理方式。適時可做自定義異常處理。

在復雜的環境中,你可以考慮拋出對象而不僅僅是字符串(默認的拋出值)。

			if(name === undefined) {
			throw {
			name: 'System Error',
			message: 'A name should always be specified!'
			}
			}
		

標準特性

總是優先考慮使用標準特性。為了最大限度地保證擴展性與兼容性,總是首選標準的特性,而不是非標準的特性(例如:首選 string.charAt(3) 而不是 string[3] ;首選 DOM 的操作方法來獲得元素引用,而不是某一應用特定的快捷方法)。


簡易的原型繼承

如果你想在 JavaScript 中繼承你的對象,請遵循一個簡易的模式來創建此繼承。如果你預計你會遇上復雜對象的繼承,那可以考慮采用一個繼承庫,比如 Proto.js by Axel Rauschmayer .

簡易繼承請用以下方式:

			(function(log){
			'use strict';
			// Constructor function
			function Apple(name) {
			this.name = name;
			}
			// Defining a method of apple
			Apple.prototype.eat = function() {
			log('Eating ' + this.name);
			};
			// Constructor function
			function GrannySmithApple() {
			// Invoking parent constructor
			Apple.prototype.constructor.call(this, 'Granny Smith');
			}
			// Set parent prototype while creating a copy with Object.create
			GrannySmithApple.prototype = Object.create(Apple.prototype);
			// Set constructor to the sub type, otherwise points to Apple
			GrannySmithApple.prototype.constructor = GrannySmithApple;
			// Calling a super method
			GrannySmithApple.prototype.eat = function() {
			// Be sure to apply it onto our current object with call(this)
			Apple.prototype.eat.call(this);
			log('Poor Grany Smith');
			};
			// Instantiation
			var apple = new Apple('Test Apple');
			var grannyApple = new GrannySmithApple();
			log(apple.name); // Test Apple
			log(grannyApple.name); // Granny Smith
			// Instance checks
			log(apple instanceof Apple); // true
			log(apple instanceof GrannySmithApple); // false
			log(grannyApple instanceof Apple); // true
			log(grannyApple instanceof GrannySmithApple); // true
			// Calling method that calls super method
			grannyApple.eat(); // Eating Granny Smith\nPoor Grany Smith
			}(window.console.log));
		

使用閉包

閉包的創建也許是 JS 最有用也是最易被忽略的能力了。 關于閉包如何工作的合理解釋 。


切勿在循環中創建函數

在簡單的循環語句中加入函數是非常容易形成閉包而帶來隱患的。下面的例子就是一個典型的陷阱:

不推薦

			(function(log, w){
			'use strict';
			// numbers and i is defined in the current function closure
			var numbers = [1, 2, 3],
			i;
			for(i = 0; i
			< numbers.length; i++) {
			w.setTimeout(function() {
			// At the moment when this gets executed the i variable, coming from the outer function scope
			// is set to 3 and the current program is alerting the message 3 times
			// 'Index 3 with number undefined
			// If you understand closures in javascript you know how to deal with those cases
			// It's best to just avoid functions / new closures in loops as this prevents those issues
			w.alert('Index ' + i + ' with number ' + numbers[i]);
			}, 0);
			}
			}(window.console.log, window));
		

接下來的改進雖然已經解決了上述例子中的問題或 bug,但還是違反了不在循環中創建函數或閉包的原則。

不推薦

			(function(log, w){
			'use strict';
			// numbers and i is defined in the current function closure
			var numbers = [1, 2, 3],
			i;
			for(i = 0; i
			< numbers.length; i++) {
			// Creating a new closure scope with an IIFE solves the problem
			// The delayed function will use index and number which are
			// in their own closure scope (one closure per loop iteration).
			// ---
			// Still this is not recommended as we violate our rule to not
			// create functions within loops and we are creating two!
			(function(index, number){
			w.setTimeout(function() {
			// Will output as expected 0 > 1, 1 > 2, 2 > 3
			w.alert('Index ' + index + ' with number ' + number);
			}, 0);
			}(i, numbers[i]));
			}
			}(window.console.log, window));
		

接下來的改進已解決問題,而且也遵循了規范。可是,你會發現看上去似乎過于復雜繁冗了,應該會有更好的解決方案吧。

不完全推薦

			(function(log, w){
			'use strict';
			// numbers and i is defined in the current function closure
			var numbers = [1, 2, 3],
			i;
			// Create a function outside of the loop that will accept arguments to create a
			// function closure scope. This function will return a function that executes in this
			// closure parent scope.
			function alertIndexWithNumber(index, number) {
			return function() {
			w.alert('Index ' + index + ' with number ' + number);
			};
			}
			// First parameter is a function call that returns a function.
			// ---
			// This solves our problem and we don't create a function inside our loop
			for(i = 0; i
			< numbers.length; i++) {
			w.setTimeout(alertIndexWithNumber(i, numbers[i]), 0);
			}
			}(window.console.log, window));
		

將循環語句轉換為函數執行的方式問題能得到立馬解決,每一次循環都會對應地創建一次閉包。函數式的風格更加值得推薦,而且看上去也更加地自然和可預料。

推薦

			(function(log, w){
			'use strict';
			// numbers and i is defined in the current function closure
			var numbers = [1, 2, 3],
			i;
			numbers.forEach(function(number, index) {
			w.setTimeout(function() {
			w.alert('Index ' + index + ' with number ' + number);
			}, 0);
			});
			}(window.console.log, window));
		

eval 函數(魔鬼)

eval() 不但混淆語境還很危險,總會有比這更好、更清晰、更安全的另一種方案來寫你的代碼,因此盡量不要使用 evil 函數。


this 關鍵字

只在對象構造器、方法和在設定的閉包中使用 this 關鍵字。this 的語義在此有些誤導。它時而指向全局對象(大多數時),時而指向調用者的定義域(在 eval 中),時而指向 DOM 樹中的某一節點(當用事件處理綁定到 HTML 屬性上時),時而指向一個新創建的對象(在構造器中),還時而指向其它的一些對象(如果函數被 call()apply() 執行和調用時)。

正因為它是如此容易地被搞錯,請限制它的使用場景:

  • 在構造函數中
  • 在對象的方法中(包括由此創建出的閉包內)

首選函數式風格

函數式編程讓你可以簡化代碼并縮減維護成本,因為它容易復用,又適當地解耦和更少的依賴。

接下來的例子中,在一組數字求和的同一問題上,比較了兩種解決方案。第一個例子是經典的程序處理,而第二個例子則是采用了函數式編程和 ECMA Script 5.1 的數組方法。

例外:往往在重代碼性能輕代碼維護的情況之下,要選擇最優性能的解決方案而非維護性高的方案(比如用簡單的循環語句代替 forEach)。

不推薦

			(function(log){
			'use strict';
			var arr = [10, 3, 7, 9, 100, 20],
			sum = 0,
			i;
			for(i = 0; i
			< arr.length; i++) {
			sum += arr[i];
			}
			log('The sum of array ' + arr + ' is: ' + sum)
			}(window.console.log));
		

推薦

			(function(log){
			'use strict';
			var arr = [10, 3, 7, 9, 100, 20];
			var sum = arr.reduce(function(prevValue, currentValue) {
			return prevValue + currentValue;
			}, 0);
			log('The sum of array ' + arr + ' is: ' + sum);
			}(window.console.log));
		

另一個例子通過某一規則對一個數組進行過濾匹配來創建一個新的數組。

不推薦

			(function(log){
			'use strict';
			var numbers = [11, 3, 7, 9, 100, 20, 14, 10],
			numbersGreaterTen = [],
			i;
			for(i = 0; i
			< numbers.length; i++) {
			if(numbers[i] > 10) {
			numbersGreaterTen.push(numbers[i]);
			}
			}
			log('From the list of numbers ' + numbers + ' only ' + numbersGreaterTen + ' are greater than ten');
			}(window.console.log));
		

推薦

			(function(log){
			'use strict';
			var numbers = [11, 3, 7, 9, 100, 20, 14, 10];
			var numbersGreaterTen = numbers.filter(function(element) {
			return element > 10;
			});
			log('From the list of numbers ' + numbers + ' only ' + numbersGreaterTen + ' are greater than ten');
			}(window.console.log));
		

使用 ECMA Script 5

建議使用 ECMA Script 5 中新增的語法糖和函數。這將簡化你的程序,并讓你的代碼更加靈活和可復用。


數組和對象的屬性迭代

用 ECMA5 的迭代方法來迭代數組。使用 Array.forEach 或者如果你要在特殊場合下中斷迭代,那就用 Array.every

			(function(log){
			'use strict';
			// Iterate over an array and break at a certain condition
			[1, 2, 3, 4, 5].every(function(element, index, arr) {
			log(element + ' at index ' + index + ' in array ' + arr);
			if(index !== 5) {
			return true;
			}
			});
			// Defining a simple javascript object
			var obj = {
			a: 'A',
			b: 'B',
			'c-d-e': 'CDE'
			};
			// Iterating over the object keys
			Object.keys(obj).forEach(function(element, index, arr) {
			log('Key ' + element + ' has value ' + obj[element]);
			});
			}(window.console.log));
		

不要使用 switch

switch 在所有的編程語言中都是個非常錯誤的難以控制的語句,建議用 if else 來替換它。


數組和對象字面量

用數組和對象字面量來代替數組和對象構造器。數組構造器很容易讓人在它的參數上犯錯。

不推薦

			// Length is 3.
			var a1 = new Array(x1, x2, x3);
			// Length is 2.
			var a2 = new Array(x1, x2);
			// If x1 is a number and it is a natural number the length will be x1.
			// If x1 is a number but not a natural number this will throw an exception.
			// Otherwise the array will have one element with x1 as its value.
			var a3 = new Array(x1);
			// Length is 0.
			var a4 = new Array();
		

正因如此,如果將代碼傳參從兩個變為一個,那數組很有可能發生意料不到的長度變化。為避免此類怪異狀況,請總是采用更多可讀的數組字面量。

推薦

			var a = [x1, x2, x3];
			var a2 = [x1, x2];
			var a3 = [x1];
			var a4 = [];
		

對象構造器不會有類似的問題,但是為了可讀性和統一性,我們應該使用對象字面量。

不推薦

			var o = new Object();
			var o2 = new Object();
			o2.a = 0;
			o2.b = 1;
			o2.c = 2;
			o2['strange key'] = 3;
		

應該寫成這樣:

推薦

			var o = {};
			var o2 = {
			a: 0,
			b: 1,
			c: 2,
			'strange key': 3
			};
		

修改內建對象的原型鏈

修改內建的諸如 Object.prototypeArray.prototype 是被嚴厲禁止的。修改其它的內建對象比如 Function.prototype ,雖危害沒那么大,但始終還是會導致在開發過程中難以 debug 的問題,應當也要避免。


自定義 toString() 方法

你可以通過自定義 toString() 來控制對象字符串化。這很好,但你必須保證你的方法總是成功并不會有其它副作用。如果你的方法達不到這樣的標準,那將會引發嚴重的問題。如果 toString() 調用了一個方法,這個方法做了一個斷言 [3] ,當斷言失敗,它可能會輸出它所在對象的名稱,當然對象也需要調用 toString() 。


圓括號

一般在語法和語義上真正需要時才謹慎地使用圓括號。不要用在一元操作符上,例如 delete , typeofvoid ,或在關鍵字之后,例如 return , throw , case , new 等。


字符串

統一使用單引號(‘),不使用雙引號(“)。這在創建 HTML 字符串非常有好處:

var msg = 'This is some HTML <div class="makes-sense"></div>';

三元條件判斷(if 的快捷方法)

用三元操作符分配或返回語句。在比較簡單的情況下使用,避免在復雜的情況下使用。沒人愿意用 10 行三元操作符把自己的腦子繞暈。

不推薦

			if(x === 10) {
			return 'valid';
			} else {
			return 'invalid';
			}
		

推薦

return x === 10 ? 'valid' : 'invalid';

[1]:作者指的是采用嚴格規范的語句寫法,從根本上杜絕由分號缺失而引起的代碼歧義。

[2]:中綴符,指的是像 x + y 中的 +

[3]:斷言一般指程序員在測試測序時的假設,一般是一些布爾表達式,當返回是 true 時,斷言為真,代碼運行會繼續進行;如果條件判斷為 false,代碼運行停止,你的應用被終止。


系列文章

  • 前端編碼規范(1)—— 一般規范
  • 前端編碼規范(2)—— HTML 規范
  • 前端編碼規范(3)—— JavaScript 規范
  • 前端編碼規范(4)—— CSS 和 Sass (SCSS) 規范

本文被轉載1次

首發媒體 Web前端開發 | 轉發媒體

隨意打賞

提交建議
微信掃一掃,分享給好友吧。
主站蜘蛛池模板: 日日骑夜夜操 | 一级黄色大片免费 | 国产一区二区三区四区三区四 | 国产精品久久久久久久久久久久午衣片 | 国产91在线播放九色快色 | 亚洲欧美人色综合婷婷久久 | 免费的男女羞羞视频软件 | 国产精品成人一区二区三区夜夜夜 | 欧美激情亚洲一区 | 女人解开乳罩给男人吃奶 | 国产免费一区二区三区香蕉精 | 一本大道熟女人妻中文字幕在线 | 天天爽天天噜在线播放 | 337p日本欧洲亚洲大胆色噜噜 | 亚洲精品一区二区三区99 | 网站黄色在线免费观看 | 亚洲偷自拍另类图片二区 | 国内精品久久久久久久97牛牛 | 久久九九精品国产综合喷水 | 成人免费一级片 | 在线观看久 | 一本大道久久a久久精品综合1 | 国产日韩欧美日韩 | 干片网在线观看 | 亚洲乱码一区二区三区在线观看 | 中文字幕一区在线观看视频 | 欧美日韩在线视频 | 一级录像免费录像性高湖 | 精品人妻一区二区三区浪潮在线 | 国产精品无码翘臀在线看 | 日产精致一致六区麻豆 | 色婷婷久久综合中文久久蜜桃av | av手机免费在线观看 | 国产毛片精品 | 久久视频免费在线观看 | 日韩视频在线观看一区二区三区 | 天堂最新资源在线 | 日本视频高清一区二区三区 | 丁香六月啪啪 | 女女les互磨高潮国产精品 | 中文字幕在线播出 | 久久久久国产精品久久久久 | 欧美精品区 | 波多野结衣亚洲一区二区 | 中文人妻无码一区二区三区 | 秋霞网久久 | 国产黄色一级 | 无人在线观看免费高清视频的优势 | 色无极亚洲影院 | 国产老女人精品毛片久久 | 亚洲视频在线观看一区 | 偷拍激情视频一区二区三区 | 欧美色乱 | 播五月婷婷 | 国产 在线 | 日韩 | 欧美激情精品久久久久久变态 | 欧美精品一区二区三区四区五区 | 91久久久精品国产一区二区蜜臀 | 日韩精品极品视频 | 色哟哟免费 | 国产清纯白嫩美女正无套播放 | 国产亚洲不卡 | 伊人天天| 日一日干一干 | 国产国语性生话播放 | 色秀av| xxxeexxx性国产 | 色婷婷综合激情综在线播放 | 日韩欧美一级在线 | 蜜臀av性久久久久av蜜臀妖精 | 无码少妇一区二区三区免费 | 日日拍夜夜拍 | 国产毛片一区二区 | 亚洲精品亚洲 | 无码午夜人妻一区二区三区不卡视频 | 中文字幕日韩三级 | 欧美日韩成人免费看片 | 亚洲熟女乱综合一区二区 | 性xxxx欧美老妇胖老太性多毛 | 在线观看黄色毛片 | 7777精品久久久久久 | 男女69式互吃动态图在线观看 | 放荡闺蜜高h苏桃情事h | 国产精品久久呻吟 | 亚洲精品久久久久中文字幕m男 | 我要看一级黄色毛片 | 欧美成人精品高清视频在线观看 | 国产在线观看你懂的 | 日韩一级色片 | 福利一区二区三区视频在线观看 | 五月天久久综合 | 欧美成人黑人xx视频免费观看 | 亚洲欧美日韩视频一区 | 国产午夜成人免费看片 | 精品黑人一区二区三区 | 7k7k在线看片午夜 | 日韩有码一区 | 高辣h文乱乳h文男男双性视频 | 国产午夜精品久久久久免费视 | 免费看的av | 国产午夜福利在线观看视频 | 欧美成人资源 | 国产成人无码网站 | 性猛交娇小69hd | 日韩欧美一区二区三区免费观看 | 性高潮免费视频 | 91在线porny国产在线看 | 国产真实乱偷精品视频 | 久久成年片色大黄全免费网站 | 日本成人动漫在线观看 | 久久视频在线观看精品 | 草草影院国产 | 亚洲乱码日产精品bd | 永久免费不卡在线观看黄网站 | 成人免费毛片足控 | 国产高潮网站 | 国产在线永久视频 | 亚洲色偷偷男人的天堂 | 调教一区 | 日本欧美大码a在线观看 | 欧美激情在线一区 | 亚洲免费精品网站 | 午夜国人精品av免费看 | 国产51人人成人人人人爽色哟哟 | 午夜精品国产精品大乳美女 | 亚洲欧美日韩中文久久 | 国产乱淫av片 | 色哟哟网站在线观看 | 激情欧美日韩 | 欧美成人中文字幕 | 日本精品视频一区二区三区四区 | 国产人体视频 | 成人性生生活a | 国产精品调教视频 | 国产男女猛烈无遮掩视频免费网站 | 久久毛片视频 | 国产精品theporn | 亚洲日韩av在线观看 | 成人动漫区 | 欧美精品第20页 | 性欧美18一19内谢 | 男女啪啪十八 | 熟女少妇在线视频播放 | 欧美两根一起进3p做受视频 | 秋霞国产午夜精品免费视频 | 手机在线免费毛片 | av日韩在线播放 | 日本老肥婆bbbwbbbwzr | 久久精品无码一区二区日韩av | 无码丰满熟妇juliaann与黑人 | 日韩视频一区二区三区在线播放免费观看 | 国产精品7777777 | 免费看av软件 | 一个人看的视频www在线 | 欧美激情精品久久久久 | 人人曰 | 韩国精品一区 | 国产精品人人爱一区二区白浆 | 51国产偷自视频区视频小蝌蚪 | 波多野结衣绝顶大高潮 | 欧美色综合天天久久综合精品 | 一卡二卡三卡视频 | 久久99精品久久只有精品 | 色婷婷综合久色aⅴ五区最新 | www麻豆| 国产主播大尺度精品福利免费 | 18禁肉肉无遮挡无码网站 | 香港三级日本三级 | 欧美色噜噜| 国产精品一区二区含羞草 | 性欧美18一19性猛交 | 国产黄色片网站 | 午夜九九 | 亚洲精品自拍偷拍 | 51av视频| 强开小嫩苞一区二区三区网站 | 亚洲中文字幕乱码av波多ji | 欧美激情视频网址 | 蜜臀aⅴ国产精品久久久国产老师 | 精品国产乱码久久久久久婷婷 | 91av视频免费观看 | 91网页版| 精久久久久久 | 亚洲黑人精品一区在线观看 | 无尽3d精品hentai在线视频 | 久久精品入口九色 | 草色噜噜噜av在线观看香蕉 | 少妇毛片一区二区三区 | 亚洲欧洲精品视频 | 一区二区三区在线免费视频 | 女性无套免费网站在线看动漫 | 久久免费看少妇高清激情 | 97久久精品无码一区二区天美 | 久久久精品免费看 | 少妇公车张开腿迎合巨大视频 | 四虎影视成人永久免费观看亚洲欧美 | 侵犯在线一区二区三区 | 国产精品婷婷 | 黄色片播放器 | 美女扒开屁股让男人桶 | 精品1区2区3区 | 欧美黑人性xxx | 中文在线www | 亚洲va国产va天堂va久久 | 日本高清视频网站www | 国产精品成人免费看片 | 黄色一级片视频 | 国产精品一区二区手机在线观看 | 国产亚洲婷婷香蕉久久精品 | 日本专区在线 | 国产精品入口夜色视频大尺度 | 伊人精品成人久久综合软件 | 少妇人妻综合久久中文字幕 | 青青草成人免费 | 本道久久综合无码中文字幕 | 亚洲欧美日韩高清 | av大帝在线| 免费麻豆av| 91精品国产色综合久久久浪潮 | 午夜影院免费看 | 校园春色 亚洲色图 | 久久久久se色偷偷亚洲精品av | 成年男女免费视频网站 | av每日更新在线观看 | 欧美牲交a欧美在线 | 蜜桃av鲁一鲁一鲁一鲁俄罗斯的 | 国产精品国产三级国产专区51 | 亚洲天堂av一区二区三区 | 久久久久久久久久久中文字幕 | 久久在线中文字幕 | 999久久久 | 中日韩精品在线 | 男人猛躁进女人免费播放 | 在线观看黄网址 | 黄色成人免费网站 | 成人在线污 | 欧洲美女与动zooz | eeuss影院一区二区三区 | 99久久精品无码一区二区三区 | 国内精品国产成人国产三级 | 少妇裸体做爰免费视频网站 | 日产精品高潮呻吟av久久 | 亚洲精品久久蜜桃站 | 九九99九九精彩3 | 日本亚洲9999aⅴ | 欧美精品videossex少妇 | 亚洲色婷婷久久精品av蜜桃 | 日本丰满大乳乳奶 | 亚洲va中文字幕 | 国产高清不卡视频 | 波多野结衣在线观看视频 | 成人免费观看网站 | av小说免费在线观看 | 日韩免费视频一区 | а√最新版在线天堂8 | 亚洲偷怕 | 午夜一级大片 | 欧洲高潮视频在线看 | 激情欧美日韩一区二区 | 精国产品一区二区三区a片 日韩av在线观看免费 | 中文字幕无码人妻aaa片 | 性久久久久久久 | 国内成人在线 | 亚洲狠狠婷婷久久久四季av | 永久免费看啪啪的网站 | 亚洲精品无码久久久久久 | 少妇一级淫片aaaaaaa | 亚洲一区视频 | 韩国av在线 | 国产一区二区播放 | 大尺度做爰床戏呻吟沙漠 | 波多野结衣av在线观看 | 国产精品视频在线免费观看 | 麻豆精品免费视频 | 波多野结衣在线观看一区 | 国产成人免费高清激情视频 | 欧美视频免费看欧美视频 | 超碰婷婷 | 一级又爽又黄的免费毛片视频 | 国产精品久久久久无码av色戒 | 波多野结衣影院 | 亚洲国产丝袜 | 美女视频久久久 | 美女100%挤奶水视频吃胸网站 | 欧美午夜在线视频 | 亚洲手机视频 | 久久久久99人妻一区二区三区 | 伊人亚洲 | 久久精品欧美日韩精品 | 国产性受xxxx黑人xyx性爽 | 国产狂喷潮在线观看 | 亚洲成人播放 | 欧美日韩在线视频一区 | 国产精品成人久久久久久久 | 欧美在线播放一区二区 | 亚洲国产福利一区二区三区 | 色先锋av资源中文字幕 | av在线播放国产 | 国产成人亚洲综合色婷婷 | 寂寞人妻瑜伽被教练日 | 91亚洲精品在线观看 | а天堂8中文最新版在线官网 | 国产真实老熟女无套内射 | 人妻夜夜爽天天爽三区麻豆av网站 | 在线aaa| 亚洲色大成网站www永久一区 | 综合网国产 | 啦啦啦www播放日本观看 | 欧美女人天堂 | 另类亚洲激情 | 欧美肥婆姓交大片 | 亚洲国产精品成人无码区 | 97影视| 亚洲精品精品 | 欧洲妇女成人淫片aaa视频 | 欧日韩毛片 | 成人av社区 | 狠狠色狠狠色综合网 | 天天爽夜夜爽视频 | 少妇又紧又色又爽又刺激视频 | 99久久精| 中文字幕亚洲精品 | 依依成人精品视频在线观看 | 精品少妇无码av无码专区 | 欧美理论视频 | 美丽姑娘国语版在线播放 | 欧美乱大交xxxxx春色视频 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 五月天综合激情 | 韩国无码无遮挡在线观看 | 拍真实国产伦偷精品 | 人禽l交视频在线播放 视频 | 伊人久久大香线蕉亚洲五月天 | 欧美11p | 一本到在线视频 | 69久久久 | 9色在线视频 | 性欧美老人牲交xxxxx视频 | 亚洲成人在线免费观看 | 黄色一节片 | 国产无套粉嫩白浆内谢软件 | 少妇人妻在线视频 | 国产伦理片在线观看 | 色播在线 | 成人本色视频在线观看 | 成人在线免费看视频 | 色婷婷噜噜久久国产精品12p | 免费人成激情视频在线观看冫 | 九九伊在人线 | 女上男下激烈啪啪xx00免费 | 精品日韩久久 | 性――交――性――乱睡觉 | www.亚洲在线 | 又湿又紧又大又爽a视频 | 简单av网 | 中文高清av | 国产精品伦一区二区三级视频 | 欧美午夜理伦三级在线观看 | 粉嫩视频在线观看 | 深夜福利成人 | 韩国三级bd高清中字2021 | 无码人妻毛片丰满熟妇区毛片 | 中文字幕日韩精品无码内射 | 亚洲五月花 | 五月天久久久久 | 亚洲蜜桃精久天干天干天啪啪夜l | 久久久久中文字幕亚洲精品 | 成人国产免费视频 | 在教室伦流澡到高潮hnp视频 | 亚洲www啪成人一区二区 | 国产一区二区毛片 | 老司机午夜福利av无码特黄a | 久久久久国产精品嫩草影院 | 亚洲天堂久久 | 国产18页| 无码人妻精品一区二区三区在线 | 精品人人妻人人澡人人爽人人 | 久久精品国产免费 | 久久精品国产视频 | 婷婷六月综合 | 亚洲成av人片在线观看ww | 一级片免费网址 | 狠狠色综合网站久久久久久久高清 | 亚洲精品久久久打桩机小说 | 精品国产三级a∨在线观看 无码丰满熟妇 | 中文字幕精品亚洲无线码二区 | 国产亚洲自拍av | 成人免费ā片在线观看 | wwwww在线观看| 日韩成人高清视频 | 久久爱影视i | 国产一久久 | 天堂中文а√在线官网 | 一级黄色短视频 | 国产精品久久久久久婷婷 | 精品伦精品一区二区三区视频 | 激情综合区 | 亚洲自偷自拍熟女另类 | 久久婷婷五月综合色和啪 | 久久99热久久99精品 | 中文字幕av久久爽一区 | 日日拍拍| 国产精品第52页 | 日本三级韩国三级美三级91 | 午夜精品一二三区 | 日日躁狠狠躁aaaaxxxx | 亚洲成人在线网站 | 777爽死你无码免费看一二区 | 国产精品久久久久久久久免费 | 在线国产欧美 | 国产主播福利在线 | 国产精品人妻一码二码尿失禁 | 人体写真 福利视频 | 伊人www22综合色 | 深夜视频一区二区 | 国产av激情久久无码天堂 | 国产成人精品a视频 | av手机免费看 | 黄色成人毛片 | 51免费看成人啪啪片 | 高潮流白浆潮喷在线播放视频 | 久久久久久一区二区 | 久久理论视频 | 亚洲精品无码久久久影院相关影片 | 欧美性生交xxxxxdddd | 日本三级毛片 | 在线免费av播放 | www.av在线播放| 欧美亚洲另类小说 | 国产男人搡女人免费视频 | 日本熟妇毛耸耸xxxxxx | 久久精品亚洲中文无东京热 | 国产精品乱码一区 | 好吊妞国产欧美日韩免费观看网站 | 亚洲国产成人一区二区在线 | 高潮久久久 | 成 人 黄 色 视频播放165 | 亚洲激情欧美色图 | 欧美乱轮 | 你懂的在线观看网址 | 国产丰满大乳奶水 | 亚洲 欧美 日韩 综合 国产aⅴ | 免费观看午夜视频 | 欧美一级网址 | 欧美做爰xxxⅹ性欧美大片 | xxxx黄色| 大吊一区二区三区 | 久久99精品久久久久 | 无码专区一va亚洲v专区在线 | 国产精品美女一区二区 | 成人自拍视频在线 | 夜夜偷天天爽夜夜爱 | 精品中文字幕在线观看 | 国产色综合久久无码有码 | 加勒比精品 | 欧美xxxxx高潮喷水 | 亚洲区小说区图片区qvod | 亚洲精品蜜桃久久久久久 | 日本精品一区二区三区四区 | 精品乱码一区内射人妻无码 | 91在线超碰 | 日韩国产欧美一区 | 成人久久18免费网站麻豆 | а√ 天堂 在线官网 | 人人摸人人搞人人透 | 欧美成人乱码一二三四区免费 | 成人午夜免费毛片 | 乖女从小调教h尿便器小说 关秀媚三级 | www.欧美亚洲 | 五月色婷婷亚洲精品制服丝袜1区 | 日本不卡一区二区三区 | 精品久久精品 | 中文字幕日本免费毛片全过程 | 波多野结衣91 | 国产看黄网站又黄又爽又色 | 日本爽快片100色毛片 | 午夜视频在线看 | 极品美女白嫩呻吟湿淋淋照片 | 一道本在线伊人蕉无码 | 乱人伦精品视频在线观看 | 怡红院av人人爰人人爽 | 香蕉久草 | 国产做a爰片久久毛片a我的朋友 | 91蝌蚪| 少妇又紧又色又爽又刺激视频 | 日本在线观看一区 | 色综合欧美在线视频区 | 欧美性受xxxx狂喷水 | 国产午夜三级一二三区 | 久久精品美乳 | 国产成人a在线观看视频免费 | 亚洲国产亚洲 | 日本三级2018 | 在线a亚洲视频播放在线观看 | 亚洲人成图片小说网站 | 国产 国语对白 露脸 | 在线视频 中文字幕 | 最新在线黄色网址 | 在线免费精品 | 一本一本久久a久久精品综合麻豆 | 免费中文字幕在线观看 | 少妇午夜三级伦理影院播放器 | 久久久噜噜噜www成人网 | 中文字幕丰满乱子无码视频 | 苍井优三级在线观看 | 麻豆一区二区三区精品视频 | 99热在线只有精品 | 欧美午夜精品久久久久久孕妇 | 欧美成人精品一区 | 综合网在线 | 丰满熟女高潮毛茸茸欧洲 | 色免费看| 亚洲最大av资源站无码av网址 | 脱岳裙子从后面挺进去在线观看 | 一本大道久久a久久精二百 一本大道久久a久久精品综合1 | 亚洲国精产品一二二线 | 亚洲男人第一无码av网站 | 国产又粗又深又猛又爽又在线观看 | 亚洲国产理论片在线播放 | 久久久精品人妻一区二区三区四 | 久久精品国产99久久6动漫亮点 | 久久久香蕉 | 69日影院| 欧美日在线 | 国产成人三级在线观看 | 日韩在线网址 | 国内毛片毛片毛片毛片毛片 | 女女百合av大片一区二区三区九县 | 色播亚洲 | 国产精品成人免费一区二区视频 | 草草网站影院白丝内射 | 欧美精品一区二区三区四区在线 | 一区二区三区在线免费 | 欧美日本91精品久久久久 | 国产亚洲欧美日韩精品一区二区三区 | 黑人狂躁中国少妇and | 一级久久久久 | 日本人乱人乱亲乱色视频观看 | 国产女主播视频一区二区三区 | 国产精品一区三区 | 日韩视频网站在线观看 | 精品二区视频 | 深夜福利视频网站 | a∨色狠狠一区二区三区 | 色呦呦免费观看 | 人人做人人爽人人爱 | 高h肉辣民工文 | 特级淫片aaaaaaa级附近的 | 国产寡妇xxxxxxxx性开放 | 美女131爽爽爽| 91成人在线观看喷潮蘑菇 | 国产午夜啪啪 | 色噜噜狠狠狠狠色综合久 | 奶波霸巨乳一二三区乳 | 黑人大战欲求不满人妻 | 九九九九热精品免费视频点播观看 | 永久天堂网 av手机版 | 亚洲精品成人无限看 | 成人免费午夜视频69影院 | 中文无码一区二区不卡av | 网红主播大秀福利视频日韩精品 | 亚洲色图 校园春色 | 人人妻人人澡人人爽欧美一区双 | 免费国产成人 | 成人国产精品免费观看 | 综合视频 | 人妖性生活视频 | 久久国产欧美日韩 | 久久久亚洲国产天美传媒修理工 | 永久免费的啪啪网站免费观看 | 国产无区一区二区三麻豆 | 牛牛影视一区二区三区免费看 | 99久久人妻无码精品系列蜜桃 | 丰满岳妇伦在线播放 | 国产小视频在线观看免费 | 久久国产二区 | 欧美髙清性xxxxhdvid | 夜夜高潮夜夜爽精品视频 | 精品久久国产字幕高潮 | 性啪啪chinese东北女人 | 欧美日韩一区二区精品 | 99九九视频| 久久6精品 | 国产精品亚洲精品日韩已满 | 亚洲图片在线观看 | 国内揄拍国内精品少妇 | 人妻少妇被粗大爽.9797pw | 黄色录像大片 | 成年女人免费视频播放体验区 | 久久国产精品波多野结衣av | 91精品在线国产 | 欧美性免费| aaaa大片少妇高潮免费看 | 在线99热| 在线观看老湿视频福利 | 国产伦精品一区二区三区在线观看 | 少妇私密会所按摩到高潮呻吟 | 香蕉视频久久 | 亚洲精品合集 | 国产精品欧美一区二区三区奶水 | 97无码免费人妻超级碰碰碰碰 | 八戒八戒在线www视频中文 | 国产口爆吞精在线视频 | 青青视频网站 | av在线资源站 | 免费精品视频在线观看 | 在线a视频 | 午夜三级在线观看 | 五月天婷婷网站 | 色婷婷蜜桃| 精品国产一区二区三区久久久蜜月 | 成人毛片网 | 性猛交娇小69hd | www色婷婷com| 国内激情 |