从Vue.js源码中我学到了尤大大几点精妙方法

话不多说,赶快试试尤大大教给我们的这几个精妙方法吧!在工作中肯定会用得到。

立即执行函数

页面加载完成后只执行一次的设置函数。

1(function (a, b) { 2  console.log(a, b); // 1,2 3})(1, 2); 4

通常,全局变量被作为一个参数传递给立即执行参数,这样它在函数内部不使用window也可以被访问到。

1(function (global) { 2  console.log(global); // Window对象 3})(this); 4

多层嵌套三目运算符

三目运算符嵌套的写法,使得代码可读性差,简单业务场景下可以试着使用。

1var a = 1; 2var b = 0; 3== 1 ? (== 2 ? (= 3) : (= 1)) : ""; 4console.log(b); // 1 5

冻结对象

不可对指定对象增删改。

1var emptyObject = Object.freeze({ 2  key: "1", 3}); 4emptyObject.name = "maomin"; 5delete emptyObject.key; 6emptyObject.key = "2"; 7console.log(emptyObject); 8

密封对象

只能对指定对象进行更改,不可进行增加删除操作。

1var sealObject = Object.seal({ 2  key: 3, 3}); 4sealObject.name = "maomin"; 5delete sealObject.key; 6sealObject.key = 4; 7console.log(sealObject); // 4 8

检查是否是原始值

1function isPrimitive(value) { 2  return ( 3    typeof value === "string" || 4    typeof value === "number" || 5    // $flow-disable-line 6    typeof value === "symbol" || 7    typeof value === "boolean" 8  ); 9} 10

快速检测是否是对象

当我们知道原始值时,它主要用于将对象与原始值区分开来。

1function isObject(obj) { 2  return obj !== null && typeof obj === "object"; 3} 4console.log(isObject(true)); //false 5

检测目标类型

1var _toString = Object.prototype.toString; 2 3function toRawType(value) { 4  return _toString.call(value).slice(8, -1); 5} 6console.log(toRawType([])); // Array 7

检查目标是否是有效的数组索引

1function isValidArrayIndex(val) { 2  var n = parseFloat(String(val)); 3  return n >= 0 && Math.floor(n) === n && isFinite(val); 4} 5

检测是否是Promise对象

1function isDef(v) { 2  return v !== undefined && v !== null; 3} 4function isPromise(val) { 5  return ( 6    isDef(val) && 7    typeof val.then === "function" && 8    typeof val.catch === "function" 9  ); 10} 11var promiseObj = new Promise(function (resolve, reject) { 12  // 一段耗时的异步操作 13  resolve("成功"); // 数据处理完成 14  // reject('失败') // 数据处理出错 15}).then( 16  (res) => { 17    console.log(res); 18  }, // 成功 19  (err) => { 20    console.log(err); 21  } // 失败 22); 23console.log(isPromise(promiseObj)); // true 24

目标转换为字符串

1var _toString = Object.prototype.toString; 2function isPlainObject(obj) { 3  return _toString.call(obj) === "[object Object]"; 4} 5function toString(val) { 6  return val == null 7    ? "" 8    : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString) 9    ? JSON.stringify(val, null, 2) 10    : String(val); 11} 12console.log(toString({ name: 1 })); // {"name": 1} 13

转化为数字

将输入值转换为数字以便持久化。如果转换失败,则返回原始字符串。

1function toNumber(val) { 2  var n = parseFloat(val); 3  return isNaN(n) ? val : n; 4} 5

检测key是否在创建的Map对象内

1function makeMap(str, expectsLowerCase) { 2  var map = Object.create(null); 3  var list = str.split(","); 4  for (var i = 0; i < list.length; i++) { 5    map[list[i]] = true; 6  } 7  return expectsLowerCase 8    ? function (val) { 9        return map[val.toLowerCase()]; 10      } 11    : function (val) { 12        return map[val]; 13      }; 14} 15var isBuiltInTag = makeMap("slot,component", true); 16console.log(isBuiltInTag("component")); // true 17

删除简单数组中某一项

1function remove(arr, item) { 2  if (arr.length) { 3    var index = arr.indexOf(item); 4    if (index > -1) { 5      return arr.splice(index, 1); 6    } 7  } 8} 9console.log(remove([1, 2], 1)); // [1] 10

检测对象中是否有指定key

1var hasOwnProperty = Object.prototype.hasOwnProperty; 2function hasOwn(obj, key) { 3  return hasOwnProperty.call(obj, key); 4} 5console.log(hasOwn({ name: 1 }, "name")); //true 6

将类数组对象转化为真实数组

1function toArray(list, start) { 2  start = start || 0; 3  var i = list.length - start; 4  var ret = new Array(i); 5  while (i--) { 6    ret[i] = list[+ start]; 7  } 8  return ret; 9} 10console.log(toArray({ 0: 42, 1: 52, 2: 63, length: 3 })); // [42, 52, 63] 11

将属性混合到目标对象中

1function extend(to, _from) { 2  for (var key in _from) { 3    to[key] = _from[key]; 4  } 5  return to; 6} 7console.log(extend({ name: 1 }, { name1: 2 })); // {name:1,name1:2} 8

将对象数组合并为单个对象

1function extend(to, _from) { 2  for (var key in _from) { 3    to[key] = _from[key]; 4  } 5  return to; 6} 7function toObject(arr) { 8  var res = {}; 9  for (var i = 0; i < arr.length; i++) { 10    if (arr[i]) { 11      extend(res, arr[i]); 12    } 13  } 14  return res; 15} 16console.log(toObject([{ name: 1 }, { name: 1 }, { name: 2 }, { name1: 3 }])); // {name: 2, name1: 3} 17

检测指定项在数组(简单数组、数组对象)中的索引

1function isObject(obj) { 2  return obj !== null && typeof obj === "object"; 3} 4function looseEqual(a, b) { 5  if (=== b) { 6    return true; 7  } 8  var isObjectA = isObject(a); 9  var isObjectB = isObject(b); 10  if (isObjectA && isObjectB) { 11    try { 12      var isArrayA = Array.isArray(a); 13      var isArrayB = Array.isArray(b); 14      if (isArrayA && isArrayB) { 15        return ( 16          a.length === b.length && 17          a.every(function (e, i) { 18            return looseEqual(e, b[i]); 19          }) 20        ); 21      } else if (instanceof Date && b instanceof Date) { 22        return a.getTime() === b.getTime(); 23      } else if (!isArrayA && !isArrayB) { 24        var keysA = Object.keys(a); 25        var keysB = Object.keys(b); 26        return ( 27          keysA.length === keysB.length && 28          keysA.every(function (key) { 29            return looseEqual(a[key], b[key]); 30          }) 31        ); 32      } else { 33        /* istanbul ignore next */ 34        return false; 35      } 36    } catch (e) { 37      /* istanbul ignore next */ 38      return false; 39    } 40  } else if (!isObjectA && !isObjectB) { 41    return String(a) === String(b); 42  } else { 43    return false; 44  } 45} 46 47function looseIndexOf(arr, val) { 48  for (var i = 0; i < arr.length; i++) { 49    if (looseEqual(arr[i], val)) { 50      return i; 51    } 52  } 53  return -1; 54} 55console.log(looseIndexOf([{ name: 1 }, { name: 2 }], 4)); // -1 56console.log(looseIndexOf([{ name: 1 }, { name: 2 }], { name: 1 })); // 0 57

确保函数只调用一次

1function once(fn) { 2  var called = false; 3  return function () { 4    if (!called) { 5      called = true; 6      fn.apply(this, arguments); 7    } 8  }; 9} 10var callOnce = once(function () { 11  console.log("javascript"); 12}); 13callOnce(); // javascript 14callOnce(); 15

定义对象属性

如果你想禁止一个对象添加新属性并且保留已有属性,就可以使用Object.preventExtensions(obj)。

1function def(obj, key, val, enumerable) { 2  Object.defineProperty(obj, key, { 3    value: val, // 对象定义属性 4    enumerable: !!enumerable, // 描述属性是否会出现在for in 或者 Object.keys()的遍历中 5    writable: true, // 是否可写 6    configurable: true, // 是否重新定义或者删除 7  }); 8} 9var obj = { 10  name: 1, 11}; 12def(obj, "name1", 2, true); 13obj.name1 = 3; 14console.log(obj); // {name: 1, name1: 3} 15

浏览器环境嗅探

1var inBrowser = typeof window !== "undefined"; 2var inWeex = typeof WXEnvironment !== "undefined" && !!WXEnvironment.platform; 3var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase(); 4var UA = inBrowser && window.navigator.userAgent.toLowerCase(); 5 6var isIE = UA && /msie|trident/.test(UA); 7var isIE9 = UA && UA.indexOf("msie 9.0") > 0; 8var isEdge = UA && UA.indexOf("edge/") > 0; 9var isAndroid = (UA && UA.indexOf("android") > 0) || weexPlatform === "android"; 10var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform === "ios"; 11var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge; 12var isPhantomJS = UA && /phantomjs/.test(UA); 13var isFF = UA && UA.match(/firefox\/(\d+)/); 14

JS构造函数内的方法与构造函数prototype属性上方法的对比

定义在构造函数内部的方法,会在它的每一个实例上都克隆这个方法;定义在构造函数的 prototype 属性上的方法会让它的所有示例都共享这个方法,但是不会在每个实例的内部重新定义这个方法。如果我们的应用需要创建很多新的对象,并且这些对象还有许多的方法,为了节省内存,我们建议把这些方法都定义在构造函数的 prototype 属性上。当然,在某些情况下,我们需要将某些方法定义在构造函数中,这种情况一般是因为我们需要访问构造函数内部的私有变量。

1function A() { 2  this.say = function () { 3    console.log(1); 4  }; 5} 6var a = new A(); 7a.say(); 8function B() {} 9B.prototype.say = function () { 10  console.log(2); 11}; 12var b = new B(); 13b.say(); 14var c = new B(); 15c.say(); 16

获取标签内容(包含标签)

1function getOuterHTML(el) { 2  if (el.outerHTML) { 3    return el.outerHTML; 4  } else { 5    var container = document.createElement("div"); 6    container.appendChild(el.cloneNode(true)); 7    return container.innerHTML; 8  } 9} 10

字符串hash值

1function hash(str) { 2  var hash = 5381; 3  var i = str.length; 4  while (i) { 5    hash = (hash * 33) ^ str.charCodeAt(--i); 6  } 7  return hash >>> 0; 8} 9console.log(hash("222sd"));// 164533792 10

谢谢阅读。

欢迎关注微信公众号 前端历劫之路

回复关键词 电子书,即可获取12本前端热门电子书。

回复关键词 红宝书第4版,即可获取最新《JavaScript高级程序设计》(第四版)电子书。

我创建了一个技术交流、文章分享群,群里有很多大厂的前端大佬,关注公众号后,点击下方菜单了解更多即可加我微信,期待你的加入。

本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/hfGR1XNsTKgWfCZ___Y46g,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Android So动态加载 优雅实现与原理分析

背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我