千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:长沙千锋IT培训  >  技术干货  >  14个你必须知道的JavaScript函数

14个你必须知道的JavaScript函数

来源:千锋教育
发布人:qyf
时间: 2023-02-02 17:22:06

  1、确定任意对象的具体类型众所周知,JavaScript 中有六种原始数据类型(Boolean、Number、String、Null、Undefined、Symbol)和一个对象数据类型。但是你知道对象数据类型可以细分为很多种子类型吗?一个对象可能是数组、函数、map等,如果我们要获取对象的具体类型,应该怎么做呢?代码:

  function toRawType (value) {

  let _toString = Object.prototype.toString;

  let str = _toString.call(value)

  return str.slice(8, -1)

  }

  解释ECMAScript 有以下规则:

图片 1

  对于不同的对象,调用 Object.prototype.toString() 时会返回不同的结果。

图片 2

  而且,Object.prototype.toString() 的返回值总是‘[object’+‘tag’+‘]’的格式。如果我们只想要中间的标签,我们可以通过正则表达式或者String.prototype.slice()删除两边的字符。例子:

  toRawType(null)

  // "Null"

  toRawType(/sdfsd/)

  //"RegExp"

  2、缓存函数计算结果如果有这样的功能:

  function computed(str) {

  // Suppose the calculation in the funtion is very time consuming

  console.log('2000s have passed')

  return 'a result'

  }

  我们要缓存函数操作的结果, 稍后调用时,如果参数相同,则不再执行该函数,而是直接返回缓存中的结果。我们能做什么?代码:

  function cached(fn){

  // Create an object to store the results returned after each function execution.

  const cache = Object.create(null);

  // Returns the wrapped function

  return function cachedFn (str) {

  // If the cache is not hit, the function will be executed

  if ( !cache[str] ) {

  let result = fn(str);

  // Store the result of the function execution in the cache

  cache[str] = result;

  }

  return cache[str]

  }

  }

  例子:

图片 3

  3、实现Array.prototype.map这是 JavaScript 中一个有用的内置方法,你应该能够自己实现此功能。代码:

  const selfMap = function (fn, context) {

  let arr = Array.prototype.slice.call(this)

  let mappedArr = Array()

  for (let i = 0; i < arr.length; i++) {

  if (!arr.hasOwnProperty(i)) continue;

  mappedArr[i] = fn.call(context, arr[i], i, this)

  }

  return mappedArr

  }

  Array.prototype.selfMap = selfMap;

  例子:

图片 4

  4、实现Array.prototype.filter这是 JavaScript 中一个有用的内置方法,你应该能够自己实现此功能。代码:

  const selfFilter = function (fn, context) {

  let arr = Array.prototype.slice.call(this)

  let filteredArr = []

  for (let i = 0; i < arr.length; i++) {

  if(!arr.hasOwnProperty(i)) continue;

  fn.call(context, arr[i], i, this) && filteredArr.push(arr[i])

  }

  return filteredArr

  }

  Array.prototype.selfFilter = selfFilter;

  例子:

图片 5

  5、实现 Array.prototype.some这是 JavaScript 中一个有用的内置方法,你应该能够自己实现此功能。代码:

  const selfSome = function (fn, context) {

  let arr = Array.prototype.slice.call(this)

  if(!arr.length) return false

  for (let i = 0; i < arr.length; i++) {

  if(!arr.hasOwnProperty(i)) continue;

  let res = fn.call(context,arr[i],i,this)

  if(res)return true

  }

  return false

  }

  Array.prototype.selfSome = selfSome;

  例子:

图片 6

  6、实现 Array.prototype.reduce这是 JavaScript 中一个有用的内置方法,你应该能够自己实现此功能。代码:

  const selfReduce = function (fn, initialValue) {

  let arr = Array.prototype.slice.call(this)

  let res

  let startIndex

  if (initialValue === undefined) {

  for (let i = 0; i < arr.length; i++) {

  if (!arr.hasOwnProperty(i)) continue

  startIndex = i

  res = arr[i]

  break

  }

  } else {

  res = initialValue

  }

  for (let i = ++startIndex || 0; i < arr.length; i++) {

  if (!arr.hasOwnProperty(i)) continue

  res = fn.call(null, res, arr[i], i, this)

  }

  return res

  }

  Array.prototype.selfReduce = selfReduce;

  例子:

图片 7

  7、实现 Array.prototype.flat代码:

  const selfFlat = function (depth = 1) {

  let arr = Array.prototype.slice.call(this)

  if (depth === 0) return arr

  return arr.reduce((pre, cur) => {

  if (Array.isArray(cur)) {

  return [...pre, ...selfFlat.call(cur, depth - 1)]

  } else {

  return [...pre, cur]

  }

  }, [])

  }

  Array.prototype.selfFlat = selfFlat;

  例子:

图片 8

  8、柯里化柯里化是一种将具有多个参数的函数评估为具有单个参数的函数序列的技术。换句话说,当一个函数不是一次接受所有参数时,而是接受第一个参数并返回一个新函数,该函数接受第二个参数并返回一个新函数,该函数接受第三个参数,依此类推,直到所有参数都已履行。那就是我们将函数调用 add(1,2,3) 转换为 add(1)(2)(3) 。通过使用这种技术,可以轻松地配置和重用小块。为什么有用?

  · 柯里化可以帮助您避免一次又一次地传递相同的变量。

  · 它有助于创建高阶函数,它对事件处理非常有帮助。

  · 小部件可以轻松配置和重用。

  让我们看一个简单的添加函数。它接受三个操作数作为参数,并返回所有三个操作数的总和作为结果。

  function add(a,b,c){

  return a + b + c;

  }

  你可以用太少(结果奇怪)或太多(多余的参数被忽略)来调用它。

  add(1,2,3) --> 6

  add(1,2) --> NaN

  add(1,2,3,4) --> 6 //Extra parameters will be ignored.

  如何将现有函数转换为 curried 版本?代码:

  function curry(fn) {

  if (fn.length <= 1) return fn;

  const generator = (...args) => {

  if (fn.length === args.length) {

  return fn(...args)

  } else {

  return (...args2) => {

  return generator(...args, ...args2)

  }

  }

  }

  return generator

  }

  例子:

图片 9

  9、去抖动去抖动只不过是减少不必要的耗时计算,以提高浏览器性能。在某些情况下,某些功能需要更多时间来执行某个操作。例如,以电子商务网站上的搜索栏为例。假设用户想要获得“Tutorix 学习套件”。他在搜索栏中键入产品的每个字符。输入每个字符后,从浏览器到服务器都会进行一次 Api 调用,以获取所需的产品。由于他想要“Tutorix 学习套件”,用户必须从浏览器到服务器进行 17 次 Api 调用。想象一个场景,当数百万人进行相同的搜索从而调用数十亿个 Api 时。所以一次调用数十亿个 Api 肯定会导致浏览器性能变慢。为了减少这个缺点,去抖动出现了。在这种情况下,去抖动将在两次击键之间设置一个时间间隔,假设为 2 秒。如果两次击键之间的时间超过 2 秒,则只会进行 Api 调用。在这 2 秒内,用户可以输入至少一些字符,从而减少 Api 调用的这些字符。由于 Api 调用减少,浏览器性能将提高。必须注意,每次击键都会更新 Debouncing 功能。代码:

  const debounce = (func, time = 17, options = {

  leading: true,

  context: null

  }) => {

  let timer;

  const _debounce = function (...args) {

  if (timer) {

  clearTimeout(timer)

  }

  if (options.leading && !timer) {

  timer = setTimeout(null, time)

  func.apply(options.context, args)

  }else{

  timer = setTimeout(() => {

  func.apply(options.context, args)

  timer = null

  }, time)

  }

  };

  _debounce.cancel = function () {

  clearTimeout(timer)

  timer = null

  };

  return _debounce

  };

  10、 节流节流将以这样一种方式更改函数,即它可以在一个时间间隔内最多触发一次。例如,无论用户单击按钮多少次,限制将在 1000 毫秒内仅执行一次该功能。

