[关闭]
@EncyKe 2017-03-03T07:40:18.000000Z 字数 11680 阅读 3461

手册:前端不完全 hack 工具小集:JS 篇

#手册 JS



1. 零碎小集

1.1. 判断时,用 === 代替 ==,用 !== 代替 !=

  1. {} === {};
  2. [] === [];
  3. NaN === NaN;
  4. // 以上判断均将返回 false;

1.2. call() 和 apply() 方法

  1. b.call(a, arg);
  2. b.apply(a, [arg1, arg2]);

1.3. 双波浪号 ~~ 可用于浮点数值取整

  1. ~~3.14 === Math.floor(3.14);
  2. // ==> true

1.4. 将判断条件写入 case

  1. switch (true) {
  2. case isNaN(age):
  3. category = "not an age";
  4. break;
  5. case (age >= 50):
  6. category = "Old";
  7. break;
  8. case (age <= 20):
  9. category = "Baby";
  10. break;
  11. default:
  12. category = "Young";
  13. break;
  14. };

1.5. 为函数参数设置默认值

  1. function fn(arg) {
  2. arg = arg || 10;
  3. // 设置 arg 默认值为 10
  4. }

1.6. 把 json 数据的友好呈现

  1. JSON.stringify(json, null, 4);

1.7 对象的 key 值可以是空串 '', 并且可以被解析为 JSON

  1. var obj = {'': 1};
  2. obj[''] === 1;
  3. // ==> true
  4. JSON.stringify(obj);
  5. // ==> "{"":1}"

1.8 新开标签页

window.open() 方法新开一个标签页链接有可能被现代浏览器阻止(一般是弹窗提示是否允许本页弹出新窗口),因此在产品逻辑有必要新开页面时,应避免使用 window.open() 方法;可以将链接拼接入 <a href="#" target="_blank"></a> 触发。

2. 常见类型验证

typeof
用于判断基本数据类型的运算符;
instanceof
用以判断某个构造函数的 prototype 属性所指向的對象是否存在于另外一个待检测对象的原型链上的运算符;
constructor
返回生成这一示例的方法;
Object.prototype.toString
返回对象类型;
  1. function getType(obj) {
  2. return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
  3. // return Object.prototype.toString.call(obj).slice(8, -1);
  4. }

2.1. 验证 undefined(是否存在)

  1. typeof theVar === 'undefined';

或者——

  1. theVar === undefined;
  1. if (!theVar) {
  2. var theVar = { };
  3. }

或者——

  1. var theVar = theVar || {};

2.2. 验证数字

  1. typeof theVar === 'number';
  2. // ==> true

或者——

  1. theVar === +theVar;
  2. // ==> true
  1. isNaN(NaN);
  2. // ==> true
  1. typeof NaN;
  2. // ==> 'number'
  3. Object.prototype.toString.call(NaN);
  4. // ==> '[object Number]'
  5. NaN instanceof Number;
  6. // ==> false

2.3. 验证字符串

  1. typeof theVar === 'string';
  2. // ==> true

2.4. 验证布尔值

  1. typeof theVar === 'boolean';
  2. // ==> true

2.5. 验证函数

  1. typeof theVar === 'function';
  2. // ==> true

2.6. 验证 null

  1. getType(null);
  2. // ==> 'Null'

2.7. 验证数组

  1. Array.isArray(theVar);

或者——

  1. if (!Array.isArray) {
  2. Array.isArray = function(arg) {
  3. return Object.prototype.toString.call(arg) === '[object Array]';
  4. };
  5. }

或者——

  1. theVar instanceof Array;
  2. // ==> true

或者——

  1. theVar.constructor.toString().indexOf('Array') > -1;
  2. // ==> true

2.8. 验证正则表达式

  1. theVar instanceof RegExp;
  2. // ==> true

或者——

  1. theVar.constructor.toString().indexOf('RegExp') > -1;
  2. // ==> true

或者——

  1. getType(theVar);
  2. // ==> 'RegExp'

2.9. 验证日期

  1. theVar instanceof Date;
  2. // ==> true

或者——

  1. theVar.constructor.toString().indexOf('Date') > -1;
  2. // ==> true

或者——

  1. getType(theVar);
  2. // ==> 'Date'

2.10. 验证对象

  1. theVar.constructor.toString().indexOf('Object') > -1;
  2. // ==> true

或者——

  1. getType(theVar);
  2. // ==> 'Object'

2.11. 验证对象属性

对于

  1. obj = {
  2. prop: 'value'
  3. }
  1. 'prop' in obj;
  2. // ==> true

或者——

  1. obj.hasOwnProperty('prop');
  2. // ==> true

3. 常见类型转换

