不定期更新 JavaScript 技巧

阅读 8182
收藏 617
2017-02-06
原文链接:rockjins.js.org

 JavaScript技巧,偶尔更新。

计算数组的极值

function smallest(array){                         
  return Math.min.apply(Math, array);             
}                                                 

function largest(array){                          
  return Math.max.apply(Math, array);             
}  

smallest([0, 1, 2.2, 3.3]); // 0

largest([0, 1, 2.2, 3.3]); // 3.3

迭代arguments

function useCall() {
    [].forEach.call(arguments, function(val, key) {
        console.log(key, val)
    });
}

useCall('Bob Dylan', 'Bob Marley', 'Steve Vai');

//0 "Bob Dylan"
//1 "Bob Marley"
//2 "Steve Vai"

Array.prototype.forEach()第二个参数

参考:MDN

var coder = {
  name: 'Shock',
  friends: ['Rocky', 'Bob'],
  logHiToFriends:function(){
    'use static'
    this.friends.forEach(function(friend){
      console.log(this.name+ ' say hi to '+ friend);
    },this)//注意这个this,如果不添加这个参数,你可以猜测会发生什么
  }
}

使用IIFE解决循环问题

unexpected:

var funcs = [];

for (var i = 0; i < 10; i++) {
    funcs.push(function() { console.log(i); });
}

funcs.forEach(function(func) {
    func();     // 输出数值 "10" 十次
});

expected:

var funcs = [];

for (var i = 0; i < 10; i++) {
    funcs.push((function(value) {
        return function() {
            console.log(value);
        }
    }(i)));
}

funcs.forEach(function(func) {
    func();     // 从 0 到 9 依次输出
});

使用let解决循环问题

这是let独有的特性(参考)

var funcs = [];

for (let i = 0; i < 10; i++) {
    funcs.push(function() {
        console.log(i);
    });
}

funcs.forEach(function(func) {
    func();     // 从 0 到 9 依次输出
})

判断两个小数是否相等

//因为javascript数字通常被输入为十进制的浮点数,但内部却被表示为二进制,所以计算结果会有偏差:

0.1 + 0.2 //0.30000000000000004

0.1 + 1 - 1 //0.10000000000000009

0.1 + 0.2 === 0.3 //false

//所以我们不应该直接比较非整数,而是取其上限,把误差计算进去
//这样一个上限称为 machine epsilon,双精度的标准epsilon值是2^-53

const EPSILON = Math.pow(2, -53); //1.1102230246251565e-16

function epsEqu(x,y) {
  return Math.abs(x - y) < EPSILON;
}

epsEqu(0.1+0.2, 0.3) //true

Math.round函数的坑

Math.round(-3.2) //-3

Math.round(-3.5) //-3(这个就奇怪了)

Math.round(-3.8) //-4

//其实,Math.round(x)等同于:
Math.floor(x + 0.5)

巧用||和&&

var bar = $ || 233;
//如果$存在,则把$赋值给bar;如果$不存在,则把233赋值给bar

$ === undefined && (window.$ =  jQuery);  
//如果$不存在,则把jQuery赋值给window.$;如果$存在,则不执行后面的表达式

使用break + labels退出循环

function findNumber(arr){
  loop:{
    for (var i = 0; i < arr.length; i++) {
      if(arr[i]%2 == 0){
        break loop;//表示退出loop区块
      }
    }
    console.log(arr);//这句代码是不会执行的,如果上面只是break,for循环之后的代码还是会执行
  }
}

findNumber([1,3,5,6]);

简单实现合并对象

function merge(root){
  for (var i = 1; i < arguments.length; i++) {
    for (var key in arguments[i]) {
      if (object.hasOwnProperty(key)) {
        root[key] = arguments[i][key];
      }
    }
  }
  return root;
}

var merged = merge(
  {name:'Shock'},
  {city:'Shenzhen'}
)//{name:'Shock',city:'Shenzhen'}

理解map和parseInt

['1','2','3'].map(parseInt);
//[1, NaN, NaN]

['1','2','3'].map(function(x){return parseInt(x,10)});
//[1, 2, 3]

上传图片预览功能

<input type="file" name="file" onchange="showPreview(this)" />
<img id="portrait" src="" width="70" height="75">
function showPreview(source) {
  var file = source.files[0];
  if(window.FileReader) {
      var fr = new FileReader();
      fr.onloadend = function(e) {
        document.getElementById("portrait").src = e.target.result;
      };
      fr.readAsDataURL(file);
  }
}

微信内部修改document.title

function setTitle(title) {
  document.title = title;
  if (/ip(hone|od|ad)/i.test(navigator.userAgent)) {
    var i = document.createElement('iframe');
    i.src = '/favicon.ico';
    i.style.display = 'none';
    i.onload = function() {
      setTimeout(function(){
        i.remove();
      }, 9)
    }
    document.body.appendChild(i);
  }
}

setTitle("要修改的标题");

快速克隆一个对象

var Rocker = function(name, age){
  this.name = name,
  this.age = age
}

var shock = new Rocker('Shock', 24);

shock.age = 99;

var cloneShock = Object.create(shock);

cloneShock.name // "Shock"
cloneShock.age // 99

//在不支持ES5的浏览器下,实现create方法如下:

Object.create = Object.create || function(obj){
  var F = function(){};
  F.prototype = obj;

  return new F();
}

判断一个值是否是对象

function isObject(value){
  return value === Object(value);
}

isObject({}); // true
isObject(123);  // false

本文出自Rockjins Blog,转载请与作者联系。否则将追究法律责任。

评论