【二十二】javascript高级技巧

高级函数

安全的类型检测,检测是原生对象还是自定义对象

Object.prototype.toString 返回构造函数名

var arr = [];
console.log(Object.prototype.toString.call(arr));//[object Array] 

作用域安全的构造函数

function Person(name, age) {
    if(this instanceof Person){
        this.name = name;
        this.age = age;
    }else {
        return new Person(name, age);
    }
}

这样做存在的问题:当使用构造函数模式实现继承时,由于作用域安全,所以继承不能实现。

function Super(name) {
    if(this instanceof Super) {
        this.name = name;
    }else {
        return new Super(name);
    }
}
function Sub(name, age) {
    Super.call(this, name);
    this.age = age;
}
var sub = new Sub("sub", 21);
console.log(sub.name);//undefined

为解决这个问题,可以结合原型链用组合模式实现继承,为上述代码添加: Sub.prototype = new Super();

惰性载入函数

包含大量if的语句,每次调用时分支结果都不变,如果能减少if的执行会加快速度。惰性载入函数就解决方案。
两种方式:
* 在函数被调用时处理函数
* 在声明函数时就指定适当的函数。

函数绑定

bind

函数柯里化

使函数参数单一化


防止篡改对象

  1. 不可扩展对象
    不能给对象添加新成员,但是对已有成员不影响
    Object.preventExtensions(); //禁止再给对象添加属性
    Object.isExtensible();//判断对象是否可扩展
  2. 密封对象
    被密封的对象不可扩展,且密封对象不可删除属性,[[Configureable]]设置成false
    Object.seal();
    Object.isSealed();
  3. 冻结对象
    冻结对象既是不可扩展的,又是密封的,对象数据属性[[Writable]]被设置false
    Object.freeze();

定时器

指定的时间间隔表示何时将定时器的代码添加到队列,而不是何时执行代码

  1. setTnterval()存在的问题是:定时器代码可能在代码再次添加到队列之前还没有完成执行,导致定时器代码连续运行多次,之间没有间隔。
  2. javascript引擎避免了这个问题:当使用setInterval时,仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中。

  3. 但是setInterval()重复定时器仍然存在的两个问题:

    • 某些间隔会被跳过
    • 多个定时器的代码执行之间的间隔会比预期小
  4. 解决上述问题的方案:使用链式setTimeout()
setTimeout(function() {
    // code 
    // arguments.callee获取当前执行的函数的引用
    setTimeout(arguments.callee, 200);
}, 200);

函数节流

var processor = {
    timeoutId: null,
    method: function() {
        console.log("sad");
    },
    process: function()  {
        clearTimeout(this.timeoutId);
        var that = this;
        this.timeoutId = setTimeout(function() {
            that.method();
        }, 100);
    }
}

for(var i = 0;i < 100;i++) {
    processor.process();
}

最后一次调用process()之后至少100ms后才会调用method()。所以100ms内调用process()100次,method()仍然只会调用一次。

// 简化
function throttle(method) {
    clearTimeout(method.tid);

    method.tid = setTimeout(function() {
        method();
    }, 100);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值