3.1. Number => String

对于 var x = new Number();

  1. x + '';

或者——

  1. String(x);

或者——

  1. x.toString();

更复杂用法——

  1. x.toExponential()
  2. // ==> '0e+0'
  3. x.toFixed()
  4. // ==> '0'
  5. x.toPrecision(2)
  6. // ==> '0.0'

3.2. Boolean => String

  1. String(false);
  2. // ==> 'false'
  3. String(true);
  4. // ==> 'true'

或者——

  1. false.toString();
  2. // ==> 'false'
  3. true.toString();
  4. // ==> 'true'

3.3. Date => String

  1. String(Date());

或者——

  1. Date().toString();

3.4. String => Number

对于 var x = new String();

  1. +x;

或者——

  1. Number(x);

或者——

  1. // 注意加上进制参数;
  2. parseInt(x, 10);
  3. // 或者:
  4. parseFloat(x);

或者——

  1. Math.floor(x);

3.5. Boolean => Number

  1. Number(false);
  2. // ==> 0
  3. Number(true);
  4. // ==> 1

3.6. Date => Number

  1. Number(new Date());
  2. // ==> 当前时间戳,此举等同于 new Date().getTime();

3.7. any object => Boolean

  1. !!'abc'.match(/a/gim);
  2. // ==> true

4. 循环遍历相关

4.1. forEach() 方法

  1. array.forEach(val, index){
  2. // code
  3. }

4.2. for() 方法

  1. for (var i = 0, len = array.length; i < len; i++) {
  2. // code
  3. }

4.3. map() 方法

  1. array.map(function (val, index) {
  2. return val * val;
  3. });

4.4. $.each() 方法

  1. $.each(array, function(index, val) {
  2. // code
  3. });

4.5. while() 方法

  1. var i = 0;
  2. var len = array.length;
  3. while(i < len){
  4. // code
  5. i++;
  6. }

4.6. 使用 for in 遍历对象属性避免循环 prototype 属性

  1. for (var name in object) {
  2. if (object.hasOwnProperty(name)) {
  3. // code
  4. }
  5. }

4.7. 不要在循环内部使用 try-catch-finally

4.8. 双重 for 循环

  1. var primary = [2, 3, 5, 7, 11, 13, 17, 19];
  2. var odd = [1, 3, 5, 7, 9, 11, 13, 17, 19];
  3. for (var i = 0, iLen = primary.length; i < iLen; i++) {
  4. for (var j = 0, jLen = odd.length; j < jLen; j++) {
  5. if (primary[i] === odd[j]) {
  6. console.info(primary[i]);
  7. }
  8. }
  9. }

可写作——

  1. var primary = [2, 3, 5, 7, 11, 13, 17, 19];
  2. var odd = [1, 3, 5, 7, 9, 11, 13, 17, 19];
  3. primary.map(function (i){
  4. var flag = odd.find(function (j){
  5. return i === j;
  6. })
  7. if (flag) {
  8. console.info(i);
  9. }
  10. });

5. 随机生成系列

5.1. 随机生成字符串

  1. /**
  2. * @description 随机生成字符串
  3. * @param {Number} len - 指定的长度
  4. * @return {String} randomString - 随机生成的长度为 len 的字符串
  5. */
  6. function randomString(len) {
  7. var randomString = '';
  8. for (;randomString.length < len; randomString += Math.random().toString(36).substr(2));
  9. return randomString.substr(0, len);
  10. }

5.2. 随机生成指定范围内的数值

  1. /**
  2. * @description 随机生成指定范围内的数值
  3. * @param {Number} max - 最大值
  4. * @param {Number} min - 最小值
  5. * @return {Number} randomNumber - 随机生成指定范围内的数值
  6. */
  7. function randomBetween(max, min){
  8. min ? min = min : min = 0;
  9. var randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
  10. return randomNumber;
  11. }

5.3. 随机返回数组中的某一值

  1. function randomItem(array) {
  2. var randomItem = array[Math.floor(Math.random() * array.length)];
  3. return randomItem;
  4. }

5.4. 随机打乱数组中的值位置

  1. /**
  2. * @description 随机打乱数组中的值位置
  3. * @param {Array} array - 待打乱数组
  4. * @return {Array} array - 已打乱数组
  5. */
  6. function randomArray(array) {
  7. array = array.sort(function(){ return Math.random() - 0.5});
  8. return array;
  9. }

6. 数组相关

6.1. 生成指定范围的数值数组

  1. /**
  2. * @description 生成指定范围的数值数组
  3. * @param {Number} max - 最大值
  4. * @param {Number} min - 最小值
  5. * @return {Array} numbersArray - 生成的指定范围内的数值数组
  6. */
  7. function listNumbersArray(min, max) {
  8. var numbersArray = [];
  9. for(var i = min; numbersArray.push(i++) < max;);
  10. return numbersArray;
  11. }

