积累

Object.assign()

//浅拷贝
    

Symbol()

//ES6引入了一个新的内置类Reflect,它的ownKeys方法可以识别出所有属性名
var s = Symbol();
var s1 = Symbol('s1');

var obj = {
    [s]: function() {
        console.log(1);
    },
    [Symbol()]: () => {
        console.log(2);
    },
    [s1]: 3,
    a: 4
};


Reflect.ownKeys(obj).forEach(function(item) {
    if (typeof obj[item] === 'function') {
        obj[item]();
    } else {
        console.log(obj[item]);
    }
});

stringObj.trim()

/*
*params: 
* stringObj: 必选。String对象或字符串。trim方法不修改字符串
*返回值:
* 已移除前导空格、尾随空格和行终止符的原始字符串(移除的字符包括空格、制表符、换页符、回车符和换行符。)
*/
var message="   abc def  \r\n";

document.write("["+message.trim()+"]");
document.write("</br>");
document.write("length"+message.trim().length);

//Output:
// [abc def]
// length:7

JavaScript trim函数大赏

/*stringObj.trim()源码实现*/
//实现1,速度惊人
String.prototype.trim = fucntion() {
    return this.replace(/^\s\s*/,'').replace(/\s\s*$/,'');
}
//实现2,和实现1很相似,但稍慢一点,主要原因是它最先是假设至少存在一个空白符
String.prototype.trim = function() {
    return this.replace(/^\s+/,'').replace(/\s+$/,'')
}
/*
实现3,以截取方式取得空白部分(当然允许中间存在空白符),总共调用了四个原生方法。设计得非常巧妙,substring以两个数字作为参数。Math.max以两个数字作参数,search则返回一个数字。速度比上面两个慢一点,但比下面大多数都快。
*/
String.prototype.trim = function() {
    return this.substring(Math.max(this.search(/\S/),0),this.search(/\S\s*$/)+1);
}
//实现4,这个可以称得上实现2的简化版,就是利用候选操作符连接两个正则。但这样做就失去了浏览器优化的机会,比不上实现3。由于看来很优雅,许多类库都使用它,如JQuery与mootools
String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, '');
}
/*
实现5,match是返回一个数组,因此原字符串符合要求的部分就成为它的元素。为了防止字符串中间的空白符被排除,我们需要动用到非捕获性分组(?:exp)。由于数组可能为空,我们在后面还要做进一步的判定。好像浏览器在处理分组上比较无力,一个字慢。所以不要迷信正则,虽然它基本上是万能的。
*/
String.prototype.trim = function() {
    var str = this;
    str = str.match(/\S+(?:\s+\S+)*/);
    return str ? str[0] : '';
}

对对象判空

/*
*params:
* 非Array的Obj
*返回数据:
* 如果是空的对象,返回true,否则返回false或者“不是期待的Obj”
*/
function objIsNull(obj) {
    if(typeof(obj) === 'object' && !(obj instanceof Array) {
        var obj_name;
        for (obj_name in obj) {
            return false;
        }
        return true
    })else {
        return "不是期待的Obj"
    }
}
//如果是空对象不会进入 for in 循环中,即如果传入的是非空对象,立即返回 false
    var obj_name;
    for (obj_name in obj) {
        return false;
    }

获取url的查询参数,并将其改造成对象

no-return-assign

ESlint 检测工具

localStorage&&sessionStorage

简介

html5 中的 web Storage 包括了两种存储方式:sessionStorage 和 localStorage。 sessionStorage 用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问,会话结束后数据也随之销毁。localStorage 用于存储一个域名下的需要永久存在在本地的数据,这些数据可以被一直访问,直到这些数据被删除。
因此sessionStorage 和 localStorage 的主要区别在于他们存储数据的生命周期,sessionStorage 存储的数据的生命周期是一个会话,而 localStorage 存储的数据的生命周期是永久,直到被主动删除,否则数据永远不会过期的。

