(可贵从繁重的业务代码中抽身,更新一下文章)前端框架和技术日益发展,可是无论怎么变,js永远都是最重要的基础,本文记录和总结一些平常开发中常见的js代码技巧和误区,不按期更新。前端
后果:可能引入全局变量chrome
//错误的写法 var a = b = 0;
这段代码中,b实际上被声明为全局变量。由于操做符优先级是是从右往左,因此该语句至关于:segmentfault
var a = (b = 0)
此时b
未声明就被直接赋值,因此b
成了全局变量数组
var
原则这条规则的意思是,把函数内部的全部变量,放到顶部声明。好比:浏览器
//示例 function A(){ var a = 1, b = 2, c = a + b ; }
优势:缓存
关于第三点,这里举个例子说明:前端框架
var x = 1; function A(){ console.log(x);//第一处输出 ,注意结果 var x = 2; console.log(x);//第二处输出 2,没问题 }
从代码上看,第二处输出确定没问题,可能会有人认为第一处输出的是1,由于此时在函数内部还没声明变量x,根据做用域链,向外层查找的话,x值为1。可是实际输出的值应该是undefined
,由于js容许在函数任何地方声明变量,而且不管在哪里声明都等同于在顶部声明,这就是声明提高。因此上面的代码至关于:框架
var x = 1; function A(){ var x;//提高到顶部 console.log(x);//此时已声明 未赋值 x = 2;//赋值 console.log(x); }
for
循环时,缓存长度值一般用使用for
循环遍历数组时,会采用如下写法:dom
for(var i = 0;i<arr.length;i++){ // 具体操做 }
这段代码存在的问题在于,在循环的每一个迭代步骤,都必须访问一次arr
的长度。若是arr是静态数值还好,可是咱们在使用js
时可能会碰到arr
是dom元素对象,因为dom对象载页面下是活动的查询,这个长度查询就至关耗时,函数
//用len缓存长度值 for(var i = 0,len = arr.length;i<len;i++){ // 具体操做 }
按照上面的代码,咱们在第一次获取长度值时就缓存这个长度值,就能够避免上述问题。
for-in
时,增长hasOwnProperty()
判断for-in
一般用来枚举对象的属性和方法,可是这个方法会枚举范围包括对象和对象的原型对象(对原型对象不了解的能够看看我以前写的文章传送门)此时,利用hasOwnProperty()
方法能够帮咱们过滤出只在对象自己上的属性和方法,或者只在原型链的属性和方法
for(var key in obj){ if(obj.hasOwnProperty(key)){ // 对象自己的属性或者方法 } else{ // 原型链的属性和方法 } } /* 下面是一个具体的例子 */ function A(name){ this.type = 'A类'; this.name = name || '未命名' } var a = new A('a'); function B(name){ this.subtype = 'B类'; } // 创建原型链 B.prototype = a; B.prototype.sayHello = function(){} var b = new B(); // 遍历属性 for(var key in b){ //对象自身属性 if(b.hasOwnProperty(key)){ console.log('对象自身的属性或方法:'+key) } //上述表达式的另外一种写法 if(Object.prototype.hasOwnProperty.call(b,key)){ console.log('对象自身的属性或方法:'+key) } else { console.log('原型链的属性或方法:'+key) } }
===
代替==
这个算是比较常见的了,由于js在作比较判断时,会执行强制类型转换,好比false == 0
返回true
这样的状况,使用===
能够执行严格的等价比较,更易于阅读代码(后来阅读的人就不须要判断这个是遗漏仍是故意使用强制类型转换简写)
parseInt()
时,带上第二个参数。parseInt()
用于从字符串中获取数值,第二个参数表明进制,默认是10。咱们在使用的时候可能习惯性忽略这个参数,可是在一些状况下会有问题:当字符串的开头为0时,在es3里会被当作是八进制,es5里面仍然当作10进制,为了代码的一致性以及避免没必要要的失误,应该每次使用时都带上参数:
var x = parseInt('089',10);//使用时都带上进制参数
大括号的使用主要是2个方面:
for(var i =1;i<10 ;i++) console.log(i) //此处原则上能够忽略大括号
上述语句并无问题,可是若是后期函数体内增长了其余语句的时候,很容易忘记补上大括号,所以建议都带上大括号;
这个地方为何加粗了呢?由于这个问题很是容易被忽略,一般咱们都以为大括号是跟在语句的同一行仍是下一行只是习惯问题,可是实际上不是的!看下面这个例子:
function func(){ return { name:'xxx' } } var res = func() console.log(res)//输出undefined
是否是以为很奇怪,看代码第一感受应该是输出一个包含name
属性的对象。请注意,因为js的分号插入机制:若是语句没有使用分号结束,会自动补充分号,所以上面的代码实际至关于以下写法:
function func(){ return undefined;//自动插入分号 { name:'xxx' } }
正确的写法应该是:
function func(){ return { name:'xxx' } } var res = func() console.log(res)//输出{name:'xxx'}
(----------------------06.15更新------------------------)
在业务中常常会遇到相似对请求结果判断后读取的状况。好比:
requset().then(function(res){ if(res){ //对返回数据进行操做的代码 } else{ } })
这种写法没有问题,可是有时候逻辑比较长,嵌套的大括号比较多。此时能够采用另外一种写法
requset().then(function(res){ // 先判断!res if(!res){ /// } //对返回数据进行操做的代码 })
这种写法能够减小一次嵌套,在逻辑判断较多时,嵌套层数减小能够增长代码可读性。
(----------------------06.20更新------------------------)
此条主要是在这两天修复一个遗留bug时候发现,一个上传组件在ie下失效,其中一个缘由是上传的请求url参数中包含中文参数,可是未手动encodeURI
,原先的开发者可能只考虑了chrome下的状况。因为chrome会自动对url进行encode,因此很容易忽略其余浏览器,为了不此类的兼容问题,建议老是手动作好编码处理。
(----------------------08.16更新------------------------)
先上代码:
function X() { } //原型上的属性 X.prototype.age = '22' var x = new X() Object.defineProperty(x, 'name', { enumerable: false, value: '张三' }) console.log(x) //方法1 使用for...in遍历 function isEmptyObject1(obj) { for (var attr in obj) { return false } return true } //方法2 使用JSON.stringify function isEmptyObject2(obj) { return (JSON.stringify(obj) === '{}') } //方法3 使用Object.keys function isEmptyObject3(obj) { return Object.keys(obj).length === 0 } //方法4 使用getOwnPropertyNames function isEmptyObject4(obj) { return Object.getOwnPropertyNames(obj).length === 0 } console.log(isEmptyObject1(x)) //true console.log(isEmptyObject2(x)) //true console.log(isEmptyObject3(x)) //true console.log(isEmptyObject4(x)) //false
(----------------------2019.01.17更新------------------------)
// 1.使用数组方式传参,须要严格按照参数顺序,而且对于多个可选参数的状况很差处理 const getMethod = (id,uid,option1,option2)=>{ const config = { // 参数处理 } request.get(config) } // 若是此时可选参数1不传,却要传入可选参数2,则必须传入空值占位 getMethod('e3ruewruwieru','231423asd',null,'asdasd') // 2. 使用对象传参时,能够不按照顺序传入参数 const getMethod = (query) =>{ const { id, uid, option1,option2} = query //直接解构出须要的参数 const config = { option1:option1 ||'' //即便多个可选参数,处理起来也很方便 } request.get(config) } // 使用比较灵活 而且不用考虑参数顺序 const query = { id:'123', uid:'asd', option2:'goodjob' } getMethod(query)
本文会长期更新和补充(若是我没被淹没在业务中的话),欢迎读者提出建议和意见。
而后依然是每次都同样的结尾,若是内容有错误的地方欢迎指出;若是对你有帮助,欢迎点赞和收藏,转载请征得赞成后著明出处,若是有问题也欢迎私信交流,主页添加了邮箱地址~溜了