日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

23 個超實用 JS 技巧

帶有多個條件的 if 語句

把多個值放在一個數(shù)組中,然后調(diào)用數(shù)組的 includes 方法。

// bad
if (x === "abc" || x === "def" || x === "ghi" || x === "jkl") {
//logic
}
// better
if (["abc", "def", "ghi", "jkl"].includes(x)) {
//logic
}

使用條件表達式簡化 if true...else

// bad
let test: boolean;
if (x > 100) {
test = true;
} else {
test = false;
}
// better
let test = x > 10 ? true : false;
//或者這樣
let test = x > 10;
console.log(test);

假值(undefined、null、0、false、NaN、空字符串)檢查

當我們創(chuàng)建了新變量,有時候想要檢查引用的變量是不是null 或 undefined空字符串 等假值。JAVAScript 確實有一個很好的快捷方式來實現(xiàn)這種檢查-邏輯或操作符(||)

||會在左側(cè)操作數(shù)為假值時返回右側(cè)操作數(shù)

只有當左側(cè)為:

  • 空字符串: ''或``
  • NaN
  • 0
  • null
  • undefined
  • false

邏輯或操作符(||) 會返回有右側(cè)的值

// bad
if (test1 !== null || test1 !== undefined || test1 !== "") {
let test2 = test1;
}
// better
let test2 = test1 || "";
// bad
if (test1 === true) or if (test1 !== "") or if (test1 !== null)
// better
if (test1){
// do some
}else{
// do other
}

注意:如果 test1 有值,將執(zhí)行 if 之后的邏輯,這個操作符主要用于 null,undefinded,空字符串 檢查。

使用空值合并操作符-??

只有當左側(cè)為

  • null
  • undefined

空值合并操作符(??) 會返回右側(cè)的值

const baz = 0 ?? 42;
console.log(baz);
// expected output: 0

注意:與邏輯或操作符(||)不同,||會在左側(cè)操作數(shù)為假值時返回右側(cè)操作數(shù)

只有當左側(cè)為:

  • 空字符串: ''或``
  • NaN
  • 0
  • null
  • undefined

邏輯或操作符(||) 會返回有右側(cè)的值

var a = "" || 1;
// 輸出 1
console.log(a);

null 檢查和默認賦值

let test1 = null;
let test2 = test1 ?? "";
console.log("null check", test2); // 輸出空字符串 ""

undefined 檢查和默認賦值

const test = undefined ?? "default";
console.log(test);
// expected output: "default"

比較后返回

// bad
let test;
function checkReturn() {
if (!(test === undefined)) {
return test;
} else {
return callMe("test");
}
}
// better
function checkReturn() {
return test ?? callMe("test");
}

使用可選鏈操作符-?.

?. 也叫鏈判斷運算符。它允許開發(fā)人員讀取深度嵌套在對象鏈中的屬性值,而不必驗證每個引用。當引用為空時,表達式停止計算并返回 undefined

const travelPlans = {
destination: "DC",
monday: {
location: "National Mall",
budget: 200,
},
};
// bad
const res =
travelPlans &&
travelPlans.tuesday &&

travelPlans.tuesday.location &&

travelPlans.tuesday.location.href;
// better
// 輸出 undefined
const res1 = travelPlans?.tuesday?.location?.href;

用于多個條件判斷的 && 操作符

如果只在變量為 true 時才調(diào)用函數(shù),可以使用 && 操作符。

// bad
if (test1) {
callMethod();
}
// better
test1 && callMethod();

當你在 React 中想要有條件地渲染某個組件時,這個與 (&&)短路寫法比較有用。例如:

<div> {this.state.isLoading && <Loading />} </div>

switch 簡化

我們可以將條件保存在鍵值對象中,并根據(jù)條件來調(diào)用它們。

// bad
switch (data) {
case 1:
test1();
break;
case 2:
test2();
break;
case 3:
test();
break;
// And so on...
}
// better
var data = {
1: test1,
2: test2,
3: test,
};
// 如果type 在 data中存在, 則執(zhí)行對應的函數(shù)
data[type] && data[type]();

默認參數(shù)值

// bad
function add(test1, test2) {
if (test1 === undefined) test1 = 1;
if (test2 === undefined) test2 = 2;
return test1 + test2;
}
// better
add = (test1 = 1, test2 = 2) => test1 + test2;
add(); //output: 3

條件查找簡化

如果我們要基于不同的類型調(diào)用不同的方法,可以使用多個 else if 語句或 switch,但有沒有比這更好的簡化技巧呢?其實是前面的 switch 簡化方式一樣!

