var a ="111";
console.log(a.constructor);//function String() { [native code]}
var b= String("111");
console.log(b.constructor);//同a function String() { [native code]}
var c= new String("111");
console.log(a.constructor===String);//true
console.log(c.constructor===String);//true

  

JavaScript 对象 
除了数字、字符串、布尔值、null、undefined(都不可变)这5种简单类型,其他都是对象。

javascript 存在2套类型系统,一套是元类型,用typeof可以检验,有六种:"number"、"string"、"boolean"、"object"、"function"、"undefined"。

另一套是对象类型系统,是元类型object的一个分支。

基础类型是通过传值来操作,而引用类型则是通过传址来操作的

JavaScript中的对象是可变的键控集合(keyed collections)。 
对象是属性的容器,其中每个属性都拥有名字和值。 
JavaScript中的对象是无类别的(class-free)的。它对新属性的名字和值没有约束。 
JavaScript包括一个原型链特性,允许对象继承另一对象的属性。

引用: 
对象通过引用来传递,他们永远不会被拷贝。

原型: 
每个对象都连接到一个原型对象,并且它可以从中继承属性。所有通过对象字面量创建的对象都连接到Object.prototype这个JavaScript中的标准对象。 
原型连接在更新时不起作用。我们对某个对象做出改变时,不会触及到该对象的原型。原型连接只有在检索值时才会被用到。

基础类型是通过传值来操作,而引用类型则是通过传址来操作的

包装类,以及“一切都是对象”。

typeof——看上去很官方

typeof是JS语言中的一个运算符,从它的字面来看,显然它是用来获取类型的,按JavaScript标准的规定,typeof获取变量类型名称的字符串表示,他可能得到的结果有6种:string、bool、number、undefined、object、function,而且JavaScript标准允许其实现者自定义一些对象的typeof值。

在JS标准中有这样一个描述列表:

Type

Result

Undefined

"undefined"

Null

"object"

Boolean

"boolean"

Number

"number"

String

"string"

