js代码常见技巧总结

写在前面

(难得从繁重的业务代码中抽身,更新一下文章)前端框架和技术日益发展,但是不管怎么变,js永远都是最重要的基础,本文记录和总结一些日常开发中常见的js代码技巧和误区,不定期更新。

https://segmentfault.com/a/1190000015269270

正文

1. 避免链式声明

后果:可能引入全局变量

    //错误的写法
    var a = b = 0;

这段代码中,b实际上被声明为全局变量。因为操作符优先级是是从右往左,所以该语句相当于:

var a = (b = 0)

此时b未声明就被直接赋值,所以b成了全局变量

2. 单一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);
  }  

3. 使用for循环时,缓存长度值

通常用使用for循环遍历数组时,会采用以下写法:

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++){
 // 具体操作
}

按照上面的代码,我们在第一次获取长度值时就缓存这个长度值,就可以避免上述问题。

4. 使用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(B.prototype.hasOwnProperty.call(b,key)){
    console.log('对象自身的属性或方法:'+key)
  }
  else {
    console.log('原型链的属性或方法:'+key)
  }
}

5. 使用===代替==

这个算是比较常见的了,因为js在做比较判断时,会执行强制类型转换,比如false == 0返回true这样的情况,使用===可以执行严格的等价比较,更易于阅读代码(后来阅读的人就不需要判断这个是遗漏还是故意使用强制类型转换简写)

6. 使用parseInt()时,带上第二个参数。

parseInt()用于从字符串中获取数值,第二个参数代表进制,默认是10。我们在使用的时候可能习惯性忽略这个参数,但是在一些情况下会有问题:当字符串的开头为0时,在es3里会被当做是八进制,es5里面仍然当做10进制,为了代码的一致性以及避免不必要的失误,应该每次使用时都带上参数:

var x = parseInt('089',10);//使用时都带上进制参数

7. 大括号的使用

大括号的使用主要是2个方面:

  • 第1,不要省略大括号,即使可以忽略,比如:
for(var i =1;i<10 ;i++)
    console.log(i) //此处原则上可以忽略大括号

上述语句并没有问题,但是如果后期函数体内增加了其他语句的时候,很容易忘记补上大括号,因此建议都带上大括号;

  • 第2,大括号的必须跟在前一个语句的同一行

这个地方为什么加粗了呢?因为这个问题非常容易被忽略,通常我们都觉得大括号是跟在语句的同一行还是下一行只是习惯问题,但是实际上不是的!看下面这个例子:

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'}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值