偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

九個(gè)超級(jí)有用的 Javascript 技巧

開(kāi)發(fā) 前端
在實(shí)際的開(kāi)發(fā)工作過(guò)程中,我積累了一些常用的、超級(jí)有用的Javascript技巧和代碼片段,包括其他大神編譯的JS使用技巧。

前言

在實(shí)際的開(kāi)發(fā)工作過(guò)程中,我積累了一些常用的、超級(jí)有用的Javascript技巧和代碼片段,包括其他大神編譯的JS使用技巧。

今天這篇文章,我認(rèn)真篩選了9個(gè)我認(rèn)為比較實(shí)用的技巧跟大家一起來(lái)分享,也歡迎你在留言區(qū)給我們留言,把你認(rèn)為一些重要而有用的技巧與大家分享一下。

1.動(dòng)態(tài)加載JS文件

在一些特殊的場(chǎng)景下,尤其是在一些庫(kù)和框架的開(kāi)發(fā)中,我們有時(shí)會(huì)動(dòng)態(tài)加載并執(zhí)行JS文件。

下面是使用Promise的簡(jiǎn)單封裝。

function loadJS(files, done) {
   // Get the head tag
   const head = document. getElementsByTagName('head')[0];
   Promise.all(files.map(file => {
     return new Promise(resolve => {
       // create script tag and add to head
       const s = document.createElement('script');
       s.type = "text/javascript";
       s.async = true;
       s.src = file;
       // Listen to the load event, resolve if the loading is complete
       s. addEventListener('load', (e) => resolve(), false);
       head.appendChild(s);
     });
   })).then(done); // everything is done, execute the user's callback event
}
loadJS(["test1.js", "test2.js"], () => {
   // user's callback logic
});There are two core points in the code above. One is to use Promise to process asynchronous logic, but to use script tags to load and execute js.

2. 實(shí)現(xiàn)模板引擎

以下示例使用很少的代碼來(lái)實(shí)現(xiàn)動(dòng)態(tài)模板渲染引擎。它不僅支持普通動(dòng)態(tài)變量的替換,還支持動(dòng)態(tài)JS語(yǔ)法邏輯包括for循環(huán)、if判斷等。

// This is a dynamic template that contains js code
var template =
'My avorite sports:' +
'<%if(this.showSports) {%>' +
     '<% for(var index in this.sports) { %>' +
     '<a><%this.sports[index]%></a>' +
     '<%}%>' +
'<%} else {%>' +
     '<p>none</p>' +
'<%}%>';
// This is the function string we're going to concatenate
const code = `with(obj) {
   var r=[];
   r.push("My avorite sports:");
   if(this. showSports) {
     for(var index in this. sports) {
       r. push("<a>");
       r.push(this.sports[index]);
       r. push("</a>");
     }
   } else {
     r.push("<span>none</span>");
   }
   return r.join("");
}`
// dynamically rendered data
const options = {
   sports: ["swimming", "basketball", "football"],
   showSports: true
}
// Build a feasible function and pass in parameters to change the direction of this when the function is executed
result = new Function("obj", code).apply(options, [options]);
console. log(result);

3.使用reduce轉(zhuǎn)換數(shù)據(jù)結(jié)構(gòu)

有時(shí)候前端需要對(duì)后端傳來(lái)的數(shù)據(jù)進(jìn)行轉(zhuǎn)換以適應(yīng)前端的業(yè)務(wù)邏輯,或者轉(zhuǎn)換組件的數(shù)據(jù)格式然后傳給后端處理,而reduce就是 一個(gè)非常強(qiáng)大的工具。

const arr = [
    { classId: "1", name: "Jack", age: 16 },
    { classId: "1", name: "Jon", age: 15 },
    { classId: "2", name: "Jenny", age: 16 },
    { classId: "3", name: "Jim", age: 15 },
    { classId: "2", name: "Zoe", age: 16 }
];
groupArrayByKey(arr, "classId");
function groupArrayByKey(arr = [], key) {
    return arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {})
}

很多復(fù)雜的邏輯如果通過(guò)reduce處理的話,就非常簡(jiǎn)單了。

4.添加默認(rèn)值

