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. 牛客国庆集训派对Day_1~3

    Day_1 A.Tobaku Mokushiroku Kaiji 题目描述 Kaiji正在与另外一人玩石头剪刀布.双方各有一些代表石头.剪刀.布的卡牌,每局两人各出一张卡牌,根据卡牌的内容决定这一局的 ...

  2. Android的代码适配方案

    public class DensityUtil { private DensityUtil(){ throw new AssertionError(); } /** * dp转px * @param ...

  3. 单机版solr6.3和分布式solr6.3的安装部署

    一.单机版的solr部署 我的是在windows下安装的,linux同理 1. 安装JDK8,并配置好环境变量,一般我们经常开发的电脑上应该都有JDk了,所以这一步可以忽略. 2. 解压solr6.3 ...

  4. sql注入原理及解决方案

    sql注入原理 sql注入原理就是用户输入动态的构造了意外sql语句,造成了意外结果,是攻击者有机可乘 SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的 ...

  5. nodejs on raspi

    一. https://cnodejs.org/topic/54032efa9769c2e93797cd06 其中的 “安装Node.js” 一节 注意事项: 1. 它用的是v0.10.26(很早的版本 ...

  6. 浅议block实现原理,block为什么使用copy关键字?

    1.block是一个特殊的oc对象,建立在栈上,而不是堆上,这么做一个是为性能考虑,还有就是方便访问局部变量. 2.默认Block使用到的局部变量会被copy,而不是retain.所以,他无法改变局部 ...

  7. 001.JS特效

    一.Js实现单行文本的滚动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...

  8. python2和python3的区别(转)

    基本语法差异 核心类差异 Python3对Unicode字符的原生支持 Python2中使用 ASCII 码作为默认编码方式导致string有两种类型str和unicode,Python3只支持uni ...

  9. ES6学习笔记(4)----正则的扩展

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 正则的扩展 ES6新增的正则表达式修饰符 u修饰符a.能够更准确地匹配unicode大于\uFF ...

  10. 程序员必须知道FTP命令

                                             程序员必须知道FTP命令 文件传输软件的使用格式为:FTP<FTP地址>,若连 接成功,系统将提示用户输入 ...