Object (native and doesn't implement [[call]])

"object"

Object (native and implements [[call]])

"function"

Object (host)

Implementation-dependent

instanceof——原型还是类型?

instanceof的意思翻译成中文就是"是……的实例",从字面意思理解它是一个基于类面向对象编程的术语,而JS实际上没有在语言级别对基于类的编程提供支持。JavaScript标准虽然只字未提,但其实一些内置对象的设计和运算符设置都暗示了一个"官方的"实现类的方式,即从把函数当作类使用,new运算符作用于函数时,将函数的prototype属性设置为新构造对象的原型,并且将函数本身作为构造函数。

所以从同一个函数的new运算构造出的对象,被认为是一个类的实例,这些对象的共同点是:1.有同一个原型 2.经过同一个构造函数处理。而instanceof正是配合这种实现类的方式检查"实例是否属于一个类"的一种运算符。猜一猜也可以知道,若要检查一个对象是否经过了一个构造函数处理千难万难,但是检查它的原型是什么就容易多了,所以instanceof的实现从原型角度理解,就是检查一个对象的[[prototype]]属性是否跟特定函数的prototype一致。注意这里[[prototype]]是私有属性,在SpiderMonkey(就是Firefox的JS引擎)中它可以用__proto__来访问。

原型只对于标准所描述的Object类型有意义,所以instanceof对于所有非Object对象都会得到false,而且instanceof只能判断是否属于某一类型,无法得到类型,但是instanceof的优势也是显而易见的,它能够分辨自定义的"类"构造出的对象。

instanceof实际上是可以被欺骗的,它用到的对象私有属性[[prototype]]固然不能更改,但函数的prototype是个共有属性,下面代码展示了如何欺骗instanceof

function ClassA(){};

function ClassB(){};

var o = new ClassA();//构造一个A类的对象

ClassB.prototype = ClassA.prototype; //ClassB.prototype替换掉

alert(o instanceof ClassB)//true 欺骗成功 - -!

Object.prototype.toString——是个好方法?

Object.prototype.toString原本很难被调用到,所有的JavaScript内置类都覆盖了toString这个方法,而对于非内置类构造出的对象,Object.prototype.toString又只能得到毫无意义的[object Object]这种结果。所以相当长的一段时间内,这个函数的神奇功效都没有被发掘出来。

在标准中,Object.prototype.toString的描述只有3句

1. 获取this对象的[[class]]属性

2. 通过连接三个字符串"[object ", 结果(1), 和 "]"算出一个字符串

3. 返回 结果(2).

显而易见,Object.prototype.toString其实只是获取对象的[[class]]属性而已,不过不知道是不是有意为之,所有JS内置函数对象String Number Array RegExp……在用于new构造对象时,全都会设定[[class]]属性,这样[[class]]属性就可以作为很好的判断类型的依据。

因为Object.prototype.toString是取this对象属性,所以只要用Object.prototype.toString.call或者Object.prototype.toString.apply就可以指定this对象,然后获取类型了。

Object.prototype.toString尽管巧妙,但是却无法获取自定义函数构造出对象的类型,因为自定义函数不会设[[class]],而且这个私有属性是无法在程序中访问的。Object.prototype.toString最大的优点是可以让1和new Number(1)成为同一类型的对象,大部分时候二者的使用方式是相同的。

然而值得注意的是 new Boolean(false)在参与bool运算时与false结果刚好相反,如果这个时候把二者视为同一类型,容易导致难以检查的错误。

总结:

为了比较上面三种类型判断方法,我做了一张表格,大家可以由此对几种方法有个整体比较。为了方便比较,我把几种判断方式得到的结果统一了写法:

对象

typeof

instanceof

Object.prototype.toString

标准

"abc"

String

——

String

String

new String("abc")

Object

String

String

Object

function hello(){}

Function

Function

Function

Object

123

Number

——

Number

Number

new Number(123)

Object

Number

Number

Object

new Array(1,2,3)

Object

Array

Array

Object

new MyType()

Object

MyType

Object

Object

null

Object

——

Object

Null

undefined

Undefined

——

Object

Undefined

事实上,很难说上面哪一种方法是更加合理的,即使是标准中的规定,也只是体现了JS的运行时机制而不是最佳使用实践。我个人观点是淡化"类型"这一概念,而更多关注"我想如何使用这个对象"这种约束,使用typeof配合instanceof来检查完全可以在需要的地方达到和强类型语言相同的效果。

附1 IEEE 754 规定的双精度浮点数表示(来自中文wikipedia):

sign bit(符号): 用来表示正负号

exponent(指数): 用来表示次方数

mantissa(尾数): 用来表示精确度

JavaScript 的类型的更多相关文章

  1. JavaScript事件类型

    JavaScript事件类型 Web浏览器中可能发生的事件有很多类型.这里我将主要将下面几种常用的事件类型: UI事件 焦点事件 鼠标与滚轮事件 键盘与文本事件 复合事件 变动事件 HTML5事件 设 ...

  2. Flow: JavaScript静态类型检查工具

    Flow: JavaScript静态类型检查工具 Flow是Facebook出品的,针对JavaScript的静态类型检查工具.其代码托管在github之上,并遵守BSD开源协议. 关于Flow 它可 ...

  3. javascript 操作符类型隐性转换

    javascript 操作符类型隐性转换 (一).一元操作符只能操作一个值的操作符叫做一元操作符1.递增和递减操作符a. 在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减1的操作 ...

  4. javascript学习-类型判断

    javascript学习-类型判断 1.类型判断的的武器 javascript中用于类型判断的武器基本上有以下几种: 严格相等===,用来判断null,undefined,true,false这种有限 ...

  5. JavaScript的类型自动转换高级玩法JSFuck

    0 前言 最开始是不小心在微信公众号(程序员大咖)看到一篇JS的高逼格代码,然后通过里面的链接跳转到了JSFuck的wiki,就像顺着迷宫找宝藏的感觉,感叹JS的自动类型转换的牛逼. 1 样例 (!( ...

  6. 面向对象的JavaScript --- 动态类型语言

    面向对象的JavaScript --- 动态类型语言 动态类型语言与面向接口编程 JavaScript 没有提供传统面向对象语言中的类式继承,而是通过原型委托的方式来实现对象与对象之间的继承. Jav ...

  7. javascript 字典类型的使用

    javascript  字典类型的使用 1.使用Array: var arr = new Array(); arr["zs"] = "zhangsan"; ar ...

  8. javascript变量类型及作用域

    javascript变量类型及作用域 一.简介 变量类型 ECMAScript变量可能包含两种不同类型的数据值:基本类型和引用类型. 基本类型 基本类型指的是简单的数据段,5种基本数据类型:undef ...

  9. js课程 1-3 Javascript变量类型详解

    js课程 1-3  Javascript变量类型详解 一.总结 一句话总结:js对象点(属性方法),json对象冒号(属性方法).属性和方法区别只有一个括号. 1.json对象中的函数的使用? 函数名 ...

  10. JavaScript 基础类型,数据类型

    1.基础类型:undefined,null,Boolean,Number,String,Symbol Undefined类型:一个没有被赋值的变量会有个默认值undefined; Null类型:nul ...

随机推荐

  1. CF850 E. Random Elections

    题目传送门:CF 题目大意: 现有\(A,B,C\)三人参加竞选,有n个市民对其进行投票,每个市民心中对三人都有一个优先顺序(如市民\(i\)对三人的优先顺序为\(A-C-B\),则凡是有\(A\)的 ...

  2. 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增

    倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...

  3. 二分图匹配 + 构造 E. Arpa’s overnight party and Mehrdad’s silent entering

    http://codeforces.com/contest/742/problem/E 跪着看题解后才会的. 对于任何一对BF[i]和GF[i] 连接了一条边后,那么他们和隔壁都是不会有边相连的了,这 ...

  4. Linux离线安装pip和numpy

    首先说明一下pip在线安装程序会发生什么 例如: 运行pip install numpy 1.pip会先下载与自己机器匹配的wheel安装包 我的是numpy-1.12.1-cp27-cp27mu-m ...

  5. AJPFX谈Java 性能优化之基本类型 vs 引用类型

    ★名词定义 先明确一下什么是“基本类型”,什么是“引用类型”. 简单地说,所谓基本类型就是 Java 语言中如下的8种内置类型: booleancharbyteshortintlongfloatdou ...

  6. elasticsearch 2.4.0安装说明

    首先从官网下载安装包,是个压缩文件,然后解压 在es目录下找到es的配置文件 修改集群(cluster)名称 PS:一般情况下一台机只部署一个es程序,也就是一个集群,默认集群名是ewater_mai ...

  7. FPGA原型验证

    为什么要做FPGA原型验证? FPGA原型验证可以在IC流片前对芯片功能和性能做出评估,同时,可以给软件设计人员提供验证平台.所有的设计,无论是SOC还是ASIC都需要被验证(功能和时序验证),以确保 ...

  8. JavaScript 字符串与数字的相互转换

    js字符串转换成数字 js 字符串转换数字方法主要有三种:转换函数.强制类型转换.利用JS变量弱类型特点进行转换 1. 转换函数:js提供了parseInt()和parseFloat()两个转换函数. ...

  9. 在同一页面显示多个JavaScript统计图表

    最近我接到一个开发任务,要求就"售后服务客户满意度调查问卷表"里客户填写的反馈答案做一个统计. 问题的例子如下: 您最后一次是何时购买了我们的产品? 服务人员服务态度是否友好.工作 ...

  10. Python3基础教程(十七)—— Virtualenv

    虚拟的 Python 环境(简称 venv) 是一个能帮助你在本地目录安装不同版本的 Python 模块的 Python 环境,你可以不再需要在你系统中安装所有东西就能开发并测试你的代码. 安装Vir ...