前端防错以及好用小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 ...
随机推荐
- Mybatis笔记02-----MyBatis的核心配置文件以及模糊查询的实现
认识MyBatis核心配置文件mybatis-config.xml 这个文件名是随意可以起,但为了规范一般都命名为mybatis-config.xml:配置文件与MyBatis的行为和属性信息息息相关 ...
- django启动报错:DisallowedHost at /
学习django第一天,第一次启动服务就报错,报错内容如下: DisallowedHost at / Invalid HTTP_HOST header: '192.168.116.22:8000'. ...
- C语言实验手册
在三位整数(100~999)中寻找符合条件的整数,并以此从小到大存到数组当中,它既是完全平方数,又是两位数字相同,例如144,676等. #include<stdio.h> #includ ...
- 链接脚本(Linker Scripts)语法和规则解析(自官方手册)
为了便于与英文原文对照学习与理解(部分翻译可能不准确),本文中的每个子章节标题和引用使用的都是官方手册英文原称.命令及命令行选项统一使用斜体书写.高频小节会用蓝色字体标出. 3 Linker Scri ...
- .NET 7 的 AOT 到底能不能扛反编译?
一:背景 1.讲故事 在B站,公众号上发了一篇 AOT 的文章后,没想到反响还是挺大的,都称赞这个东西能抗反编译,可以让破解难度极大提高,可能有很多朋友对逆向不了解,以为用 ILSpy,Reflect ...
- Solon v1.11.0 发布,Hello Java
一个更现代感的 Java 应用开发框架:更快.更小.更自由.没有 Spring,没有 Servlet,没有 JavaEE:独立的轻量生态.主框架仅 0.1 MB. @Controller public ...
- 解决linux mint内置无线网卡失效问题
前言 同学安装了linux mint,但是内置的无线网卡失效,只能通过有线网卡连接,经过查询得到不是缺少驱动的问题,是内核不支持 解决办法 sudo apt install linux-generic ...
- 前后端分离开发工具YAPI部署记录
之前公司说要建立起前后端分离开发模式,而我只是刚毕业,让我负责建立起这个规范 ,虽然刚毕业还没去大厂待过,对我来说是个挑战,只能按我理解和网上的方案进行建立.在 Google 和 github 搜了好 ...
- 14 STL-常用算法
重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦! 每一次学习都是为了追求智慧! 写在前面,本篇章主要介绍STL中常用算法. 算法主要由 ...
- Day29 Linux相关命令的使用
今日内容 基本概念 安装 基本命令 在linux上安装软件 jdk mysql jdk Nginx的安装 一.概述 1.Unix linux基于Unix,Unix由贝尔实验室在1969年开发 一开始由 ...