从Vue.js源码中我学到的几个实用函数

大家好,我是若川。欢迎加我微信 ruochuan12,长期交流学习。今天推荐Vuejs源码中几个实用的方法。

如果想看Vuejs源码,不知道如何下手,一般推荐配置Sourcemap,针对单个问题调试来看,如何调试Vuejs源码,我的vuex源码文章中写了。

点击下方卡片关注我、加个星标,或者查看源码等系列文章。学习源码整体架构系列、年度总结、JS基础系列


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

立即执行函数

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

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

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

(function (global) {console.log(global); // Window对象
})(this);

多层嵌套三目运算符

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

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

冻结对象

不可对指定对象增删改。

var emptyObject = Object.freeze({key: "1",
});
emptyObject.name = "maomin";
delete emptyObject.key;
emptyObject.key = "2";
console.log(emptyObject);

密封对象

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

var sealObject = Object.seal({key: 3,
});
sealObject.name = "maomin";
delete sealObject.key;
sealObject.key = 4;
console.log(sealObject); // 4

检查是否是原始值

function isPrimitive(value) {return (typeof value === "string" ||typeof value === "number" ||// $flow-disable-linetypeof value === "symbol" ||typeof value === "boolean");
}

快速检测是否是对象

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

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

检测目标类型

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

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

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

检测是否是Promise对象

function isDef(v) {return v !== undefined && v !== null;
}
function isPromise(val) {return (isDef(val) &&typeof val.then === "function" &&typeof val.catch === "function");
}
var promiseObj = new Promise(function (resolve, reject) {// 一段耗时的异步操作resolve("成功"); // 数据处理完成// reject('失败') // 数据处理出错
}).then((res) => {console.log(res);}, // 成功(err) => {console.log(err);} // 失败
);
console.log(isPromise(promiseObj)); // true

目标转换为字符串

var _toString = Object.prototype.toString;
function isPlainObject(obj) {return _toString.call(obj) === "[object Object]";
}
function toString(val) {return val == null? "": Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)? JSON.stringify(val, null, 2): String(val);
}
console.log(toString({ name: 1 })); // {"name": 1}

转化为数字

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

function toNumber(val) {var n = parseFloat(val);return isNaN(n) ? val : n;
}

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

function makeMap(str, expectsLowerCase) {var map = Object.create(null);var list = str.split(",");for (var i = 0; i < list.length; i++) {map[list[i]] = true;}return expectsLowerCase? function (val) {return map[val.toLowerCase()];}: function (val) {return map[val];};
}
var isBuiltInTag = makeMap("slot,component", true);
console.log(isBuiltInTag("component")); // true

删除简单数组中某一项

function remove(arr, item) {if (arr.length) {var index = arr.indexOf(item);if (index > -1) {return arr.splice(index, 1);}}
}
console.log(remove([1, 2], 1)); // [1]

检测对象中是否有指定key

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

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

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

将属性混合到目标对象中

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

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

function extend(to, _from) {for (var key in _from) {to[key] = _from[key];}return to;
}
function toObject(arr) {var res = {};for (var i = 0; i < arr.length; i++) {if (arr[i]) {extend(res, arr[i]);}}return res;
}
console.log(toObject([{ name: 1 }, { name: 1 }, { name: 2 }, { name1: 3 }])); // {name: 2, name1: 3}

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

function isObject(obj) {return obj !== null && typeof obj === "object";
}
function looseEqual(a, b) {if (a === b) {return true;}var isObjectA = isObject(a);var isObjectB = isObject(b);if (isObjectA && isObjectB) {try {var isArrayA = Array.isArray(a);var isArrayB = Array.isArray(b);if (isArrayA && isArrayB) {return (a.length === b.length &&a.every(function (e, i) {return looseEqual(e, b[i]);}));} else if (a instanceof Date && b instanceof Date) {return a.getTime() === b.getTime();} else if (!isArrayA && !isArrayB) {var keysA = Object.keys(a);var keysB = Object.keys(b);return (keysA.length === keysB.length &&keysA.every(function (key) {return looseEqual(a[key], b[key]);}));} else {/* istanbul ignore next */return false;}} catch (e) {/* istanbul ignore next */return false;}} else if (!isObjectA && !isObjectB) {return String(a) === String(b);} else {return false;}
}function looseIndexOf(arr, val) {for (var i = 0; i < arr.length; i++) {if (looseEqual(arr[i], val)) {return i;}}return -1;
}
console.log(looseIndexOf([{ name: 1 }, { name: 2 }], 4)); // -1
console.log(looseIndexOf([{ name: 1 }, { name: 2 }], { name: 1 })); // 0

确保函数只调用一次

function once(fn) {var called = false;return function () {if (!called) {called = true;fn.apply(this, arguments);}};
}
var callOnce = once(function () {console.log("javascript");
});
callOnce(); // javascript
callOnce();

定义对象属性

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

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

浏览器环境嗅探

