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"
将arguments转为数组
function transformToArray(arg){
return Array.prototype.slice.call(arg);
}
Array.prototype.forEach()第二个参数
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,如果不添加这个参数,你可以猜测会发生什么
}
}
随机生成字母和数字组合的字符串
Math.random().toString(36).substr(2);
//un80usvvsgcpi0rffskf39pb9
//02aoe605zgg5xqup6fdclnb3xr
//ydzr1swdxjg3yolkb95p14i
使用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
为构造器模拟apply功能
if(!Function.prototype.construct){
Function.prototype.construct = function(argArray){
if(!Array.isArray(argArray)){
throw new TypeError("Arguments must be an array");
}
var constr = this;
var nullaryFunc = Function.prototype.bind.apply(
constr,[null].concat(argArray));
return new nullaryFunc();
}
}
//使用:
Date.construct([2017, 02, 14]); // Tue Mar 14 2017 00:00:00 GMT+0800 (CST)