学习一门语言的一种十分无效的办法就是浏览该编程语言开发的优良开源我的项目的源代码。Vuejs 是最好的 Javascript 开源我的项目之一。
1. 变量转字符串
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)); //""
2. 一般对象
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]";
}
很多时候,咱们心愿一个函数只执行一次。如果屡次调用该函数,则只会执行第一次。
3.once
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();
4. 浏览器嗅探
vue/src/core/util/env.js
咱们晓得 Javascript 能够在浏览器、nodejs 等环境中运行,那么如何查看以后的 Javascript 代码是否在浏览器环境中运行?
如果 Javascript 在浏览器环境中运行,则会有一个全局对象:window。因而,能够通过以下形式判断环境:
const inBrowser = typeof window !== “undefined”;
在 Chrome 中执行
在 Node 中执行
如果脚本在浏览器环境中运行,那么咱们能够通过以下形式获取浏览器的 userAgent
:
const UA = inBrowser && window.navigator.userAgent.toLowerCase();
在 Chrome 中执行
不同的浏览器具备不同的 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。