var inBrowser = typeof window !== "undefined";
var inWeex = typeof WXEnvironment !== "undefined" && !!WXEnvironment.platform;
var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
var UA = inBrowser && window.navigator.userAgent.toLowerCase();var isIE = UA && /msie|trident/.test(UA);
var isIE9 = UA && UA.indexOf("msie 9.0") > 0;
var isEdge = UA && UA.indexOf("edge/") > 0;
var isAndroid = (UA && UA.indexOf("android") > 0) || weexPlatform === "android";
var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform === "ios";
var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
var isPhantomJS = UA && /phantomjs/.test(UA);
var isFF = UA && UA.match(/firefox\/(\d+)/);

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

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

function A() {this.say = function () {console.log(1);};
}
var a = new A();
a.say();
function B() {}
B.prototype.say = function () {console.log(2);
};
var b = new B();
b.say();
var c = new B();
c.say();

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

function getOuterHTML(el) {if (el.outerHTML) {return el.outerHTML;} else {var container = document.createElement("div");container.appendChild(el.cloneNode(true));return container.innerHTML;}
}

字符串hash值

function hash(str) {var hash = 5381;var i = str.length;while (i) {hash = (hash * 33) ^ str.charCodeAt(--i);}return hash >>> 0;
}
console.log(hash("222sd"));// 164533792

最近组建了一个江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你进群。


················· 若川出品 ·················

今日话题

有时候付费学习,真的是能节省很多时间,时间也是资源,也是金钱。视频学习和书籍学习都是很好的学习方式,相辅相成,当然,符合自己学习方式才是最重要的。书籍出版一般要经过严格审核流程,网上视频的质量参差不齐。欢迎分享、收藏、点赞、在看我的公众号文章~

一个愿景是帮助5年内前端人走向前列的公众号

可加我个人微信 ruochuan12,长期交流学习

推荐阅读

我在阿里招前端,我该怎么帮你?(现在还能加我进模拟面试群)

如何拿下阿里巴巴 P6 的前端 Offer

点击方卡片关注我、加个星标,或者查看源码等系列文章。
学习源码整体架构系列、年度总结、JS基础系列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

real类型_如何使用REAL方法对您的Web内容进行现实检查

real类型Web内容审核模板 (Web content audit template) I recently completed a website audit project for a nonprofit organization through CatchAFire.org. As part of the website audit, I audited every key page’s content, looking for areas of opportunity.我最近…

青海行--(7月26日)翻越祁连山

嘉峪关是最值得一写的&#xff0c;虽然也是著名的旅游城嘉峪关景点是国家&#xff21;&#xff21;&#xff21;&#xff21;&#xff21;级景区&#xff0c;但与敦煌完全不一样&#xff0c;没有人山人海的游客&#xff0c;门票也不贵&#xff0c;才&#xff11;&#xff10;&a…

导出Excel

2019独角兽企业重金招聘Python工程师标准>>> 思路: 1, 引入Excel类库; 2, 创建一个模板; 3, 将数据填充进去; 4, 生成文件; 下面是一个简单的示例 $phpExcelObj new PHPExcel(); $titleMap self::TITLE_MAP; //设置表头 $i 0; foreach ($titleMap as $key > $…

在类中用class时数据是共有还是私有_jvm学习笔记之class文件的加载、初始化

编写的java文件在要真正运行时&#xff0c;会首先被编译成 “.class"结尾的二进制文件&#xff0c;然后被虚拟机加载。那么在虚拟机中一个class文件要成为java实例&#xff0c;需要经历好几个步骤&#xff1a;1、装载&#xff1a;装载阶段由三个基本动作完成&#xff0c;要…

所有前端都要看的2D游戏化互动入门基础知识

背景现在越来越多的公司和APP开始使用游戏化的方式去做产品了&#xff0c;所谓游戏化&#xff0c;是指在非游戏环境中将游戏的思维和游戏的机制进行整合运用&#xff0c;以引导用户互动和使用的方法。支付宝里面的蚂蚁庄园、蚂蚁森林&#xff0c;通过游戏和公益的结合实现用户的…

江苏一动物园现“旋转活马” 园方:创意来自马术训练

中新网南通1月31日电 (记者唐娟)“旋转马设备采用同时容纳六匹马的遛马器组装而成&#xff0c;对马匹没有任何伤害&#xff0c;初衷是希望给小朋友一种全新体验&#xff0c;这才有了这个创意项目。”1月31日&#xff0c;针对活马版“旋转木马”引发的热议&#xff0c;江苏南通森…

加快信息化建设对地方发展的_加快设计师职业发展的9种方法

加快信息化建设对地方发展的重点 (Top highlight)Over the past few months, I have had an increase in conversations with design students from various institutions, as well as early, to senior-level designers, researchers, & product managers from various co…

epoll监听文件_介绍一下 Android Handler 中的 epoll 机制?