区别

相同点
  • localStroage和sessionStroage是相似的
不同点
  • 生命周期不同,localStroage的生命周期是永久,数据在localStorage中是可以无限期保存的;sessionStroage的生命周期是一个会话,会话结束时会清除sessionStorage中保存的数据

API

localStorage.getItem()
localStorage.setItem()
localStorage.removeItem()
localStorage.clear()

sessionStorage.getItem()
sessionStorage.setItem()
localStorage.removeItem()
localStorage.clear()

example

  • 添加键值对:localStorage.setItem(key, value)setItem 用于把值 value 存储到键key上,除了使用 setItem ,还可以使用 localStorage.key = value 或者 localStorage['key'] = value 这两种形式。另外需要注意的是,key和value值必须是字符串形式的,如果不是字符串,会调用它们相应的toString() 方法来转换成字符串再存储。当我们要存储对象是,应先转换成我们可识别的字符串格式(比如JSON格式)再进行存储。
    localStorage.setItem('name','linjianran')
    //localStorage.name = 'linjianran'
    //localStorage['name'] = 'linjianran'
    //把一个用户存储在user的键上
    localStorage.setItem('user', JSON.stringify(id:1,name:'linjianran'))
  • 获取键值:localStorage.getItem(key)getItem 用于获取键 key 对应的数据,和 setItem 一样,getItem 也有两种等效形式 value = localStorage.key和 value = localStorage['key'] 。获取到的 value 值是字符串类型,如果需要其他类型,要做手动的类型转换。
    let name = localStorage.getItem('name')
    //let name = localStorage.name
    //let name = localStorage['name']
    //获取存储到user的键上的值
    let user = JSON.parse(localStorage.getItem('user'));
  • 删除键值对:localStorage.removeItem(key)removeItem 用于删除指定键的项,localStorage 没有数据过期的概念,所有数据如果失效了,需要开发者手动删除。
let name = localStorage.getItem('name') //'linjianran'
localStorage.removeItem('name')
name = localStroage.getItem('name') //null
  • 清除所有键值对:localStorage.clear() 用于删除所有存储的内容,它和removeItem不同的地方是removeItem 删除的是某一项,而clear是删除所有。
localStorage.clear()
let length = localStorage.length // 0
  • 获取 localStorage 的属性名称(键名称):localStorage.key(index)key 方法用于获取指定索引的键名称。需要注意的是赋值的早晚对键值对应的索引值无影响,索引值按键值名称做升序排列,key方法可用于遍历 localStorage 存储的键值。
localStorage.setItem('aKey1','aValue')
localStorage.key(0) // aKey1
localStorage.setItem('bKey','bValue')
localStorage.key(1) // bKey
localStorage.setItem('aKey2','aValue')
localStorage.key(0) // aKey1
localStorage.key(1) // aKey2
localStorage.key(2) // bKey
  • 获取loaclStorage中保存的键值对的数量:localStorage.length length 属性用于获取localStorage中键值对的数量
localStorage.setItem('aKey1','aValue')
localStorage.length // 1
localStorage.setItem('bKey','bValue')
localStorage.length // 2

下面的示例会自动保存一个文本输入框的内容,如果浏览器因偶然因素被刷新了,文本输入框里面的内容会被恢复,因此写入的内容不会丢失。

//获取文本输入框
let field = document.getElementById('field')

//检测是否存在autosave键值
//(这个会在页面偶然被刷新的情况下存在)
if (sessionStorage.getItem('autosave')) {
    //恢复文本输入框的内容
    field.value = sessionStorage.getItem('autosave')
}

//监听文本输入框的 change 事件
field.addEventListener("change",function() {
    // 保存结果到 sessionStorage 对象中
    sessionStorage.setItem('autosave', field.value)
})