6.2. 数组去重

  1. /**
  2. * @description 数组去重
  3. * @param {Array} array - 待去重数组
  4. * @return {Array} result - 已去重数组
  5. * @example
  6. * var fruits = ['apple', 'orange', 'peach', 'apple', 'strawberry', 'orange'];
  7. * var uniquefruits = removeDuplicates(fruits);
  8. * // ==> ['apple', 'orange', 'peach', 'strawberry'];
  9. */
  10. function removeDuplicates(array) {
  11. var temp = {};
  12. var result = [];
  13. for (var i = 0, len = array.length; i < len; i++) {
  14. temp[array[i]] = true;
  15. }
  16. for (var t in temp) {
  17. result.push(t);
  18. }
  19. return result;
  20. }

6.3. 数组删除值

  1. /**
  2. * @description 删除数组中的指定值
  3. * @param {Array} array - 待操作数组
  4. * @param {String} val - 待删除的数组中的值
  5. * @example
  6. * var somearray = ['mon', 'tue', 'wed', 'thur']
  7. * removeVal(somearray, 'tue');
  8. * // somearray will be ['mon', 'wed', 'thur']
  9. */
  10. function removeVal(array, val) {
  11. for(var i = 0, len = array.length; i < len; i++) {
  12. if(array[i] === val) {
  13. array.splice(i, 1);
  14. break;
  15. }
  16. }
  17. }

或者——

  1. /**
  2. * @description 删除数组中的指定值
  3. * @param {String} val - 待删除的数组中的值
  4. * @example
  5. * var somearray = ['mon', 'tue', 'wed', 'thur']
  6. * somearray.removeVal('tue');
  7. * // somearray will be ['mon', 'wed', 'thur']
  8. */
  9. Array.prototype.removeVal = function(val) {
  10. for(var i = 0, len = this.length; i < len; i++) {
  11. if(this[i] == val) {
  12. this.splice(i, 1);
  13. break;
  14. }
  15. }
  16. }

6.4. 清空数组

  1. array.length = 0;

6.5. 删除数组的值

  1. array.splice(3,1);
  2. // 将删除索引为 3 的值;

6.6. 截断数组

  1. array.length = 4;
  2. // 将数组更新为只保留前 4 个值;

6.7. 检测数组/字符串是否包含值

  1. if (!Array.prototype.indexOf) {
  2. Array.prototype.indexOf = function(obj, start) {
  3. for (var i = (start || 0), len = this.length; i < len; i++) {
  4. if (this[i] === obj) {
  5. return i;
  6. }
  7. }
  8. return -1;
  9. }
  10. }
  11. if (!String.prototype.contains) {
  12. String.prototype.contains = function (arg) {
  13. return !!~this.indexOf(arg);
  14. };
  15. }

6.8. 快速排序(找出最大值)函数

  1. /**
  2. * @description 获取最大值
  3. * @param {Array.<Number>} numbers - 数值数组
  4. * @return {Number} max - 最大数值
  5. * @example
  6. * getMax([1, 2, 3, 4]);
  7. */
  8. function getMax(numbers) {
  9. numbers.sort(function(a, b){
  10. {
  11. return b - a;
  12. }
  13. });
  14. return max = numbers[0];
  15. }

或者——

  1. /**
  2. * @description 获取最大值
  3. * @param {Array.<Number>} numbers - 数值数组
  4. * @return {Number} max - 最大数值
  5. * @example
  6. * getMax([1, 2, 3, 4]);
  7. */
  8. function getMax(numbers) {
  9. var max = 0;
  10. for (var i = 0, len = numbers.length; i < len; i++) {
  11. if (numbers[i] > max) {
  12. max = numbers[i];
  13. };
  14. }
  15. return max;
  16. }

还可以——

  1. function getMax(array) {
  2. var max = Math.max.apply(Math, array);
  3. return max;
  4. }
  5. function getMin(array) {
  6. var min = Math.min.apply(Math, array);
  7. return min;
  8. }

7. 获取图片到屏幕上下边距

  1. /**
  2. * @description 获取图片到屏幕上下边距
  3. * @param {Number} i - 页面内图片的索引,从 0 开始
  4. * @param {String} dir - 方向:'top' | 'bottom'
  5. * @return {Number} - 边距值
  6. */
  7. function getImgScroll(i, dir) {
  8. var imgs = document.getElementsByTagName('img');
  9. var imgTop = imgs[i].offsetParent.offsetTop + imgs[i].offsetTop - document.body.scrollTop;
  10. var imgBottom = window.innerHeight - imgs[i].scrollHeight - (imgs[i].offsetParent.offsetTop + imgs[i].offsetTop - document.body.scrollTop);
  11. if (dir === 'top') {
  12. return imgTop;
  13. } else if (dir === 'bottom') {
  14. return imgBottom;
  15. };
  16. };

