资讯专栏INFORMATION COLUMN

JavaScript 高级技巧

wean / 406人阅读

摘要:如果直接调用构造函数,那么会指向全局对象然后你的代码就会覆盖的原生。冻结对象最严格的防篡改就是冻结对象。中央定时器动画地址参考书籍高级程序设计忍者秘籍

1 安全类型检测

javascript内置类型检测并不可靠

safari某些版本(<4)typeof正则表达式返回为function

建议使用Object.prototype.toString.call()方法检测数据类型

    function isArray(value){
        return Object.prototype.toString.call(value) === "[object Array]";
    }
    
    function isFunction(value){
        return Object.prototype.toString.call(value) === "[object Function]";
    }
    
    function isRegExp(value){
        return Object.prototype.toString.call(value) === "[object RegExp]";
    }
    
    function isNativeJSON(){
        return window.JSON && Object.prototype.toString.call(JSON) === "[object JSON]";
    }

对于ie中一COM对象形式实现的任何函数,isFunction都返回false,因为他们并非原生的javascript函数。

在web开发中,能够区分原生与非原生的对象非常重要。只有这样才能确切知道某个对象是否有哪些功能

以上所有的正确性的前提是:Object.prototype.toString没有被修改过

2 作用域安全的构造函数
function Person(name){
    this.name = name;
}

//使用new来创建一个对象
var one = new Person("wdd");

//直接调用构造函数
Person();

由于this是运行时分配的,如果你使用new来操作,this指向的就是one。如果直接调用构造函数,那么this会指向全局对象window,然后你的代码就会覆盖window的原生name。如果有其他地方使用过window.name, 那么你的函数将会埋下一个深藏的bug。

==那么,如何才能创建一个作用域安全的构造函数?==
方法1

function Person(name){
    if(this instanceof Person){
        this.name = name;
    }
    else{
        return new Person(name);
    }
}
3 惰性载入函数

假设有一个方法X,在A类浏览器里叫A,在b类浏览器里叫B,有些浏览器并没有这个方法,你想实现一个跨浏览器的方法。

惰性载入函数的思想是:在函数内部改变函数自身的执行逻辑

function X(){
    if(A){
        return new A();
    }
    else{
        if(B){
            return new B();
        }
        else{
            throw new Error("no A or B");
        }
    }
}

换一种写法

function X(){
    if(A){
        X = function(){
            return new A();
        };
    }
    else{
        if(B){
            X = function(){
                return new B();
            };
        }
        else{
            throw new Error("no A or B");
        }
    }
    
    return new X();
}
4 防篡改对象 4.1 不可扩展对象 Object.preventExtensions
// 下面代码在谷歌浏览器中执行
> var person = {name: "wdd"};
undefined
> Object.preventExtensions(person);
Object {name: "wdd"}
> person.age = 10
10
> person
Object {name: "wdd"}
> Object.isExtensible(person)
false
4.2 密封对象Object.seal

密封对象不可扩展,并且不能删除对象的属性或者方法。但是属性值可以修改。

> var one = {name: "hihi"}
undefined
> Object.seal(one)
Object {name: "hihi"}
> one.age = 12
12
> one
Object {name: "hihi"}
> delete one.name
false
> one
Object {name: "hihi"}
4.3 冻结对象 Object.freeze

最严格的防篡改就是冻结对象。对象不可扩展,而且密封,不能修改。只能访问。

5 高级定时器 5.1 函数节流

函数节流的思想是:某些代码不可以没有间断的连续重复执行

var processor = {
    timeoutId: null,

    // 实际进行处理的方法
    performProcessing: function(){
        ...
    },

    // 初始化调用方法
    process: function(){
        clearTimeout(this.timeoutId);

        var that = this;

        this.timeoutId = setTimeout(function(){
            that.performProcessing();
        }, 100);
    }
}

// 尝试开始执行
processor.process();
5.2 中央定时器

页面如果有十个区域要动态显示当前时间,一般来说,可以用10个定时来实现。其实一个中央定时器就可以搞定。

中央定时器动画 demo地址:http://wangduanduan.coding.me...

var timers = {
        timerId: 0,
        timers: [],
        add: function(fn){
            this.timers.push(fn);
        },
        start: function(){
            if(this.timerId){
                return;
            }

            (function runNext(){
                if(timers.timers.length > 0){
                    for(var i=0; i < timers.timers.length ; i++){
                        if(timers.timers[i]() === false){
                            timers.timers.splice(i, 1);
                            i--;
                        }
                    }

                    timers.timerId = setTimeout(runNext, 16);
                }
            })();
        },
        stop: function(){
            clearTimeout(timers.timerId);
            this.timerId = 0;
        }
    };

参考书籍:
《javascript高级程序设计》
《javascript忍者秘籍》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81986.html

相关文章

  • JavaScript 高级技巧——“高级定时器”的注意要点

    摘要:为了规避这个问题,可以使用定时器对事件处理程序进行节流。当第二次调用该函数时,它会清除前一次的定时器,并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。 高级定时器 为了解决setInterval的一些执行问题, 下面是采用链式setTimeout的方式来规避: setTimeout(function()...

    rubyshen 评论0 收藏0
  • JavaScript 高级技巧——“防篡改对象”的注意要点

    摘要:防篡改对象不可扩展对象默认情况下,所有对象都是可扩展的不可扩展可以使用这个方法严格模式下会抛出错误一旦设置防扩展,对象就无法添加新的属性和方法。已有的属性方法不受影响,这些属性方法仍然可以修改和删除。检测是否被冻结,用方法 防篡改对象 不可扩展对象 默认情况下,所有对象都是可扩展的: var person = { name: Oliver }; person.age = 18;...

    atinosun 评论0 收藏0
  • 10个用Console来Debug的高级技巧

    摘要:在本文,我会为你介绍一些用老式来的技巧。使用可以将聚合成组,并且形成嵌套的层级。最后一个压轴的你可以使用将对象以表格的形式打印出来。自从年双十一正式上线,累计处理了亿错误事件,得到了金山软件百姓网等众多知名用户的认可。 译者按: 我们往往会局限在自己熟悉的知识圈,但也应担偶尔拓展一下,使用一些不常见而又有用的技巧,扩大自己的舒适圈。 原文: 10 Tips for Javascrip...

    Hwg 评论0 收藏0
  • JavaScript 高级技巧——“高级函数”的注意要点

    摘要:语法如下注意这里使用的并不是的,是内部函数的。函数柯里化的基本方法是使用一个闭包返回一个函数。当函数被调用时,返回的函数还需要设置一些传入的参数。 安全的类型检测 typeof操作符 检测数据类型的结果可能会不正确; instanceof操作符 操作符在多个全局作用域下存在问题: var value = []; var isArray = value instanceof Array;...

    solocoder 评论0 收藏0
  • JavaScript 高级技巧 Memoization

    摘要:来源于拉丁语,不要与混淆了。本文首先介绍一个简单的使用优化技术的例子,然后解读和库中使用的源码,加深理解。总结是一种优化技术,避免一些不必要的重复计算,可以提高计算速度。 memoization 来源于拉丁语 memorandum (to be remembered),不要与 memorization 混淆了。 首先来看一下维基百科的描述: In computing, memoizat...

    刘德刚 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<