学习一门语言的一种非常有效的方法就是阅读该编程语言开发的优秀开源项目的源代码。 vuejs是最好的Javascript开源项目之一。
vue/src/shared/util.js
将值转换为字符串是一个非常常见的需求,在Javascript中,有两个函数将值转换为字符串:
String()
JSON.stringify()
这两个功能具有不同的机制,请看下面代码:
console.log(String(null)); // null
console.log(JSON.stringify(null)); // null
console.log(String(undefined)); // undefined 这里是字符串
console.log(JSON.stringify(undefined)); // undefined 这里是变量
console.log(String("abc")); // abc
console.log(JSON.stringify("abc")); // "abc"
console.log(String({ key: "value" })); // [object Object]
console.log(JSON.stringify({ key: "value" })); // {"key":"value"}
console.log(String([1, 2, 3])); // 1,2,3
console.log(JSON.stringify([1, 2, 3])); // [1,2,3]
const obj = {
title: "devpoint",
toString() {
return "obj";
},
};
console.log(String(obj)); // obj
console.log(JSON.stringify(obj)); // {"title":"devpoint"}
从上面输出结果来看,两个方法将对象转为字符串机制存在差异,如何选择呢?
实际开发中我们需要将null和undefined转换为字符串时,经常是希望它返回一个空字符串。
当需要将一个数组和一个普通对象转换为字符串时,经常使用JSON.stringify。
如果需要对象的toString方法被重写,则需要使用String()。
在其他情况下,使用String()将变量转换为字符串。
为了满足以上条件,Vue源码的实现如下:
function isPlainObject(obj) {
return Object.prototype.toString.call(obj) === "[object Object]";
}
function toString(val) {
if (val === null || val === undefined) return "";
if (Array.isArray(val)) return JSON.stringify(val);
if (isPlainObject(val) && val.toString === Object.prototype.toString)
return JSON.stringify(val);
return String(val);
}
const obj = {
title: "devpoint",
toString() {
return "obj";
},
};
console.log(toString(obj)); // obj
console.log(toString([1, 2, 3])); // [1, 2, 3]
console.log(toString(undefined)); // ""
console.log(toString(null)); // ""
vue/src/shared/util.js
Object.prototype.toString允许将对象转换为字符串。对于普通对象,当调用此方法时,总是返回[object object]。
const runToString = (obj) => Object.prototype.toString.call(obj);
console.log(runToString({})); // [object Object]
console.log(runToString({ title: "devpoint" })); // [object Object]
console.log(runToString({ title: "devpoint", author: { name: "devpoint" } })); // [object Object]
类似上面这种对象我们称之为普通对象。
在Javascript中还有一些特殊的对象,如Array、String和RegExp,它们在Javascript引擎中具有特殊的设计。当它们调用Object.prototype.toString方法时,会返回不同的结果。
const runToString = (obj) => Object.prototype.toString.call(obj);
console.log(runToString(["devpoint", 2021])); // [object Array]
console.log(runToString(new String("devpoint"))); // [object String]
console.log(runToString(/devpoint/)); // [object RegExp]
为了区分特殊设计对象和普通对象,可以用下面的函数来实现。
function isPlainObject(obj) {
return Object.prototype.toString.call(obj) === "[object Object]";
}
很多时候,我们希望一个函数只执行一次。如果多次调用该函数,则只会执行第一次。
vue/src/shared/util.js
很多时候,我们希望一个函数只执行一次。如果多次调用该函数,则只会执行第一次。
function once(fn) {
let called = false;
return function () {
if (!called) {
called = true;
fn.apply(this, arguments);
}
};
}
function launchRocket() {
console.log("我已经执行了");
}
const launchRocketOnce = once(launchRocket);
launchRocketOnce();
launchRocketOnce();
launchRocketOnce();
vue/src/core/util/env.js
我们知道Javascript可以在浏览器、nodejs等环境中运行,那么如何检查当前的Javascript代码是否在浏览器环境中运行?
如果Javascript在浏览器环境中运行,则会有一个全局对象:window。因此,可以通过以下方式判断环境:
const inBrowser = typeof window !== "undefined";
如果脚本在浏览器环境中运行,那么我们可以通过以下方式获取浏览器的userAgent:
const UA = inBrowser && window.navigator.userAgent.toLowerCase();
不同的浏览器具有不同的userAgent。在Internet Explorer的userAgent中,始终包含单词MSIE和Trident。在Chrome浏览器的userAgent中,始终包含Chrome一词。
同样,在Android操作系统浏览器中,userAgent始终包含单词Android。在iOS中,总是有iPhone、iPad、iPod、iOS一词。
因此,可以通过检查userAgent来确定当前的浏览器供应商和操作系统。
export const UA = inBrowser && window.navigator.userAgent.toLowerCase();
export const isIE = UA && /msie|trident/.test(UA);
export const isIE9 = UA && UA.indexOf("msie 9.0") > 0;
export const isEdge = UA && UA.indexOf("edge/") > 0;
export const isAndroid = (UA && UA.indexOf("android") > 0) || weexPlatform === "android";
export const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform === "ios";
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
export const isPhantomJS = UA && /phantomjs/.test(UA);
export const isFF = UA && UA.match(/firefox\/(\d+)/);
附带说明一下,Edge和Chrome均基于Chromium,因此两种浏览器的userAgent都包含Chrome一词。也就是说,当浏览器的userAgent中包含Chrome一词时,该浏览器不一定是Chrome。const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
作者:天行无忌
链接:https://juejin.cn/post/6971225536882278413
来源:掘金
一直以来进行了比较多的微信小程序开发... 总会接触到一些和官方组件或 api 相关或其无法解决的需求,于是决定在这里小小的整理一下微信小程序开发的一些技巧
小程序提供onShareAppMessage 函数,此函数只支持分享给我微信朋友,小程序如何分享到朋友圈呢?使用canvas绘制一张图片,并用wx.previewImage预览图片,然后长按图片保存图片到手机。
前端新手程序员不知道的 20个小技巧:作为前端开发者,使用双显示器能大幅提高开发效率、学编程最好的语言不是PHP,是English、东西交付之前偷偷测试一遍、问别人之前最好先自己百度,google一下、把觉得不靠谱的需求放到最后做,很可能到时候需求就变了...
本地的 IP 地址是分配给你计算机上的内部硬件或虚拟网卡的本地/私有 IP 地址。根据你的 LAN 配置,上述 IP 地址可能是静态或动态的。公共的 IP 地址是你的 Internet 服务提供商(ISP)为你分配的公共/外部 IP 地址。
使用 :not() 在菜单上应用/取消应用边框;给body添加行高;所有一切都垂直居中;逗号分隔的列表;使用负的 nth-child 选择项目;对图标使用SVG;优化显示文本;对纯CSS滑块使用 max-height;继承 box-sizing
禁用右键点击;禁用搜索文本框;新窗口打开链接;检测浏览器;预加载图片;样式筛选;列高度相同;字体大小调整;返回页面顶部;获取鼠标的xy坐标;验证元素是否为空;替换元素
为你网站的用户留下良好的第一印象是非常必要的。随着商业领域的竞争,拥有一个吸引人的网站可以帮助你脱颖而出。研究表明,如果加载时间超过3秒,会有 40% 的用户放弃访问你的网站
清除浮动主要用于子元素浮动(float)之后,父元素无法撑起高度和宽度。文字少时居中,多时靠左因为div嵌套着p,所以p的尺寸并不会超过div。但是要注意,当p的内容为英文单词组成的时候
这次我们主要来分享11个在日常教程中不常被提及的JavaScript小技巧,他们往往在我们的日常工作中经常出现,但是我们又很容易忽略。Set类型是在ES6中新增的,它类似于数组,但是成员的值都是唯一的
为什么要在JavaScript里写CSS?避免命名全局污染,条件和动态样式(比如选择主题色之类的),在框架层面进行限制或补充(比如补全供应商前缀),避免业务人员使用奇技淫巧
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!