zoukankan      html  css  js  c++  java
  • typeof + instanceof+toString+constructor什么推理javascript数据类型

    一个、typeof

    JS这些变量是弱类型(这是弱类型)的,它可以不管用来存储数据的类型的。

    typeof 数据类型可用于检测给定的变量。可能的返回值:
    1. 'undefined' --- 这个值没有定义;
    2. 'boolean' --- 这个值是布尔值。
    3. 'string' --- 这个值是字符串。
    4. 'number' --- 这个值是数值;
    5. 'object' --- 这个值是对象或null;
    6. 'function' --- 这个值是函数。

    測试:
    document.write("typeof(1): " + typeof(1) + "<br>");
    document.write("typeof(NaN): " + typeof(NaN) + "<br>");
    document.write("typeof(Number.MIN_VALUE): " + typeof(Number.MIN_VALUE) + "<br>")
    document.write("typeof(Infinity): " + typeof(Infinity) + "<br>")
    document.write("typeof("123"): " + typeof("123") + "<br>")
    document.write("typeof(true): " + typeof(true) + "<br>")
    document.write("typeof(window): " + typeof(window) + "<br>")
    document.write("typeof(document): " + typeof(document) + "<br>")
    document.write("typeof(null): " + typeof(null) + "<br>")
    document.write("typeof(eval): " + typeof(eval) + "<br>")
    document.write("typeof(Date): " + typeof(Date) + "<br>")
    document.write("typeof(sss): " + typeof(sss) + "<br>")
    document.write("typeof(undefined): " + typeof(undefined) + "<br>")
    測试结果:
    typeof(1): number
    typeof(NaN): number
    typeof(Number.MIN_VALUE): number
    typeof(Infinity): number
    typeof("123"): string
    typeof(true): boolean
    typeof(window): object
    typeof(document): object
    typeof(null): object
    typeof(eval): function
    typeof(Date): function
    typeof(sss): undefined
    typeof(undefined): undefined
    參考资料
    http://javaeyetodj.iteye.com/blog/1199125
    http://www.cnblogs.com/lidabo/archive/2011/12/29/2305770.html

    二、instanceof

    在 JavaScript 中,推断一个变量的类型经常会用 typeof 运算符。在使用 typeof 运算符时採用引用类型存储值会出现一个问题,不管引用的是什么类型的对象,它都返回 “object”。

    这就须要用到instanceof来检測某个对象是不是还有一个对象的实例。

    通常来讲。使用 instanceof 就是推断一个实例是否属于某种类型。
    另外。更重的一点是 instanceof 能够在继承关系中用来推断一个实例是否属于它的父类型。上面的代码中是推断了一层继承关系中的父类,在多层继承关系中,instanceof 运算符相同适用。

    instanceof 检測一个对象A是不是还有一个对象B的实例的原理是:查看对象B的prototype指向的对象是否在对象A的[[prototype]]链上。假设在,则返回true,假设不在则返回false。

    只是有一个特殊的情况,当对象B的prototype为null将会报错(类似于空指针异常)。

    測试:

    function Foo(){}
    Foo.prototype = new Aoo();//JavaScript 原型继承
    var foo = new Foo();
    console.log(foo instanceof Foo)//true
    console.log(foo instanceof Aoo)//true
    
    console.log(Object instanceof Object);//true
    console.log(Function instanceof Function);//true
    console.log(Number instanceof Number);//false
    console.log(String instanceof String);//false
    console.log(Function instanceof Object);//true
    console.log(Foo instanceof Function);//true
    console.log(Foo instanceof Foo);//false
    參考资料
    http://www.studyofnet.com/news/175.html

    三、toString

    Object.prototype.toString().call(param) 返回param的类型(string,格式是[object class]) 。

    toString() 方法可把一个逻辑值转换为字符串,并返回结果,语法为:booleanObject.toString()。刚才我说了,js中的对象都是继承的Object,这些对象都自己定义的有函数或者重构了Object的部分函数,并且它们都对toString()函数进行了重写。所以我们不能像1中直接写param.prototype.toString()这样就运行的是param自己重写后的toString()函数了。

    在toString方法被调用时,会运行以下的操作步骤:
    1. 获取this对象的[[Class]]属性的值.
    2. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串.
    3. 返回第二步的操作结果Result(2).
    在ES3中,规范文档并没有总结出[[class]]内部属性一共同拥有几种,只是我们能够自己统计一下,原生对象的[[class]]内部属性的值一共同拥有10种.各自是:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object","RegExp", "String".所以Object.prototype.toString()的输出结果就是这样的格式的字符串[object Array],[object Boolean]。
    所以说toString能够推断:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object","RegExp", "String"以上十种数据类型。




    在ES5.1中,除了规范写的更具体一些以外,Object.prototype.toString方法和[[class]]内部属性的定义上也有一些变化,Object.prototype.toString方法的规范例如以下:
    在toString方法被调用时,会运行以下的操作步骤:
    1 假设this的值为undefined,则返回"[object Undefined]".
    2 假设this的值为null,则返回"[object Null]".
    3 让O成为调用ToObject(this)的结果.
    4 让class成为O的内部属性[[Class]]的值.
    5 返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.
    能够看出。比ES3多了1,2,3步.第1,2步属于新规则,比較特殊,由于"Undefined"和"Null"并不属于[[class]]属性的值。经统计,可返回的类型有"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"比ES3多了2种各自是arguments对象的[[class]]成了"Arguments"。而不是曾经的"Object",还有就是多个了全局对象JSON,它的[[class]]值为"JSON"。


    最后的最后提醒大家,Object.prototype.toString().call(param)返回的[object class]中class首字母是大写。像JSON这样的甚至都是大写,所以。大家推断的时候能够都转换成小写,以防出错,Object.prototype.toString().call(param).toLowerCase()就可以。

    測试:

    document.write("{}.toString.call(1): " + {}.toString.call(1) + "<br>");
    document.write("{}.toString.call(NaN): " + {}.toString.call(NaN) + "<br>");
    document.write("{}.toString.call(Number.MIN_VALUE): " + {}.toString.call(Number.MIN_VALUE) + "<br>")
    document.write("{}.toString.call(Infinity): " + {}.toString.call(Infinity) + "<br>")
    document.write("{}.toString.call("123"): " + {}.toString.call("123") + "<br>")
    document.write("{}.toString.call(true): " + {}.toString.call(true) + "<br>")
    document.write("{}.toString.call(window): " + {}.toString.call(window) + "<br>")
    document.write("{}.toString.call(document): " + {}.toString.call(document) + "<br>")
    document.write("{}.toString.call(null): " + {}.toString.call(null) + "<br>")
    document.write("{}.toString.call(eval): " + {}.toString.call(eval) + "<br>")
    document.write("{}.toString.call(Date): " + {}.toString.call(Date) + "<br>")
    document.write("{}.toString.call(undefined): " + {}.toString.call(undefined) + "<br>")
    document.write("{}.toString.call({}): " + {}.toString.call({}) + "<br>")
    document.write("{}.toString.call(sss): " + {}.toString.call(sss) + "<br>")

    測试结果:
    {}.toString.call(1): [object Number]
    {}.toString.call(NaN): [object Number]
    {}.toString.call(Number.MIN_VALUE): [object Number]
    {}.toString.call(Infinity): [object Number]
    {}.toString.call("123"): [object String]
    {}.toString.call(true): [object Boolean]
    {}.toString.call(window): [object global]
    {}.toString.call(document): [object HTMLDocument]
    {}.toString.call(null): [object Null]
    {}.toString.call(eval): [object Function]
    {}.toString.call(Date): [object Function]
    {}.toString.call(undefined): [object Undefined]
    {}.toString.call({}): [object Object]

    參考资料:

    http://www.jb51.net/article/42864.htm

    四、constructor

    在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用。

    就是返回对象相相应的构造函数。

    从定义上来说跟instanceof不太一致,但效果都是一样的
    注意: constructor 在类继承时会出错
    比如:

    function A(){};
    function B(){};
    A.prototype = new B(); //A继承自B
    var aObj = new A();
    alert(aobj.constructor === B)// -----------> true;
    alert(aobj.constructor === A) //-----------> false;
    而instanceof方法不会出现该问题,对象直接继承和间接继承的都会报true:
    alert(aobj instanceof B) //----------------> true;
    alert(aobj instanceof B) //----------------> true;
    言归正传。解决construtor的问题一般是让对象的constructor手动指向自己:
    aobj.constructor = A; //将自己的类赋值给对象的constructor属性
    alert(aobj.constructor === A) //-----------> true;
    alert(aobj.constructor === B) //-----------> false; //基类不会报true了;
    測试:
    console.log([].constructor == <strong>Array</strong>); // true
    console.log({}.constructor == <strong>Object</strong>); // true
    console.log("string".constructor == <strong>String</strong>); // true
    console.log((123).constructor == <strong>Number</strong>); // true
    console.log(true.constructor == <strong>Boolean</strong>); // true
    console.log((new Date()).constructor == <strong>Date</strong>);//true

    參考资料:http://blog.sina.com.cn/s/blog_51048da70101grz6.html

    五、jQuery中的类型推断

    type()方法

    type: function( obj ) {
        if ( obj == null ) {
            return String( obj );
        }
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[ core_toString.call(obj) ] || "object" :
            typeof obj;
    },


    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    Linux常用命令大全(非常全!!!)
    TCP连接的建立与释放(三次握手与四次挥手)
    TCP/IP Http 和Https socket之间的区别
    redis持久化方法对比分析
    关于HTTP协议,一篇就够了
    远程桌面不能拷贝文件的问题
    URLDecoder: Incomplete trailing escape (%) pattern
    利用pdf2swf将PDF转换成SWF
    Oracle删除当前用户下所有的表的方法
    JS简单验证密码强度
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4754343.html
Copyright © 2011-2022 走看看