javascript 高级写法

一、安全类型检测

1、比较基础的方案(instanceof)
let data = [1]
console.log(data instanceof Array) // true

对于typeof

2、强行转义
let data = [1]
Object.prototype.toString.call(data) === '[objectd Array]'

*注意:*使用call,非直接调用,call的第一个参数是context执行上下文,把数组传入作为执行上下文(this)

3、es6 类检测
class Person{}
toString.call(Person) // [object function]
toString.call(new Person()) // [object Object]

class是使用function实现,也就是说class == function

二、惰性载入函数

在代码中做一些兼容性判断,做一些ua的判断

包括做函数、类存在的判断,都可以借鉴

//UA的类型
getUAType: function() {
    let ua = window.navigator.userAgent;
    if (ua.match(/renren/i)) {
        return 0;
    }
    else if (ua.match(/MicroMessenger/i)) {
        return 1;
    }
    else if (ua.match(/weibo/i)) {
        return 2;
    }
    return -1;
}

三、函数绑定

其实就是在类中尽量去改变执行上下文,减少this改变导致执行出错

  • bind不会立即调用,而是返回一个新的函数,称为绑定函数,this指向的是第一个参数,第二个及以后的参数作为原函数的参数进行调用
  • apply和call都是为了改变某个函数(内部this的指向)运行时而存在的,调用返回的是执行结果;第一个参数改变this
    • apply第二个参数为数组
    • call第二个参数及其后的参数都是变量,非数组

四、柯里化

柯里化就是函数与参数结合产生一个新的函数,重点就是需要返回一个函数,也就是链式调用

Function.prototype.curry = function() {
    let slice = Array.prototype.slice;
    let defaultArgs = slice.call(arguments);
    let that = this;
    return function() {
        return that.apply(this,defaultArgs.concat(slice.call(arguments)));    
    }
};

五、防止篡改对象

1、Object.seal防止新增和删除属性:
let person = {}
Object.seal(person)
delete person.name
person.age = 12

非严格模式不会抛异常,但是执行无效;严格模式下会抛异常:
在这里插入图片描述

2、Object.freeze冻结对象

同时可以使用Object.isFrozen、Object.isSealed、Object.isExtensible判断当前对象的状态。

let person = {}
Object.freeze(person)
delete person.name
person.age = 12

执行会抛异常

3、defineProperty冻结单个属性
let person = {}
Object.defineProperty(person,'age', {
	enumerable: false, // 不能枚举、遍历
	writable: false, // 不能进行编辑,写入
	value: 12
})

六、函数节流throttle

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
场景:

  • 监听input触发搜索
  • 监听resize做响应式调整
  • 监听mousemove调整位置

节流两种形式:时间戳版和定时器版。
时间戳版:

function throttle(func, wait) {
    let previous = 0;
    return function() {
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}

定时器版:

function throttle(func, wait) {
    let timeout;
    return function() {
        let context = this;
        let args = arguments;
        if (!timeout) {
            timeout = setTimeout(() => {
                timeout = null;
                func.apply(context, args)
            }, wait)
        }
    }
}

七、函数防抖deboucing

所谓防抖,指的是在触发事件后,n秒内函数只响应一次,如果在n秒内重复触发,则会重新计算函数执行时间
场景:

  • 滚动
  • 暴击

防抖两种形式:前缘响应(立即执行)和后缘响应(非立即执行)。

  • 前缘响应:事件第一次触发时响应;倒计时一段时间内不会响应,并且如果在此时间内再次触发,会重置倒计时
  • 后缘响应:在事件第一次触发后开始倒计时,如果这段时间没有触发,则响应,否则,重置倒计时

非立即执行:

function debounce(func, wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait);
    }
}

立即执行:

function debounce(func,wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;
        if (timeout) clearTimeout(timeout);
        let callNow = !timeout;
        timeout = setTimeout(() => {
            timeout = null;
        }, wait)

        if (callNow) func.apply(context, args)
    }
}

合并立即和非立即双剑合璧:

/*
* immediate: true立即,false为非立即
*/
function debounce(func,wait, immediate) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;
        if (timeout) clearTimeout(timeout);
        if(immediate) {
        	let callNow = !timeout;
	        timeout = setTimeout(() => {
	            timeout = null;
	        }, wait)
	        if (callNow) func.apply(context, args)
        } else {
        	timeout = setTimeout(() => {
	            timeout = null;
	        }, wait)
        }
    }
}

技术分享,希望大家能共同进步,共同学习,如果我有那部分分析错了,麻烦不要珍惜你的金口良言,使劲怼,日天日地才是好朋友

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值