Web Storage 事件

  • storage 事件当存储的数据发生变化时,会触发 storage 事件。但要注意的是它不同于click类的事件会事件捕获和冒泡,storage 事件更像是一个通知,不可取消。触发这个事件会调用同域下其他窗口的storage事件,不过触发storage的窗口(即当前窗口)不触发这个事件。storage 的 event 对象的常用属性如下:
  oldValue:更新前的值。如果该键为新增加,则这个属性为null。
  newValue:更新后的值。如果该键被删除,则这个属性为null。
  url:原始触发storage事件的那个网页的网址。
  key:存储store的key名
    function storageChanged() {
        console.log(arguments);
    }

    window.addEventListener('storage', storageChanged, false);

时间戳和date对象相互转换

将Date对象转换成时间戳

  • 使用Number()
    let newDate = new Date()
    // 返回当前时间的时间戳
    Number(newDate)
  • 使用Date.parse()
    let newDate = new Date()
    // 返回当前时间戳
    Date.parse(newDate)
  • 利用转义符进行转义
    // 使用“+”对时间对象进行转义
    let newDate = +new Date()

将时间戳转换为Date对象

  • 实例化一个Date对象,并将13位的时间戳传入
    //let newDate = new Date(1538148600000)
    let newDate = new Date(时间戳)
  • 使用Date.setTime(),设置Date对象的时间为时间戳的时间
    // 时间戳
    let timestamp = 1538148600000
    // 实例一个时间戳对象
    let newDate = new Date()
    // 设置Date对象的时间为时间戳的时间
    newDate.setTime(tiemstamp)

实例1:格式化时间戳

将时间戳转换为日期,时间格式为:'yyyy-MM-dd hh:mm:ss'
1...9 属性 (RegExp) (JavaScript)

/*
* value为时间戳,fmt为时间格式('yyyy-MM-dd hh:mm:ss')
* @param { Number | Date } value
* @param { String } fmt
* 格式化完成的时间
* @return { String } fmt 
*/
const dateFmt = (value, fmt) => {
    if(typeof value !== undefined) {
        value = new Date(value)
        const fmtObj = {
            'M+': value.getMonth() + 1, // 月份
            'd+': value.getDate(), // 日期
            'h+': value.getHours(), // 小时
            'm+': value.getMinutes(), // 分钟
            's+': value.getSeconds(), // 秒
            'q+': Math.floor((value.getMonth() + 3) / 3), //季度
            'S': value.getMilliseconds() // 毫秒
        }
        if (/(y+)/.test(fmt)) {
            // fmt = fmt.replace(Reg.Exp.$1,(value.getFullYear() + '').substr(4 - RegExp.$1.length));
            fmt = fmt.replace(/(y+)/, (value.getFullYear() + '').substr(4 - RegExp.$1.length))
        }
        for (let key in fmtObj) {
            let regExp = new RegExp('(' + key + ')')
            if (regExp.test(fmt)) {
               //fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (fmtObj[key]) : (('00' + fmtObj[key]).substr(('' + fmtObj[key]).length)))
               fmt = fmt.replace(regExp, (RegExp.$1.length === 1) ? fmtObj[key] : (('00' + fmtObj[key]).substr(('' + fmtObj[key]).length)))
            }
        }
        return fmt
    }
}

const fmt = "yyyy-MM-dd hh:mm:ss"
const timestamp =  1538148600000
const date = dateFmt(timestamp, fmt) // "2018-09-28 23:30:00"

实例2:计算两个时间戳或 Date对象 相隔多少天

/*
* 计算time1和time2相隔时间,精确到‘日’
* @param { String | Date } time1
* @param { String | Date } time2
* @return { Number } (time2 - time1) / (24 * 60 * 60 * 1000)
*/