有時(shí),方法需要用戶(hù)傳入?yún)?shù)。通常,我們有兩種方法來(lái)處理。如果用戶(hù)不傳入,我們通常會(huì)給出一個(gè)默認(rèn)值,或者用戶(hù)必須傳入一個(gè)參數(shù),不傳則拋出錯(cuò)誤。

function double() {
     return value *2
}
// If not passed, give a default value of 0
function double(value = 0) {
     return value * 2
}
// The user must pass a parameter, and an error will be thrown if no parameter is passed
const required = () => {
     throw new Error("This function requires one parameter.")
}
function double(value = required()) {
     return value * 2
}
double(3) // 6
double() // throw Error

Listen方法用于創(chuàng)建NodeJS原生http服務(wù)并監(jiān)聽(tīng)端口,在服務(wù)的回調(diào)函數(shù)中創(chuàng)建上下文,然后調(diào)用用戶(hù)注冊(cè)的回調(diào)函數(shù)并傳遞生成的上下文。我們先看一下之前createContext和handleRequest的實(shí)現(xiàn)。

5.該函數(shù)只執(zhí)行一次

在某些情況下,我們有一些特殊的場(chǎng)景,某個(gè)函數(shù)只允許執(zhí)行一次,或者某個(gè)綁定方法只允許執(zhí)行一次。

export function once (fn) {
   // Use the closure to determine whether the function has been executed
   let called = false
   return function () {
     if (! called) {
       called = true
       fn. apply(this, arguments)
     }
   }
}

6. 實(shí)現(xiàn)Curry

JavaScript 中的柯里化是將采用多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換為一系列僅采用一個(gè)參數(shù)的函數(shù)的過(guò)程。這樣可以更靈活地使用函數(shù),減少代碼的重復(fù),提高代碼的可讀性。

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}
function add(x, y) {
  return x + y;
}
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)); // output 3
console.log(curriedAdd(1, 2)); // output 3

通過(guò)柯里化,我們可以將一些常用的功能模塊化,比如驗(yàn)證、緩存等。 這提高了代碼的可維護(hù)性和可讀性,并減少了出錯(cuò)的機(jī)會(huì)。

7. 實(shí)現(xiàn)單例模式

JavaScript的單例模式是一種常用的設(shè)計(jì)模式。它可以確保一個(gè)類(lèi)只有一個(gè)實(shí)例,并提供對(duì)該實(shí)例的全局訪問(wèn)點(diǎn)。它在JS中有廣泛的應(yīng)用場(chǎng)景,比如購(gòu)物車(chē)、緩存對(duì)象、全局狀態(tài)管理等等。

let cache;
class A {
  // ...
}
function getInstance() {
  if (cache) return cache;
  return cache = new A();
}
const x = getInstance();
const y = getInstance();
console.log(x === y); // true

8. 實(shí)現(xiàn)CommonJs規(guī)范

CommonJS規(guī)范的核心思想是將每個(gè)文件視為一個(gè)模塊,每個(gè)模塊都有自己的作用域,其中的變量、函數(shù)和對(duì)象都是私有的,外部無(wú)法訪問(wèn)。要訪問(wèn)模塊中的數(shù)據(jù),您必須導(dǎo)出并要求。