// bad
if (type === "test1") {
test1();
} else if (type === "test2") {
test2();
} else if (type === "test3") {
test3();
} else if (type === "test4") {
test4();
} else {
throw new Error("Invalid value " + type);
}
// better
var types = {
test1,
test2,
test3,
test4,
};
types[type] && types[type]();

對象屬性賦值

let test1 = "a";
let test2 = "b";
// bad
let obj = { test1: test1, test2: test2 };
// better
let obj = { test1, test2 };

解構(gòu)賦值

// bad
const test1 = this.data.test1;
const test2 = this.data.test2;
const test2 = this.data.test3;
// better
const { test1, test2, test3 } = this.data;

模板字符串

如果你厭倦了使用 + 將多個變量連接成一個字符串,那么這個簡化技巧將讓你不再頭痛。

// bad
const welcome = "Hi " + test1 + " " + test2 + ".";
// better
const welcome = `Hi ${test1} ${test2}`;

跨行字符串

// bad
const data =
"abc abc abc abc abc abcnt" + "test test,test test test testnt";
// better
const data = `abc abc abc abc abc abc
test test,test test test test`;

indexOf 的按位操作簡化

在查找數(shù)組的某個值時,我們可以使用 indexOf() 方法。但有一種更好的方法,讓我們來看一下這個例子。

// bad
if (arr.indexOf(item) > -1) {
// item found
}
if (arr.indexOf(item) === -1) {
// item not found
}
// better
if (~arr.indexOf(item)) {
// item found
}
if (!~arr.indexOf(item)) {
// item not found
}

按位 (~) 運算符將返回 true(-1 除外),反向操作只需要!~。另外,也可以使用 includes() 函數(shù)。

if (arr.includes(item)) {
// true if the item found
}

字符串轉(zhuǎn)成數(shù)字

有一些內(nèi)置的方法,例如 parseInt 和 parseFloat 可以用來將字符串轉(zhuǎn)為數(shù)字。我們還可以簡單地在字符串前提供一個一元運算符 (+) 來實現(xiàn)這一點。

// bad
let total = parseInt("453");
let average = parseFloat("42.6");
// better
let total = +"453";
let average = +"42.6";

順序執(zhí)行 promise

如果你有一堆異步或普通函數(shù)都返回 promise,要求你一個接一個地執(zhí)行,怎么辦?

async function getData() {
const promises = [fetch("url1"), fetch("url2"), fetch("url3"), fetch("url4")];
for (const item of promises) {
// 打印出promise
console.log(item);
}
// better
for await (const item of promises) {
// 打印出請求的結(jié)果
console.log(item);
}
}

等待所有 promise 完成

Promise.allSettled()方法接受一組 Promise 實例作為參數(shù),包裝成一個新的 Promise 實例。只有等到所有這些參數(shù)實例都返回結(jié)果,不管是 fulfilled 還是 rejected,包裝實例才會結(jié)束

有時候,我們不關(guān)心異步請求的結(jié)果,只關(guān)心所有的請求有沒有結(jié)束。這時,Promise.allSettled()方法就很有用

const promises = [fetch("index.html"), fetch("https://does-not-exist/")];
const results = await Promise.allSettled(promises);
// 過濾出成功的請求
const successfulPromises = results.filter((p) => p.status === "fulfilled");
// 過濾出失敗的請求,并輸出原因
const errors = results
.filter((p) => p.status === "rejected")
.map((p) => p.reason);

交換數(shù)組元素的位置

// bad
const swapWay = (arr, i, j) => {
const newArr = [...arr];
let temp = newArr[i];
newArr[i] = list[j];
newArr[j] = temp;
return newArr;
};

ES6 開始,從數(shù)組中的不同位置交換值變得容易多了

// better
const swapWay = (arr, i, j) => {
const newArr = [...arr];
const [newArr[j],newArr[i]] = [newArr[i],newArr[j]];
return newArr;
};

使用變量作為對象鍵

當你有一個字符串變量,并想將其用作對象中的鍵以設置一個值時可以用它

let property = "a";
const obj = {
b: "b",
};
property = "name";
obj[property] = "這是A";
// {b: "b", name: "這是A"}
console.log(obj);

帶有范圍的隨機數(shù)生成器

有時你需要生成隨機數(shù),但希望這些數(shù)字在一定范圍內(nèi),那就可以用這個工具。

function randomNumber(max = 1, min = 0) {
if (min >= max) {
return max;
}
return Math.floor(Math.random() * (max - min) + min);
}

生成隨機顏色

function getRandomColor() {
const colorAngle = Math.floor(Math.random() * 360);
return `hsla(${colorAngle},100%,50%,1)`;
}

獲取列表最后一項

其他語言里這個功能被做成了可以在數(shù)組上調(diào)用的方法或函數(shù),但在 JavaScript 里面,你得自己做點工作。

