前端防错以及好用小tips指南总结
1.一般情況下我們接收到的都是對象格式,某些情況下,需要接到後端傳過來的奇怪的字符串格式的JSON,需要解析成對象,但是有時候他們傳過來的格式有問題,會報錯
- 解決方案:可以将方法放在try{JSON.parse(...)}catch(e){}代码块中。
- 好用的JSON.stringify 方法
// 1.1接受一个数组参数,指定需要转成字符串的属性,第二个参数指定,只转a属性。
JSON.stringify({ a: 1, b: 2 }, ['a'])
// '{"a":1}'
// 1.2接受函数参数,转化对象的键和值
function f12(key, value) {
if (typeof value === "number") {
value = 2 * value;
}
return value;
}
JSON.stringify({ a: 1, b: 2 }, f12)
// '{"a":2,"b":4}'
// 1.3只拿自己想要的值,如果处理函数返回undefined或没有返回值,這個属性就沒了啊哈哈。
function f13(key, value) {
if (typeof (value) == "string") {
return undefined;
}
return value;
}
JSON.stringify({ a: "abc", b: 123 }, f13)
// '{"b":123}'
// 1.4給數據添加可讀性
var d = { a: 1, b: 2 }
JSON.stringify(d, null, 2);
// "{
// "a": 1,
// "b": 2
// }"
// 1.5只输出你你想要的keys,加強版
var e = { a: 1, b: 2, c: 3, d: 4 }
JSON.stringify(e, ["a", "d"], 4);
// "{
// "a": 1,
// "d": 4
// }"
// 1.5還可以這樣玩一下
JSON.stringify({ a: 1, b: 2, c: 3 }, null, '|----');
// "{
// |----"a": 1,
// |----"b": 2,
// |----"c": 3
// }"
// 1.6關於JSON.parse你也可以試試看喲
2.switch case 一定要記得寫break
3.对象最後一個屬性结尾多逗号兼容IE會出問題,記得格式化一下代碼
4.輸入框防呆要注意:如果是字符串類型就用myInput && myInput.trim()
const myInput = ' '
if (myInput && myInput.trim()) { console.log('這個輸入框不為空') }
5.禁止給未声明的变量赋值,否則會搞出来很多全局变量
6.多JS文件打包,如果你不喜歡寫分號,有時候會出問題,可以在文件開頭加個分號
7.如果你不喜歡寫分號,有時候會引起函数返回值不正确或者是代碼執行有問題
- 舉例說明
function e() {
return
{
a: "e"
}
}
console.log(e()) // undefined
let z = 'z'
let m = 'm'
[z, m] = [m, z]
console.log(z, m) // Uncaught ReferenceError: m is not defined
let z1 = 'z';
let m1 = 'm';
[z1, m1] = [m1, z1];
console.log(z1, m1); // m z
8.Array forEach()中无法return和break,代替方法有some()与every()
var arr = [1, 2, 3, 4, 5];
var num = 3;
arr.forEach(function (v) {
if (v == num) {
break;
}
console.log(v);
});
// Uncaught SyntaxError: Illegal break statement
var arr = [1, 2, 3, 4, 5];
var num = 3;
arr.forEach(function (v) {
if (v == num) {
return;
}
console.log(v);
});
// VM62:7 1
// VM62:7 2
// VM62:7 4
// VM62:7 5
// 解決如下,使用数组的另外两个方法some()与every():
var arr = [1, 2, 3, 4, 5];
var num = 3;
arr.some(function (v) {
if (v == num) {
return true;
}
console.log(v);
});
// VM65:7 1
// VM65:7 2
// true 跳出循環啦~~~~
var arr = [1, 2, 3, 4, 5];
var num = 3;
arr.every(function (v) {
if (v == num) {
return false;
} else {
console.log(v);
return true;
}
});
// 1
// 2
// false 跳出循環啦~~~~
- 小金理解的小總結
- 8.1 forEach没有返回值,只针对每个元素调用函數.
- 8.2 some 当内部return true时跳出整个循环.
- 8.3 every 当内部return false时跳出整个循环.
- 8.4 map 有返回值,返回一个新的数组,每个元素为调用函數的结果
9.需要使用到 eval()的时候,使用 Function()来搞一下
- 9.1 eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。
- 9.2 但是,(谢天谢地)存在一个非常好的eval替代方法:只需使用 window.Function。 这有个例子方便你了解如何将eval()的使用转变为Function()。
使用eval的糟糕代码:
function looseJsonParse(obj){
return eval("(" + obj + ")");
}
console.log(looseJsonParse(
"{a:(4-1), b:function(){}, c:new Date()}"
))
不用eval的更好的代码:
function looseJsonParse(obj){
return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse(
"{a:(4-1), b:function(){}, c:new Date()}"
))
10.箭头函数不仅没有this,常用的arguments也没有。如果你能获取到arguments,那它一定是来自父作用域的。
11.防止後端瞎搞,常用的寫法
var ccc = { a: { t: 123 } }
function setC() { ccc['b'] = 111 }
ccc && ccc.a && ccc.a.t && setC()
12.關於arguments,你要注意一下,想要把它當成數組用的話,需要轉化一下哦~
function setArg() {
console.log(arguments) // Arguments(4)
console.log([].slice.call(arguments)) // Array(4) ----[1,2,3,'4']
}
setArg(1, 2, 3, '4')
13.判断数组用這個:Array.isArray,別用其他的~
14.使用Object.prototype 和 for in 搭配使用可能引發的坑,要注意下下~~
- 14.1如果你非要用,那就記得搭配上Object.hasOwnProperty(key)
var q = { a: 1, s: 2, d: 3 };
Object.prototype.w = function () { };
for (var key in q) {
if (q.hasOwnProperty(key)) {
console.log('for in搭配hasOwnProperty方法', '對象的key:', key, '對象的value:', q[key]);
}
console.log('for in方法', '對象的key:', key, '對象的value:', q[key]);
}
Object.keys(q).forEach(key => {
console.log('forEach方法', '對象的key:', key, '對象的value:', q[key]);
})
Object.keys(q).some(key => {
if (key === 'e') {
return true; // some true时跳出 循环.
}
console.log('some方法', '對象的key:', key, '對象的value:', q[key]);
})
Object.keys(q).every(key => {
if (key === 'e') {
return false; // every false 跳出 循环
} else {
console.log('every方法', '對象的key:', key, '對象的value:', q[key]);
return true;
}
})
// for in搭配hasOwnProperty方法 對象的key: a 對象的value: 1
// for in方法 對象的key: a 對象的value: 1
// for in搭配hasOwnProperty方法 對象的key: s 對象的value: 2
// for in方法 對象的key: s 對象的value: 2
// for in搭配hasOwnProperty方法 對象的key: d 對象的value: 3
// for in方法 對象的key: d 對象的value: 3
// for in方法 對象的key: w 對象的value: ƒ () { }
// forEach方法 對象的key: a 對象的value: 1
// forEach方法 對象的key: s 對象的value: 2
// forEach方法 對象的key: d 對象的value: 3
// some方法 對象的key: a 對象的value: 1
// some方法 對象的key: s 對象的value: 2
// some方法 對象的key: d 對象的value: 3
// every方法 對象的key: a 對象的value: 1
// every方法 對象的key: s 對象的value: 2
// every方法 對象的key: d 對象的value: 3
15.带有ID的DOM树元素會成为全局变量,SO:尽量避免使用全局变量
<div id="myDiv"></div>
<script>
if (typeof myDiv === 'undefined') {
myDiv = '測試一下我是不是字符串' // 其实这里不会执行到的
}
console.log(myDiv)
// <div id="myDiv"></div>--输出DOM对象
myDiv = '改一改變量感受一下'
console.log(myDiv)
// 改一改變量感受一下
</script>
16.關於按给定的参数创建一日期对象以及獲取瀏覽器版本
const data1 = new Date("2019-01-01")
// Tue Jan 01 2019 08:00:00 GMT+0800 (台北标准时间)
// ie某些版本會告訴你語法錯誤
const data2 = new Date(2019,0,1)
// Tue Jan 01 2019 00:00:00 GMT+0800 (台北标准时间), IE在用版本還OK
const data3 = new Date("2019/01/01")
// Tue Jan 01 2019 00:00:00 GMT+0800 (台北标准时间), IE在用版本還OK
const userAgent1 = navigator.userAgent.toLowerCase()
// "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/71.0.3578.98 safari/537.36"
function getBroswer(){
var Sys = {};
var ua = navigator.userAgent.toLowerCase();
var s;
(s = ua.match(/edge\/([\d.]+)/)) ? Sys.edge = s[1] :
(s = ua.match(/rv:([\d.]+)\) like gecko/)) ? Sys.ie = s[1] :
(s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
(s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
(s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
(s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
(s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;
if (Sys.edge) return { broswer : "Edge", version : Sys.edge };
if (Sys.ie) return { broswer : "IE", version : Sys.ie };
if (Sys.firefox) return { broswer : "Firefox", version : Sys.firefox };
if (Sys.chrome) return { broswer : "Chrome", version : Sys.chrome };
if (Sys.opera) return { broswer : "Opera", version : Sys.opera };
if (Sys.safari) return { broswer : "Safari", version : Sys.safari };
return { broswer : "", version : "0" };
}
var abc = getBroswer();
console.log("broswer:"+abc.broswer+" version:"+abc.version);
// broswer:Chrome version:71.0.3578.98
17. js裡常用的replace方法--string/正则我們容易忽略或者忘記的地方
var str11 = '小金:需要替換的地方:1.待替換1,2.待替換2,3.待替換3,4.待替換4,5.待替換5,6.待替換6,7.待替換7,'
var newStr11 = str11.replace('待替換', '替換過啦')
console.log(newStr11)
// 小金:需要替換的地方:1.替換過啦1,2.待替換2,3.待替換3,4.待替換4,5.待替換5,6.待替換6,7.待替換7,
// 從以上我們可以看出,只替換了第一個哦~~
let myReg = new RegExp('^' + escape('待替換'))
// .replace(/%/g, '\\')
console.log(myReg)
var newStr12 = str11.replace(new RegExp('待替換', 'g'), '替換過啦')
console.log("new RegExp('待替換', 'g')", newStr12)
// new RegExp('待替換', 'g') 小金:需要替換的地方:1.替換過啦1,2.替換過啦2,3.替換過啦3,4.替換過啦4,5.替換過啦5,6.替換過啦6,7.替換過啦7,
var res1 = str11.split('待替換').join('替換過啦')
console.log('split-join', res1)
// split-join 小金:需要替換的地方:1.替換過啦1,2.替換過啦2,3.替換過啦3,4.替換過啦4,5.替換過啦5,6.替換過啦6,7.替換過啦7,
结语
欢迎大家指出文章需要改正之处~
如果有更好的方法,欢迎大家提出来,共同进步哟~~
前端防错以及好用小tips指南总结的更多相关文章
- 前端必备,5大mock省时提效小tips,用了提前下班一小时
一.一些为难前端的业务场景 在我的工作经历里,需要等待后端童鞋配合我的情形大概有以下几种: a.我们跟外部有项目合作,需要调用到第三方接口. 一般这种情况下,商务那边谈合同,走流程,等第三方审核, ...
- 你不知道的JavaScript--Item17 循环与prototype最后的几点小tips
1.优先使用数组而不是Object类型来表示有顺序的集合 ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 但是在使用for..in循环对Object中的 ...
- 进阶篇:4.3)DFA设计指南:防错设计( 防呆设计)
本章目的:每一个装配步骤都有设计防错. 1.前言 关于防错设计,作者有想说的话: 1)防错设计是DFA重要的一条.因为太过重要,作者单独开一分章写! 2)只有理解了设计防错的重要,才会去设计防错特征. ...
- 小tips: zoom和transform:scale的区别
小tips: zoom和transform:scale的区别 转自 张鑫旭 前端大神 by zhangxinxu from http://www.zhangxinxu.com本文地址:http://w ...
- 关于请求接口报4XX错误,给广大前端同胞进行伸冤澄清,请相信它不一定都是前端的错
关于请求接口报4XX错误,给广大前端同胞进行伸冤澄清,请相信它不一定都是前端的错 首先确保接口没有写错,参数按照后台要的写,确保自己也没有写错,若页面还是报4xx错误,请站出来大胆的质疑后端,干什么吃 ...
- HTML meta锚点跳转 小tips
小tips meta锚点跳转 http://www.zhangxinxu.com/wordpress/2015/03/meta-http-equiv-refresh-content/
- Windows7驱动调试小Tips
v:* { } o:* { } w:* { } .shape { }p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-botto ...
- 小tips:JS之浅拷贝与深拷贝
浅拷贝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷贝: functio ...
- C#复习笔记(4)--C#3:革新写代码的方式(用智能的编译器来防错)
用智能的编译器来防错 本章的主要内容: 自动实现的属性:编写由字段直接支持的简单属性, 不再显得臃肿不堪: 隐式类型的局部变量:根据初始值推断类型,简化局部变量的声明: 对象和集合初始化程序:用一个表 ...
- keras搭建深度学习模型的一些小tips
定义模型两种方法: 1.sequential 类仅用于层的线性堆叠,这是目前最常用的网络架构 2.函数式API,用于层组成的有向无环图,让你可以构建任意形式的架构 from keras import ...
随机推荐
- 25.自定义mixin和基类
很多时候业务需求并不是几个简单的mixin就可以满足,需要我们自定义mixin # get_object源码中字段查询源代码 filter_kwargs = {self.lookup_field: s ...
- element-ui v-table 复选框默认选中
<el-table ref="refTable" :data="list" v-loading="listLoading" eleme ...
- SoringCloud(四) - 微信获取用户信息
1.项目介绍 2.微信公众平台 和 微信开放文档 2.1 微信公众平台 2.1.1 网址链接 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?ac ...
- FastApi学习1
先写路由文件: 其次通过ORM操作数据库相关:
- <四>虚函数 静态绑定 动态绑定
代码1 class Base { public: Base(int data=10):ma(data){ cout<<"Base()"<<endl; } v ...
- uniCloud云开发入门以及对传统开发方式的思考
事情缘由 作为选修了移动互联网应用的一员,老师讲的什么JS基础,还有ES6和uniapp,当然是没怎么听,因为是之前大二的时候都大概看过. 但是快到期末,老师讲了云开发,并且布置了与此相关的大作业,自 ...
- Windows server 2008 tomcat间歇性掉线关闭
1.代码没有问题,已经正常运行一年. 2.近期无更新代码. 3.tomcat 无运行报错. 今天突然间歇性掉线次数很多,客户不停反应情况,这边一时从代码开始找,我问了下在场运维其他服务器系统有无此现象 ...
- ArcObjects SDK开发 002 写第一个ArcObjects SDK程序
1.开发环境 基于ArcObjects SDK开发,开发环境一般选用Visual Studio,开发语言使用C#,开发包使用ArcObjects SDK for .Net.UI有的使用Winform, ...
- 通过启动脚本控制PHP-FPM开关
vi /etc/init.d/php-fpm 复制粘贴以下内容: #! /bin/sh# Comments to support chkconfig on CentOS# chkconfig: 234 ...
- 关于Qt的QPixmap中不支持jpg文件格式的问题
问题 Qt部分版本存在不支持jpg,JPEG等图像格式的问题 qDebug()<<QImageWriter::supportedImageFormats(); 这行代码可以查看所支持的图像 ...