zoukankan      html  css  js  c++  java
  • 【JavaScript框架封装】数据类型检测模块功能封装

    数据类型检测封装后的最终模块代码如下:

    /*数据类型检验*/
        xframe.extend(xframe, {
            // 鸭子类型(duck typing)如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭子。
            // 只关注对象的行为,不关注对象本身面向接口编型 ,而不是面向实现编程,是设计模式中最重要的思想。
            // 【理解】:一个对象有效的语义,不是由集成自特定的类或实现特定的接口, 而是由当前方法和属性的集合决定的!!!
            isNumber: function (val) {
                // 如果这个数字是有限的话, 而且是数字类型
                return (typeof val === 'number' && isFinite(val)) && (Object.prototype.toString.call(val) === '[object Number]');
            },
            /***
             * 判断一个变量是不是Boolean类型
             * @param val
             * @returns {boolean}
             */
            isBoolean: function (val) {
                return (typeof val === 'boolean') && (Object.prototype.toString.call(val) === '[object Boolean]');
            },
            /**
             * 判断一个变量是不是字符串类型
             * @param val
             * @returns {boolean}
             */
            isString: function (val) {
                return (typeof val === 'string') && (Object.prototype.toString.call(val) === '[object String]');
            },
            /**
             * 判断一个变量是不是undefined
             * @param val
             * @returns {boolean}
             */
            isUndefined: function (val) {
                // oid 0 is a correct and standard way to produce undefined.
                return (val === void 0) || (typeof val === 'undefined') && (Object.prototype.toString.call(val) === '[object Undefined]');
            },
            /**
             * 判断一个变量是不是为空
             * @param val
             * @returns {boolean}
             */
            isNull: function (val) {
                return (val === null) && (Object.prototype.toString.call(val) === '[object Null]');
            },
            /**
             * 检测
             * @param obj
             * @returns {*}
             */
            isNaN: function (val) {
                // 只要这个数字通过判断是不是和他自身相同或者使用typef的方式去检测
                return val !== val;
            },
            /**
             * 判断一个变量是不是一个对象类型
             * @param val
             * @returns {boolean}
             */
            isObject: function (val) {
                if (val !== null && val !== undefined) {
                    if ((typeof val === 'object') && (Object.prototype.toString.call(val))) {
                        return true;
                    }
                }
                return false;
            },
            /**
             * 判断一个对象是不是数组对象
             * @param val
             * @returns {boolean|void|string}
             */
            isArray: function (val) {
                // 判断上不是一个数组的先判断这个数组对象是不是为空, 因为如果val为空的话,就是val.constructor这个属性实际上是没有的,error
                if (val !== null || typeof val !== "undefined") {
                    // 注意在使用constructor判断数据类型的时候比较的实际上是他的原型对象的constructor属性, 这个属性指向的实际上是这个变量的原型对象
                    return (val.constructor === Array) && (Object.prototype.toString.call(val));
                }
                return false;
            }
    
        });

    知识要点总结:

    1.判断一个对象的数据类型通常可以使用

    Object.prototype.toString.call(val)

    这种方式判断数据类型一般对于String,Boolean.Object,Array,NUll都是通用的一种检测方法,首先调用Object的原型对象里面的toString()方法,并使用call方法修改toString()函数中this的指向为val

     /*
        *  这是因为toString为Object的原型方法,
        *  而Array ,function等类型作为Object的实例,都重写了toString方法。
        *  不同的对象类型调用toString方法时,
        *  根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),
        *  而不会去调用Object上原型toString方法(返回对象的具体类型),
        *  所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。
        *

        * */

    // 每一个原型都有自己的prototype都有自己的constructor和toString()方法
     console.log(Object.prototype.toString.call("jerry"));//[object String]
        console.log(Object.prototype.toString.call(12));//[object Number]
        console.log(Object.prototype.toString.call(true));//[object Boolean]
        console.log(Object.prototype.toString.call(undefined));//[object Undefined]
        console.log(Object.prototype.toString.call(null));//[object Null]
        console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
        console.log(Object.prototype.toString.call(function () {
        }));//[object Function]
        console.log(Object.prototype.toString.call([]));//[object Array]
        console.log(Object.prototype.toString.call(new Date));//[object Date]
        console.log(Object.prototype.toString.call(/d/));//[object RegExp]

    2.call,apply,bind的使用方法总结

    // call和apply的使用方法总结-----------------------------------------------------------------
        window.color = 'red';
        document.color = 'yellow';
    
        var s1 = {color: 'blue' };
        function changeColor(){
            console.log(this.color);
        }
    
    
        // 注意call()里面传递的参数,就会把这个参数传给调用的函数,此时调用函数的内部里面的this实际上指向了传递过来的这个参数对象
        changeColor.call();         //red (默认传递参数)
        changeColor.call(window);   //red
        changeColor.call(document); //yellow
        changeColor.call(this);     //red
        changeColor.call(s1);       //blue
    
    
    
        window.firstName = "Cynthia";
        window.lastName = "_xie";
    
        var myObject = {firstName:'my', lastName:'Object'};
    
        function getName(){
            // 这个函数内部的this默认指向的是window,通过call和apply可以间接修改这个this的指向
            console.log(this.firstName + this.lastName);
        }
    
        function getMessage(sex,age){
            console.log(this.firstName + this.lastName + " 性别: " + sex + " age: " + age );
        }
    
        getName.call(window); // Cynthia_xie
        getName.call(myObject); // myObject
    
        getName.apply(window); // Cynthia_xie
        getName.apply(myObject);// myObject
    
        getMessage.call(window,"女",21); //Cynthia_xie 性别: 女 age: 21
        getMessage.apply(window,["女",21]); // Cynthia_xie 性别: 女 age: 21
    
        getMessage.call(myObject,"未知",22); //myObject 性别: 未知 age: 22
        getMessage.apply(myObject,["未知",22]); // myObject 性别: 未知 age: 22

    总结:

     /* 1. apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
            语法:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。


            说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个
            TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。


           2. call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。
            语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。


            说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。

            3. bind()方法通常用于修改一个函数内部this的指向,返回的是一个函数,但是不会立即调用,如果需要调用传递参数的话还需要自己手动调用这个函数

        *
        *
        * */

  • 相关阅读:
    django-makdown编辑器之编辑和显示
    Jenkins以root用户运行的方法
    利用Django提供的ModelForm增删改数据的方法
    Django之URL反向解析
    腾讯云-tke-设置configmap
    线程同步
    测试人的福利来了!柠檬班题库免费对外开放啦。
    如何设计一个高并发系统?
    为什么使用消息队列?消息队列有什么优点和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么优点和缺点?
    记一次idea问题—performing vcs refresh...
  • 原文地址:https://www.cnblogs.com/52tech/p/9325101.html
Copyright © 2011-2022 走看看