let array = [0, 1, 2, 3, 4, 5, 6, 7];
console.log(array.slice(-1)) >>> [7];
console.log(array.slice(-2)) >>> [6, 7];
console.log(array.slice(-3)) >>> [5, 6, 7];
function lastItem(list) {
if (Array.isArray(list)) {
return list.slice(-1)[0];
}
if (list instanceof Set) {
return Array.from(list).slice(-1)[0];
}
if (list instanceof Map) {
return Array.from(list.values()).slice(-1)[0];
}
}

圖片懶加載

在懶加載的實現(xiàn)中,有兩個關(guān)鍵的數(shù)值:一個是當前可視區(qū)域的高度,另一個是元素距離可視區(qū)域頂部的高度。

當前可視區(qū)域的高度, 在和現(xiàn)代瀏覽器及 IE9 以上的瀏覽器中,可以用 window.innerHeight 屬性獲取。在低版本 IE 的標準模式中,可以用
document.documentElement.clientHeight 獲取,這里我們兼容兩種情況:

const viewHeight = window.innerHeight || document.documentElement.clientHeight;

而元素距離可視區(qū)域頂部的高度,我們這里選用 getBoundingClientRect() 方法來獲取返回元素的大小及其相對于視口的位置。對此 MDN 給出了非常清晰的解釋:

該方法的返回值是一個 DOMRect 對象,這個對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關(guān)的 css 邊框集合 。

DOMRect 對象包含了一組用于描述邊框的只讀屬性——left、top、right 和 bottom,單位為像素。除了 width 和 height 外的屬性都是相對于視口的左上角位置而言的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Lazy-Load</title>
<style>
.img {
width: 200px;
height: 200px;
background-color: gray;
}
.pic {
// 必要的img樣式
}
</style>
</head>
<body>
<div class="container">
<div class="img">
// 注意我們并沒有為它引入真實的src
<img class="pic" alt="加載中" data-src="./images/1.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/2.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/3.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/4.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/5.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/6.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/7.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/8.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/9.png" />
</div>
<div class="img">
<img class="pic" alt="加載中" data-src="./images/10.png" />
</div>
</div>
</body>
</html>
<script>
// 獲取所有的圖片標簽
const imgs =
document.getElementsByTagName('img')
// 獲取可視區(qū)域的高度
const viewHeight = window.innerHeight ||
document.documentElement.clientHeight
// num用于統(tǒng)計當前顯示到了哪一張圖片,避免每次都從第一張圖片開始檢查是否露出
let num = 0
function lazyload(){
for(let i=num; i<imgs.length; i++) {
// 用可視區(qū)域高度減去元素頂部距離可視區(qū)域頂部的高度
let distance = viewHeight - imgs[i].getBoundingClientRect().top
// 如果可視區(qū)域高度大于等于元素頂部距離可視區(qū)域頂部的高度,說明元素露出
if(distance >= 0 ){
// 給元素寫入真實的src,展示圖片
imgs[i].src = imgs[i].getAttribute('data-src')
// 前i張圖片已經(jīng)加載完畢,下次從第i+1張開始檢查是否露出
num = i + 1
}
}
}
// 監(jiān)聽Scroll事件
window.addEventListener('scroll', lazyload, false);
</script>

圖片預加載

class PreLoadImage {
constructor(imgNode) {
// 獲取真實的DOM節(jié)點
this.imgNode = imgNode;
}
// 操作img節(jié)點的src屬性
setSrc(imgUrl) {
this.imgNode.src = imgUrl;
}
}
class ProxyImage {
// 占位圖的url地址
static LOADING_URL = "xxxxxx";
constructor(targetImage) {
// 目標Image,即PreLoadImage實例
this.targetImage = targetImage;
}
// 該方法主要操作虛擬Image,完成加載
setSrc(targetUrl) {
// 真實img節(jié)點初始化時展示的是一個占位圖
this.targetImage.setSrc(ProxyImage.LOADING_URL);
// 創(chuàng)建一個幫我們加載圖片的虛擬Image實例
const virtualImage = new Image();
// 監(jiān)聽目標圖片加載的情況,完成時再將DOM上的真實img節(jié)點的src屬性設置為目標圖片的url
virtualImage.onload = () => {
this.targetImage.setSrc(targetUrl);
};
// 設置src屬性,虛擬Image實例開始加載圖片
virtualImage.src = targetUrl;
}
}

ProxyImage 幫我們調(diào)度了預加載相關(guān)的工作,我們可以通過 ProxyImage 這個代理,實現(xiàn)對真實 img 節(jié)點的間接訪問,并得到我們想要的效果。

https://www.ixiera.com

分享到:
標簽:JS
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定