const diffDay = function (time1, time2) {
    // 如果 time1 或者 time2 不是Date对象则将其转换为Date对象
    const time1 = time1 instanceof Date ? time1 : new Date(time1)
    const time2 = time2 instanceof Date ? time2 : new Date(time2)
    
    time1.setHours(0)
    time1.setMinutes(0)
    time1.setSeconds(0)
    time1.setMilliseconds(0)
    time2.setHours(0)
    time2.setMinutes(0)
    time2.setSeconds(0)
    time2.setMilliseconds(0)
    
    /*
    *如果是负数说明 time2 比 time1 早。如 -1,则说明早了一天,即 time1 是今天,则 time2 是昨天。
    *如果是正数说明 time2 比 time1 晚。如1,则说明晚一天,即 time1 是今天,则 time2 是明天。
    */
    return (time2 - time1) / (24 * 60 * 60 * 1000)
}

实例3:将时间戳或者Date对象转换为对应的日期

/*
* 计算 value 的日期,返回值可能为“昨天 00:00”,“今天 00:00”,“明天 00:00”,
* “**月**日 00:00”,“****年**月**日 00:00”,精确到分钟
* @param { String | Date } value
* @return { String } result
*/

const moment = (value) => {
    if(typeof value !== undefined) {
        const today = new Date()
        let result = ''
        value = value instanceof Date ? value : new Date(value)
        // 调用实例2的diffDay()方法
        const diff = diffDay(today, value)
        // 设置日期
        if (diff === -1) {
            result = '昨天'
        } else if (diff === 0) {
            result = '今天'
        } else if (diff === 1) {
            result = '明天'
        } else if (Math.abs(diff) >= 365) {
            result = value.getFullYear() + '年' + (value.getMonth() + 1) + '月' + value.getDate() + '日'
        } else {
            result = (value.getMonth() + 1) + '月' + value.getDate() + '日'
        }
        // 设置小时和分钟
        let hours = value.getHours()
        let minutes = value.getMinutes()
        hours = hours >= 10 ? hours : '0' + hours
        minutes = minutes >= 10 ? minutes : '0' + minutes;
        result += ' ' + hours + ':' + minutes
        
        return result
    } else {
        return false    
    }
}

// 传入时间戳 1538148600000
let result = moment(1538148600000) // "9月28日 23:30" 

RegExp.1-9

非标准1,2, 3,4, 5,6, 7,8, $9 属性是包含括号子串匹配的正则表达式的静态和只读属性。(该特性是非标准的,请尽量不要在生产环境中使用它!)

语法

// RegExp.$_,与正则表达式匹配的完整字符串。
RegExp.$_
// RegExp.$n,(n为1-9之间的数值)指的是与正则表达式匹配的第n个子匹配(以括号为标志)字符串
RegExp.$1
RegExp.$2
RegExp.$3
RegExp.$4
RegExp.$5
RegExp.$6
RegExp.$7
RegExp.$8
RegExp.$9

描述

  • 1, ...,9 属性是静态的, 他不是独立的的正则表达式属性. 所以, 我们总是像这样子使用他们RegExp.1, ..., RegExp.9.
  • 属性的值是只读的而且只有在正确匹配的情况下才会改变.
  • 括号匹配项是无限的, 但是RegExp对象能捕获的只有九个. 你可以通过返回一个数组索引来取得所有的括号匹配项.
  • 这些属性可以在String.replace 方法中替换字符串. 在这种情况下,不用在前面加上RegExp。下面的例子将详细说明. 当正则表达式中不包含括号, 脚本中的 $n's 就是字面上的意思 (当n是正整数).

例子

使用replace()去匹配一个 first last 格式的 name String 实例,然后输出 last first 格式。在替换文本中,用 1** 和 **2 表示正则表达式中括号匹配项的结果。

let regExp = /(\w+)\s(\w+)/
let str = 'Jianran Lin'
str.replace(regExp, '$2 '+ '$1') // "Lin Jianran"
console.log(RegExp.$1) // "Jianran"
console.log(RegExp.$2) // "Lin"

技术指标

非标准,不属于当前的任何规范

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343