8. 类名操作函数

8.1. 增加类名

  1. /**
  2. * @description 为 DOM 元素增加指定域名
  3. * @param {DOMelement} el - DOM 元素
  4. * @param {String} cls - 类名
  5. * @example
  6. * var el = document.getElementById('el');
  7. * addClass(el, 'hidden');
  8. */
  9. function addClass(el, cls) {
  10. var classes = el.className.split(' ');
  11. classes.push(cls);
  12. el.className = classes.join(' ');
  13. }

或者——

  1. /**
  2. * @description 为 DOM 元素增加指定类名
  3. * @param {DOMelement} el - DOM 元素
  4. * @param {String} cls - 类名
  5. * @example
  6. * var el = document.getElementById('el');
  7. * addClass(el, 'hidden');
  8. */
  9. function addClass(el, cls) {
  10. if (!!el.classList) {
  11. el.classList.add(cls)
  12. } else {
  13. var existence = el.className.indexOf(cls)
  14. if (existence < 0) {
  15. el.className += cls;
  16. }
  17. }
  18. }

8.2. 删减类名

  1. /**
  2. * @description 为 DOM 元素删减指定类名
  3. * @param {DOMelement} el - DOM 元素
  4. * @param {String} cls - 类名
  5. * @example
  6. * var el = document.getElementById('el');
  7. * removeClass(el, 'hidden');
  8. */
  9. function removeClass(el, cls) {
  10. if (!!el.classList) {
  11. el.classList.remove(cls);
  12. } else {
  13. var classNames = el.className.split(/\s+/);
  14. var pos = -1,
  15. i,
  16. len = classNames.length;
  17. for (i = 0; i < len; i++ ) {
  18. if (classNames[i] == cls) {
  19. pos = i;
  20. break;
  21. }
  22. }
  23. classNames.splice(i, 1);
  24. el.className = classNames.join(' ');
  25. }
  26. }

8.3. 切换类名

  1. /**
  2. * @description 为 DOM 元素切换指定类名
  3. * @param {DOMelement} el - DOM 元素
  4. * @param {String} cls - 类名
  5. * @example
  6. * var el = document.getElementById('el');
  7. * toggleClass(el, 'hidden');
  8. */
  9. function toggleClass(el, cls) {
  10. if (!!el.classList) {
  11. el.classList.toggle(cls);
  12. } else {
  13. var classNames = el.className.split(/\s+/);
  14. var pos = -1,
  15. i,
  16. len = classNames.length;
  17. for (i = 0; i < len; i++ ) {
  18. if (classNames[i] == cls) {
  19. pos = i;
  20. break;
  21. }
  22. }
  23. if (pos == -1) {
  24. classNames.push(cls)
  25. } else {
  26. classNames.splice(i, 1);
  27. }
  28. el.className = classNames.join(' ');
  29. }
  30. }

9. 获取页面可见性(标签页活动状态)

HTML5 提供页面可见性接口,可用 document.visibilitychange 页面事件或者 document.hidden 属性来判断当前页面所在标签是否处于激活状态。

9.1. document.visibilityState

9.2. document.hidden

9.3. 页面可见性兼容性监听

  1. // 各种浏览器兼容
  2. var hidden, state, visibilityChange;
  3. if (typeof document.hidden !== 'undefined') {
  4. hidden = 'hidden';
  5. visibilityChange = 'visibilitychange';
  6. state = 'visibilityState';
  7. } else if (typeof document.mozHidden !== 'undefined') {
  8. hidden = 'mozHidden';
  9. visibilityChange = 'mozvisibilitychange';
  10. state = 'mozVisibilityState';
  11. } else if (typeof document.msHidden !== 'undefined') {
  12. hidden = 'msHidden';
  13. visibilityChange = 'msvisibilitychange';
  14. state = 'msVisibilityState';
  15. } else if (typeof document.webkitHidden !== 'undefined') {
  16. hidden = 'webkitHidden';
  17. visibilityChange = 'webkitvisibilitychange';
  18. state = 'webkitVisibilityState';
  19. }
  20. // 添加监听器,在title里显示状态变化
  21. document.addEventListener(visibilityChange, function() {
  22. document.title = document[state];
  23. }, false);
  24. // 初始化
  25. document.title = document[state];

10. 监听设备是否横屏


附:参考

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注