介绍一下 Android Handler 中的 epoll 机制&#xff1f;目录&#xff1a;IO 多路复用select、poll、epoll 对比epoll APIepoll 使用示例Handler 中的 epoll 源码分析IO 多路复用IO 多路复用是一种同步 IO 模型&#xff0c;实现一个线程可以监视多个文件句柄。一旦某个文件句柄就…

前端工程师的一大神器——puppeteer

大家好&#xff0c;我是若川。欢迎加我微信 ruochuan12&#xff0c;长期交流学习。今天推荐神器puppeteer&#xff0c;我猜有挺多人不知道。文章不长&#xff0c;看完有空也可以试玩。我18年也写过一篇puppeteer爬取生成pdf的文章&#xff0c;时间真快。前端使用puppeteer 爬虫…

selenium界面元素定位

一、 Selenium界面元素定位 本文元素定位以das2为例 #导入包 from selenium import webdriver #打开火狐驱动 driverwebdriver.Firefox() #访问网址 driver.get("http://192.168.3.217:8080/das/seatlogin.jsp ") 进行web页面自动化测试&#xff0c;对页面上…

vue.js ui_UI / UX开发:考虑Vue.js

vue.js uiBecause sometimes we have to add logic to our concepts, and Vue makes it a whole lot easier.因为有时我们必须在概念中添加逻辑&#xff0c;而Vue使其变得更加容易。 FULL DISCLOSURE: THIS IS NOT A COMPLETE JAVASCRIPT OR VUE COURSE. There’s no way I co…

Silverlight学习笔记十七BingMap(三)之地图的地区标识

如果我们需要在Bing Maps中加入一个小图钉标记&#xff0c;该如何实现了&#xff1f; Bing Maps控件已经为我们提供了这个功能&#xff0c;在Microsoft.Maps.MapControl名称空间下提供了实现图钉应用的图钉层Pushpin类用该类来实现普通标识 在Xaml中添加<map:Pushpin Locati…

win10查看pcie设备_壹拓网科技解密WIN10系统使用向日葵开机棒远程开机需要设置几个地方...

向日葵开机棒&#xff0c;是一款非常好用的远程智能远程开机硬件&#xff0c;它一头接网线&#xff0c;另外一头和被开电脑接在同一个路由器下&#xff0c;不需要和被开电脑或者设备直接连接&#xff0c;当然&#xff0c;被开电脑需要有线联网&#xff0c;暂时不支持使用无线方…

如何成为公司独当一面的工程师

大家好&#xff0c;我是若川。欢迎加我微信 ruochuan12&#xff0c;长期交流学习。今天推荐黄老师的这篇文章&#xff0c;你可能看到过了&#xff0c;但值得再看一遍。之前常有小伙伴问&#xff0c;大多情况下我都会分享这篇文章。点击下方卡片关注我、加个星标&#xff0c;或者…

flex如何做响应式设计_响应式设计-您做错了!

flex如何做响应式设计Responsive design is not just about the web that automatically adjusts to different screen resolutions and resizeable images, but designs that are crucial for web performance.自适应设计不仅涉及可自动适应不同屏幕分辨率和可调整大小图像的网…

30万手表推荐_今年六十岁生日,儿子说要送只30万的手表,请问有哪些推荐?...

关注腕表部落&#xff0c;尽享腕表生活一位读者向笔者提出这样一个问题&#xff1a;今年六十岁生日&#xff0c;儿子说要送只30万的手表&#xff0c;请问有哪些推荐&#xff1f;首先要恭喜这位老爷子&#xff0c;一来是生日马上就要到了&#xff0c;二来是还有这么孝顺而且慷慨…

写 Node.js 代码,从学会调试开始

大家好&#xff0c;我是若川&#xff08;点这里加我微信 ruochuan12&#xff0c;长期交流学习&#xff09;。今天推荐这篇调试文章&#xff0c;熟悉我的读者都知道我写的源码文章都多次强调要调试&#xff0c;而且写了调试方法。点击下方卡片关注我、加个星标&#xff0c;或者查…

创建用户友好的表单

Forms are a common way to engage with users and could be a user’s first impression of your product. Since forms aren’t always the user’s favourite thing, it is essential to make filling out forms as easy as possible. Let’s go over a few tips for creati…

细节决定成败—关于.net的.dll.refresh文件

一直在做.net的项目&#xff0c;c/s的、b/s的&#xff0c;一直没有注意这个东西。众所周知&#xff0c;.net的程序生成后会在bin目录下生成.dll文件&#xff0c;而.dll.refresh这个文件从何而来呢&#xff1f;那天无聊地google了下才知&#xff0c;这个东东是在你的项目中引用第…

环境在c盘_如何给女朋友解释为什么 Windows 上面的软件都把自己安装在 C 盘

本文经授权转载自漫画编程(ID&#xff1a;mhcoding)周末&#xff0c;我在家里面看电视&#xff0c;女朋友正在旁边鼓捣她的电脑&#xff0c;但是好像并不是很顺利&#xff0c;于是就有了以下对话。计算机存储我们使用的计算机中&#xff0c;保存信息的介质有两类&#xff1a;一…