图片 10

  代码:

  const throttle = (func, time = 17, options = {

  leading: true,

  trailing: false,

  context: null

  }) => {

  let previous = new Date(0).getTime()

  let timer;

  const _throttle = function (...args) {

  let now = new Date().getTime();

  if (!options.leading) {

  if (timer) return

  timer = setTimeout(() => {

  timer = null

  func.apply(options.context, args)

  }, time)

  } else if (now - previous > time) {

  func.apply(options.context, args)

  previous = now

  } else if (options.trailing) {

  clearTimeout(timer)

  timer = setTimeout(() => {

  func.apply(options.context, args)

  }, time)

  }

  };

  _throttle.cancel = () => {

  previous = 0;

  clearTimeout(timer);

  timer = null

  };

  return _throttle

  };

  11、 延迟加载图片延迟加载图片意味着在网站上异步加载图片——也就是说,在首屏内容完全加载之后,甚至有条件地,只有当它们出现在浏览器的视口中时。这意味着如果用户不一直向下滚动,则放置在页面底部的图像甚至不会被加载。代码:

  // getBoundingClientRect

  let imgList1 = [...document.querySelectorAll(".get_bounding_rect")]

  let num = imgList1.length

  let lazyLoad1 = (function () {

  let count = 0

  return function () {

  let deleteIndexList = []

  imgList1.forEach((img,index) => {

  let rect = img.getBoundingClientRect()

  if (rect.top < window.innerHeight) {

  img.src = img.dataset.src

  // Add picture to delete list after loading successfully

  deleteIndexList.push(index)

  count++

  if (count === num) {

  //When all pictures are loaded, unbind scroll event

  document.removeEventListener('scroll',lazyLoad1)

  }

  }

  })

  // Delete loaded pictures

  imgList1 = imgList1.filter((_,index)=>!deleteIndexList.includes(index))

  }

  })()

  12、数组随机无序我们经常需要打乱一个数组。代码:

  // Randomly select one of all elements after the current element to exchange with the current element

  function shuffle(arr) {

  for (let i = 0; i < arr.length; i++) {

  let randomIndex = i + Math.floor(Math.random() * (arr.length - i));

  [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]]

  }

  return arr

  }

  // Generate a new array, randomly take an element from the original array and put it into the new array

  function shuffle2(arr) {

  let _arr = []

  while (arr.length) {

  let randomIndex = Math.floor(Math.random() * (arr.length))

  _arr.push(arr.splice(randomIndex, 1)[0])

  }

  return _arr

  }

  例子:

图片 11

  13、单例模式单例模式将特定对象的实例数限制为一个,这个单一实例称为单例模式。单例在需要从单个中心位置协调系统范围的操作的情况下很有用。一个例子是数据库连接池。池管理整个应用程序的所有数据库连接的创建、销毁和生命周期,确保没有连接“丢失”。单例减少了对全局变量的需求,这在 JavaScript 中尤为重要,因为它限制了命名空间污染和相关的名称冲突风险。代码:

  function proxy(func) {

  let instance;

  let handler = {

  construct(target, args) {

  if (!instance) {

  // Create an instance if there is not exist

  instance = Reflect.construct(func,args)

  }

  return instance

  }

  }

  return new Proxy(func, handler)

  }

  // example

  function Person(name, age) {

  this.name = name

  this.age = age

  }

  const SingletonPerson = proxy(Person)

  let person1 = new SingletonPerson('zhl', 22)

  let person2 = new SingletonPerson('cyw', 22)

  console.log(person1 === person2) // true

  例子:

