zoukankan      html  css  js  c++  java
  • 自我学习——javascript——高级技巧

    1.安全类型检测(toString方式)

      因为javascript的本身检测并不是很可靠,比如在safari4以前的版本里,对正则表达式用typeof的时候,返回的是"function",instanceof在存在多个全局作用局(存在iframe)的情况下必须要保证对象和构造函数是同一个全局作用域下。

                var arr1={
                    a:1,
                    b:2        
                }
                
                var arr2=[1,2];
                
                function isArray(value){
                    //这样子检验可以避免和变量作用域的绑定
                    return Object.prototype.toString.call(value)=="[object Array]";
                }
                
                isArray(arr1);            //false
                isArray(arr2);            //true
    View Code

    注意:1 对于ie的COM对象实现的任何函数

    2.作用域安全的构造函数

      构造函数之所以被称为构造函数就是因为我们在调用这个函数的时候用了new关键字,如果不用的话就会出错

                function Person(name, age, job) {
                    this.name = name;
                    this.age = age;
                    this.job = job;
                }
                var person=Person("xiaosi",20,"web");
                alert(window.name);        //xiaosi
                alert(window.age);         //20      
                alert(window.job);         //web
                
                alert(person.name);    //报错,person未定义
                alert(person.age);
                alert(person.job);
    View Code

      在执行下面的的 alert(person.name);时候会报错,报错的原因就是因为Person没有使用new关键字,所以只是个普通函数,而普通函数的话person等于Person的返回值,而Person没有返回值,所以person值为undefined;而上面 alert(window.name);会有返回值的原因是因为没有用new关键字会导致Person的this指向window

      改进的函数:

                function Person(name,age,job){
                    if(this instanceof Person){
                        this.name=name;
                        this.age=age;
                        this.job=job;
                        alert("设置对应的属性");
                    }else{
                        alert("直接返回一个对象");
                        return new Person(name,age,job);
                    }
                }
                
                var person1=Person("xiaosi","20","web");
                alert(window.name);
                alert(person1.name);
                
                var person2=new Person("xiaosi","20","web");
                alert(person2.name);
    View Code

    这样的话,构造函数会进行检验,如果不是通过new 关键字构造对象将会返回带new 的构造函数,然后重新构造一次

    ,但是,这会导致实现继承的时候出现问题:

                function Person(name,age,job){
                    if(this instanceof Person){
                        this.name=name;
                        this.age=age;
                        this.job=job;
                        alert("设置对应的属性");
                    }else{
                        alert("直接返回一个对象");
                        return new Person(name,age,job);
                    }
                }
                
                function Me(love){
                    Person.call(this,"xiaosi","20","web");
                    this.love=love;
                    this.getArea=function(){
                        return this.love();
                    }
                }
                
                var me=new Me("cancan");
                alert(me.name);             //undefined
                alert(me.age);             //undefined
                alert(Me.job);            //undefined
    View Code

    像这里会导致子类无法继承到父类的属性,而原因就是因为在调用call的时候,父类用了安全模式,导致子类无法调用父类的构造函数,因为原型链上的对象构造函数不同(注意,instanceof 不是用来检测对象类型的,而是用来检测对象原型链上是否存在某一构造函数,虽然返回结果类似,但是由于实际上检测的是原型链,会导致作用域不同情况下返回错误结果)

    解决办法:给子类对象的原型链上添加一个父类的对象(原型链不是指向构造函数的)

                function Person(name,age,job){
                    if(this instanceof Person){
                        this.name=name;
                        this.age=age;
                        this.job=job;
                        alert("设置对应的属性");
                    }else{
                        alert("直接返回一个对象");
                        return new Person(name,age,job);
                    }
                }
                
                function Me(love){
                    Person.call(this,"xiaosi","20","web");
                    this.love=love;
                    this.getArea=function(){
                        return this.love();
                    }
                }
                Me.prototype=new Person();        //给Me添加原型链指向Person()的一个实例对象
                
                var me=new Me("cancan");
                alert(me.name);             //undefined
                alert(me.age);             //undefined
                alert(Me.job);            //undefined
    View Code

     3.惰性载入函数(提高执行效率)

     我们在写函数的时候往往需要进行很多的if判断,但是实际上如果我们得到了一次页面环境的话用不用再次判断了,如果直接调用函数的话就会比执行if判断更快速

                    function createXHR(){
                        if(window.XMLHttpRequest){
                            alert("创建XMLHttpRequest对象");
                            return new XMLHttpRequest();
                        }else if(window.ActiveXObject) {
                            alert("创建ActiveXObject对象");
                            return new ActiveXObject();
                        }else{
                            alert("不能创建对象");
                        }
                    }            
                  var xhr=  createXHR();
    View Code

    这上面的代码就说明了这个问题,需要判断浏览器支持情况再执行构造函数,但是用户的判断情况只需要一次就可以了,所以,改进:

                function createXHR() {
                    if (window.XMLHttpRequest) {
                        alert("创建XMLHttpRequest对象");
    
                        createXHR = function() {
                            return new XMLHttpRequest();
                        }
                    } else if (window.ActiveXObject) {
                        alert("创建ActiveXObject对象");
                        createXHR = function() {
                            return new ActiveXObject();
                        }
                    } else {
                        alert("不能创建对象");
                    }
                }
                var xhr = createXHR();
    View Code

    这样改进之后,实际上在执行完一次判断之后createXHR函数内容就被改变了,然后就可以直接针对浏览器执行我们想要的代码了

    另一方式:

                var createXHR = (function() {
                    if (window.XMLHttpRequest) {
                        alert("创建XMLHttpRequest对象");
    
                        return function() {
                            return new XMLHttpRequest();
                        }
                    } else if (window.ActiveXObject) {
                        alert("创建ActiveXObject对象");
                        return function() {
                            return new ActiveXObject();
                        }
                    } else {
                        alert("不能创建对象");
                    }
                })();
    View Code

    也是一样的在判断完成之后返回我们需要的函数

    4.函数绑定

  • 相关阅读:
    一个链表,奇数位升序偶数位降序,让链表变成升序的
    LeetCode 046 Permutations 全排列
    LeetCode 128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列
    LeetCode 024 Swap Nodes in Pairs 交换链表中相邻的两个节点
    模板实现一个栈(内部使用动态申请的数组作为存储结构)
    004 Median of Two Sorted Arrays 两个有序数组的中位数
    静态链接与动态链接
    sizeof和strlen的区别
    const和define的区别
    lodash
  • 原文地址:https://www.cnblogs.com/yansi/p/3213292.html
Copyright © 2011-2022 走看看