// id: full file name
const path = require('path');
const fs = require('fs');
function Module(id){
     // Used to uniquely identify the module
     this.id = id;
     // Properties and methods used to export modules
     this.exports = {};
}
function myRequire(filePath) {
     // Directly call the static method of Module to load the file
     return Module._load(filePath);
}
Module._cache = {};
Module._load = function(filePath) {
     // First address the absolute path of the file through the filePath passed in by the user
     // Because in CommnJS, the unique identifier of the module is the absolute path of the file
     const realPath = Module._resoleveFilename(filePath);
     // Cache priority, if it exists in the cache, it will directly return the exports property of the module
     let cacheModule = Module._cache[realPath];
     if(cacheModule) return cacheModule. exports;
     // If it is loaded for the first time, a new module is required, and the parameter is the absolute path of the file
     let module = new Module(realPath);
     // Call the load method of the module to compile the module
     module.load(realPath);
     return module. exports;
}
// The node file is not discussed yet
Module._extensions = {
    // Process the js file
   ".js": handleJS,
   // process the json file
   ".json": handleJSON
}
function handleJSON(module) {
  // If it is a json file, read it directly with fs.readFileSync,
  // Then use JSON.parse to convert and return directly
   const json = fs.readFileSync(module.id, 'utf-8')
   module.exports = JSON.parse(json)
}
function handleJS(module) {
   const js = fs. readFileSync(module. id, 'utf-8')
   let fn = new Function('exports', 'myRequire', 'module', '__filename', '__dirname', js)
   let exports = module. exports;
   // The assembled function can be executed directly
   fn.call(exports, exports, myRequire, module, module.id, path.dirname(module.id))
}
Module._resolveFilename = function (filePath) {
   // Splice the absolute path, and then search it, if it exists, it will return
   let absPath = path. resolve(__dirname, filePath);
   let exists = fs.existsSync(absPath);
   if (exists) return absPath;
   // If it does not exist, try splicing .js, .json, .node in sequence
   let keys = Object.keys(Module._extensions);
   for (let i = 0; i < keys. length; i++) {
     let currentPath = absPath + keys[i];
     if (fs.existsSync(currentPath)) return currentPath;
   }
};
Module.prototype.load = function(realPath) {
   // Get the file extension and hand it over to the corresponding method for processing
   let extname = path.extname(realPath)
   Module._extensions[extname](this)
}

以上是CommonJs規(guī)范的簡(jiǎn)單實(shí)現(xiàn)。核心解決了作用域的隔離,提供了Myrequire方法來(lái)加載方法和屬性。

9. 遞歸獲取對(duì)象屬性

如果讓我選擇使用最廣泛的設(shè)計(jì)模式,我會(huì)選擇觀察者模式。如果要選我遇到過(guò)最多的算法思維,那一定是遞歸。遞歸將原問(wèn)題劃分為具有相同結(jié)構(gòu)的結(jié)構(gòu)。子問(wèn)題,然后依次解決這些子問(wèn)題,并結(jié)合子問(wèn)題的結(jié)果,最終得到原問(wèn)題的答案。

const user = {
   info: {
     name: "Jacky",
     address: { home: "MLB", company: "AI" },
   },
};
// obj is the object to get the property, path is the path, and fallback is the default value
function get(obj, path, fallback) {
   const parts = path. split(".");
   const key = parts. shift();
   if (typeof obj[key] !== "undefined") {
     return parts. length > 0 ?
       get(obj[key], parts. join("."), fallback) :
       obj[key];
   }
   // return fallback if key not found
   return fallback;
}
console.log(get(user, "info.name")); // Jacky
console.log(get(user, "info.address.home")); // MLB
console.log(get(user, "info.address.company")); // AI
console.log(get(user, "info.address.abc", "fallback")); // fallback

總結(jié)

以上就是我今天為大家精選的全部?jī)?nèi)容,也是我認(rèn)為比較有用的9個(gè)JavaScript技巧,希望對(duì)大家有所幫助。

責(zé)任編輯:華軒 來(lái)源: web前端開(kāi)發(fā)
相關(guān)推薦

2023-07-18 07:56:31

工具reduce業(yè)務(wù)

2022-12-22 14:44:06

JavaScript技巧

2022-12-25 16:03:31

JavaScript技巧

2022-11-07 16:25:07

JavaScript技巧

2023-08-11 17:39:43

JavaScriptWeb 應(yīng)用程序

2022-12-19 15:23:51

JavaScrip開(kāi)發(fā)語(yǔ)言

2023-05-30 15:11:16

JavaScrip開(kāi)發(fā)功能

2023-08-18 15:12:00

JavaScript開(kāi)發(fā)

2020-06-21 13:57:21

JavaScript開(kāi)發(fā)代碼

2022-05-30 09:44:11

TypeScriptJavaScript技巧

2023-09-07 16:28:46

JavaScrip

2011-07-15 10:02:01

JavaScript

2024-08-20 15:23:27

JavaScript開(kāi)發(fā)

2023-05-28 23:23:44

2023-10-26 07:47:35

JavaScript代碼變量

2023-09-06 16:55:33

JavaScript閉包

2013-07-12 09:45:16

PHP功能

2023-05-18 15:32:02

HTML開(kāi)發(fā)技巧

2020-07-02 08:27:47

Javascript

2024-02-26 08:20:00

CSS開(kāi)發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)