一些常用的代码块,
JS Snippets
// isObject
function isObject (obj) {
return obj !== null && typeof obj === 'object'
}
// 判断数据是数字,可能类型是string,但是'123'也算数字
function isNumber(value) {
return !isNaN(Number(value));
}
// isEmpty
const isEmpty = value => {
return value === undefined || value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0)
}
如何判断一个对象是否为数组
如果浏览器支持 Array.isArray()可以直接判断, 否则需进行必要判断
/**
* 判断一个对象是否是数组,参数不是对象或者不是数组,返回false
*
* @param {Object} arg 需要测试是否为数组的对象
* @return {Boolean} 传入参数是数组返回true,否则返回false
*/
function isArray(arg) {
if (typeof arg === 'object') {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return false;
}
如何判断一个对象是否为函数
/**
* 判断对象是否为函数,如果当前运行环境对可调用对象(如正则表达式)
* 的typeof返回'function',采用通用方法,否则采用优化方法
*
* @param {Any} arg 需要检测是否为函数的对象
* @return {boolean} 如果参数是函数,返回true,否则false
*/
function isFunction(arg) {
if (arg) {
if (typeof (/./) !== 'function') {
return typeof arg === 'function';
} else {
return Object.prototype.toString.call(arg) === '[object Function]';
}
} // end if
return false;
}
深度克隆函数 deepClone
function deepClone(obj) {
var _toString = Object.prototype.toString;
// null, undefined, non-object, function
if (!obj || typeof obj !== 'object') {
return obj;
}
// DOM Node
if (obj.nodeType && 'cloneNode' in obj) {
return obj.cloneNode(true);
}
// Date
if (_toString.call(obj) === '[object Date]') {
return new Date(obj.getTime());
}
// RegExp
if (_toString.call(obj) === '[object RegExp]') {
var flags = [];
if (obj.global) { flags.push('g'); }
if (obj.multiline) { flags.push('m'); }
if (obj.ignoreCase) { flags.push('i'); }
return new RegExp(obj.source, flags.join(''));
}
var result = Array.isArray(obj) ? [] :
obj.constructor ? new obj.constructor() : {};
for (var key in obj ) {
result[key] = deepClone(obj[key]);
}
return result;
}
function A() {
this.a = a;
}
var a = {
name: 'qiu',
birth: new Date(),
pattern: /qiu/gim,
container: document.body,
hobbys: ['book', new Date(), /aaa/gim, 111]
};
var c = new A();
var b = deepClone(c);
console.log(c.a === b.a);
console.log(c, b);
编写一个函数接受 url 中 query string 为参数,返回解析后的 Object,query string 使用 application/x-www-form-urlencoded 编码
/**
* 解析query string转换为对象,一个key有多个值时生成数组
*
* @param {String} query 需要解析的query字符串,开头可以是?,
* 按照application/x-www-form-urlencoded编码
* @return {Object} 参数解析后的对象
*/
function parseQuery(query) {
var result = {};
// 如果不是字符串返回空对象
if (typeof query !== 'string') {
return result;
}
// 去掉字符串开头可能带的?
if (query.charAt(0) === '?') {
query = query.substring(1);
}
var pairs = query.split('&');
var pair;
var key, value;
var i, len;
for (i = 0, len = pairs.length; i < len; ++i) {
pair = pairs[i].split('=');
// application/x-www-form-urlencoded编码会将' '转换为+
key = decodeURIComponent(pair[0]).replace(/\+/g, ' ');
value = decodeURIComponent(pair[1]).replace(/\+/g, ' ');
// 如果是新key,直接添加
if (!(key in result)) {
result[key] = value;
}
// 如果key已经出现一次以上,直接向数组添加value
else if (isArray(result[key])) {
result[key].push(value);
}
// key第二次出现,将结果改为数组
else {
var arr = [result[key]];
arr.push(value);
result[key] = arr;
} // end if-else
} // end for
return result;
}
function isArray(arg) {
if (arg && typeof arg === 'object') {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return false;
}
/**
console.log(parseQuery('sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8'));
*/
解析一个完整的 url,返回 Object 包含域与 window.location 相同
/**
* 解析一个url并生成window.location对象中包含的域
* location:
* {
* href: '包含完整的url',
* origin: '包含协议到pathname之前的内容',
* protocol: 'url使用的协议,包含末尾的:',
* username: '用户名', // 暂时不支持
* password: '密码', // 暂时不支持
* host: '完整主机名,包含:和端口',
* hostname: '主机名,不包含端口'
* port: '端口号',
* pathname: '服务器上访问资源的路径/开头',
* search: 'query string,?开头',
* hash: '#开头的fragment identifier'
* }
*
* @param {string} url 需要解析的url
* @return {Object} 包含url信息的对象
*/
function parseUrl(url) {
var result = {};
var keys = ['href', 'origin', 'protocol', 'host',
'hostname', 'port', 'pathname', 'search', 'hash'];
var i, len;
var regexp = /(([^:]+:)\/\/(([^:\/\?#]+)(:\d+)?))(\/[^?#]*)?(\?[^#]*)?(#.*)?/;
var match = regexp.exec(url);
if (match) {
for (i = keys.length - 1; i >= 0; --i) {
result[keys[i]] = match[i] ? match[i] : '';
}
}
return result;
}
完成函数 getViewportSize 返回指定窗口的视口尺寸
/**
* 查询指定窗口的视口尺寸,如果不指定窗口,查询当前窗口尺寸
**/
function getViewportSize(w) {
w = w || window;
// IE9及标准浏览器中可使用此标准方法
if ('innerHeight' in w) {
return {
width: w.innerWidth,
height: w.innerHeight
};
}
var d = w.document;
// IE 8及以下浏览器在标准模式下
if (document.compatMode === 'CSS1Compat') {
return {
width: d.documentElement.clientWidth,
height: d.documentElement.clientHeight
};
}
// IE8及以下浏览器在怪癖模式下
return {
width: d.body.clientWidth,
height: d.body.clientHeight
};
}
完成函数 getScrollOffset 返回窗口滚动条偏移量
/**
* 获取指定window中滚动条的偏移量,如未指定则获取当前window
* 滚动条偏移量
*
* @param {window} w 需要获取滚动条偏移量的窗口
* @return {Object} obj.x为水平滚动条偏移量,obj.y为竖直滚动条偏移量
*/
function getScrollOffset(w) {
w = w || window;
// 如果是标准浏览器
if (w.pageXOffset != null) {
return {
x: w.pageXOffset,
y: w.pageYOffset
};
}
// 老版本IE,根据兼容性不同访问不同元素
var d = w.document;
if (d.compatMode === 'CSS1Compat') {
return {
x: d.documentElement.scrollLeft,
y: d.documentElement.scrollTop
}
}
return {
x: d.body.scrollLeft,
y: d.body.scrollTop
};
}
// 费波拉希数列
function fib(n) {
return function(n, a, b) {
return n > 0 ? arguments.callee(n - 1, b, a + b) : a;
} (n, 0, 1);
}
//
// 第 114 题:编程题,找出字符串中连续出现最多的字符和个数
// 'abcaakjbb' => {'a':2,'b':2}
// 'abbkejsbcccwqaa' => {'c':3}
const arr = str.match(/(\w)\1*/g);
const maxLen = Math.max(...arr.map(s => s.length));
const result = arr.reduce((pre, curr) => {
if (curr.length === maxLen) {
pre[curr[0]] = curr.length;
}
return pre;
}, {});
console.log(result);
有一个大数组,var a = [‘1’, ‘2’, ‘3’, …];a 的长度是 100,内容填充随机整数的字符串.请先构造此数组 a,然后设计一个算法将其内容去重
/**
* 数组去重
**/
function normalize(arr) {
if (arr && Array.isArray(arr)) {
var i, len, map = {};
for (i = arr.length; i >= 0; --i) {
if (arr[i] in map) {
arr.splice(i, 1);
} else {
map[arr[i]] = true;
}
}
}
return arr;
}
/**
* 用100个随机整数对应的字符串填充数组。
**/
function fillArray(arr, start, end) {
start = start == undefined ? 1 : start;
end = end == undefined ? 100 : end;
if (end <= start) {
end = start + 100;
}
var width = end - start;
var i;
for (i = 100; i >= 1; --i) {
arr.push('' + (Math.floor(Math.random() * width) + start));
}
return arr;
}
var input = [];
fillArray(input, 1, 100);
input.sort(function (a, b) {
return a - b;
});
console.log(input);
normalize(input);
console.log(input);
// 116
1 + "1" // 11
2 * "2" // 4
[1, 2] + [2, 1] // "1,22,1"
"a" + + "b" // aNaN
1 + "1"
// 加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来所以值为:“11”
2 * "2"
// 乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值
[1, 2] + [2, 1]
// Javascript中所有对象基本都是先调用valueOf方法,如果不是数值,再调用toString方法。
// 所以两个数组对象的toString方法相加,值为:"1,22,1"
"a" + + "b"
// 后边的“+”将作为一元操作符,如果操作数是字符串,将调用Number方法将该操作数转为数值,如果操作数无法转为数值,则为NaN。
// 所以值为:"aNaN"
// 以上均参考:《Javascript高级程序设计》
Js new Date()方法移动端兼容 ios
//直接:安卓可兼容两种格式,ios支持/** 2019/11/09 10:13:21 **/格式
let str = '2019-11-09 10:13:21'; // 这种格式 ios不兼容使用new date() >==> NaN
str = str.replace(/\-/g, "/"); // 兼容ios '2019/11/09 10:13:21'
let iosstr = '2019/11/09 10:13:21'; // 兼容ios写法