图片 12

  14、实现 JSON.stringify这是 JavaScript 中一个有用的内置方法,你应该能够自己实现此功能。代码:

  const isString = value => typeof value === 'string';

  const isSymbol = value => typeof value === 'symbol'

  const isUndefined = value => typeof value === 'undefined'

  const isDate = obj => Object.prototype.toString.call(obj) === '[object Date]'

  const isFunction = obj => Object.prototype.toString.call(obj) === '[object Function]';

  const isComplexDataType = value => (typeof value === 'object' || typeof value === 'function') && value !== null;

  const isValidBasicDataType = value => value !== undefined && !isSymbol(value);

  const isValidObj = obj => Array.isArray(obj) || Object.prototype.toString.call(obj) === '[object Object]';

  const isInfinity = value => value === Infinity || value === -Infinity

  // Symbol,undefined,function in array will become null

  // Infinity,NaN will also become null

  const processSpecialValueInArray = value =>

  isSymbol(value) || isFunction(value) || isUndefined(value) || isInfinity(value) || isNaN(value) ? null : value;

  // Handling property values according to JSON specification

  const processValue = value => {

  if (isInfinity(value) || isNaN(value)) {

  return null

  }

  if (isString(value)) {

  return `"${value}"`

  }

  return value

  };

  // obj.loop = obj

  const jsonStringify = (function () {

  // Closure + WeakMap prevent circular references

  let wp = new WeakMap();

  //It is the function in the closure that recursively calls jsonstrify, not the jsonstrify function declared by const

  return function jsonStringify(obj) {

  if (wp.get(obj)) throw new TypeError('Converting circular structure to JSON');

  let res = "";

  if (isComplexDataType(obj)) {

  if (obj.toJSON) return obj.toJSON;

  if (!isValidObj(obj)) {

  return

  }

  wp.set(obj, obj);

  if (Array.isArray(obj)) {

  res += "[";

  let temp = [];

  obj.forEach((value) => {

  temp.push(

  isComplexDataType(value) && !isFunction(value) ?

  jsonStringify(value) :

  `${processSpecialValueInArray(value, true)}`

  )

  });

  res += `${temp.join(',')}]`

  } else {

  res += "{";

  let temp = [];

  Object.keys(obj).forEach((key) => {

  if (isComplexDataType(obj[key])) {

  if (isValidObj(obj[key])) {

  temp.push(`"${key}":${jsonStringify(obj[key])}`)

  } else if (isDate(obj[key])) {

  temp.push(`"${key}":"${obj[key].toISOString()}"`)

  } else if (!isFunction(obj[key])) {

  temp.push(`"${key}":{}`)

  }

  } else if (isValidBasicDataType(obj[key])) {

  temp.push(`"${key}":${processValue(obj[key])}`)

  }

  });

  res += `${temp.join(',')}}`

  }

  } else if (isSymbol(obj)) {

  return

  } else {

  return obj

  }

  return res

  }

  })();

  // example

  let s = Symbol('s')

  let obj = {

  str: "123",

  arr: [1, {e: 1}, s, () => {

  }, undefined,Infinity,NaN],

  obj: {a: 1},

  Infinity: -Infinity,

  nan: NaN,

  undef: undefined,

  symbol: s,

  date: new Date(),

  reg: /123/g,

  func: () => {

  },

  dom: document.querySelector('body'),

  };

  console.log(jsonStringify(obj));

  console.log(JSON.stringify(obj));

  例子:

图片 13

  总结以上就是我与你分享的14个JavaScript的函数,这些函数也是我们作为一名web前端开发人员必须要知道的,希望对你有用,如果觉得对你有帮助的话,请记得点赞我,关注我,并将它分享给你身边做开发的朋友,也许能够帮助到他。

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

bootstrap是什么?有什么用处

2023-04-20

自旋锁原理是什么?自旋锁有什么优缺点

2023-03-17

Kafka的leader选举机制是什么

2023-03-03

最新文章NEW

多种java日志框架你真的了解吗

2023-03-17

如何查看git用户名和密码

2023-03-03

2分钟了解BFC

2023-02-06

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>