javascript标准对象与包装对象

标准对象

在JavaScript的世界里,一切都是对象。

但是某些对象还是和其他对象不太一样。为了区分对象的类型,我们用typeof操作符获取对象的类型,它总是返回一个字符串:

typeof 123; // 'number' 
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'

可见,number、string、boolean、function和undefined有别于其他类型。特别注意null的类型是object,Array的类型也是object,如果我们用typeof将无法区分出null、Array和通常意义上的object——{}。

包装对象

除了这些类型外,JavaScript还提供了包装对象,熟悉Java的小伙伴肯定很清楚int和Integer这种暧昧关系。

number、boolean和string都有包装对象。没错,在JavaScript中,字符串也区分string类型和它的包装类型。包装对象用new创建:

var n = new Number(123); // 123,生成了新的包装类型 
var b = new Boolean(true); // true,生成了新的包装类型
var s = new String('str'); // 'str',生成了新的包装类型

虽然包装对象看上去和原来的值一模一样,显示出来也是一模一样,但他们的类型已经变为object了!所以,包装对象和原始值用===比较会返回false:

typeof new Number(123); // 'object' 
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false

所以闲的蛋疼也不要使用包装对象!尤其是针对string类型!!!

如果我们在使用Number、Boolean和String时,没有写new会发生什么情况?

此时,Number()、Boolean和String()被当做普通函数,把任何类型的数据转换为number、boolean和string类型(注意不是其包装类型):

var n = Number('123'); // 123,相当于parseInt()或parseFloat() 
typeof n; // 'number'
var b = Boolean('true'); // true
typeof b; // 'boolean'
var b2 = Boolean('false'); // true! 'false'字符串转换结果为true!因为它是非空字符串!
var b3 = Boolean(''); // false
var s = String(123.45); // '123.45'
typeof s; // 'string'

是不是感觉头大了?这就是JavaScript特有的催眠魅力!

总结一下,有这么几条规则需要遵守:

  • 不要使用new Number()、new Boolean()、new String()创建包装对象;

  • 用parseInt()或parseFloat()来转换任意类型到number;

  • 用String()来转换任意类型到string,或者直接调用某个对象的toString()方法;

  • 通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {...};

  • typeof操作符可以判断出number、boolean、string、function和undefined;

  • 判断Array要使用Array.isArray(arr);

  • 判断null请使用myVar === null;

  • 判断某个全局变量是否存在用typeof window.myVar === 'undefined';

  • 函数内部判断某个变量是否存在用typeof myVar === 'undefined'。

最后有细心的同学指出,任何对象都有toString()方法吗?null和undefined就没有!确实如此,这两个特殊值要除外,虽然null还伪装成了object类型。

更细心的同学指出,number对象调用toString()报SyntaxError:

123.toString(); // SyntaxError

遇到这种情况,要特殊处理一下:

123..toString(); // '123', 注意是两个点!
(123).toString(); // '123'

不要问为什么,这就是JavaScript代码的乐趣!

javascript的数据类型可以分为两种:原始类型和引用类型

  原始类型也称为基本类型或简单类型,因为其占据空间固定,是简单的数据段,为了便于提升变量查询速度,将其存储在栈(stack)中(按值访问)。其中,javascript基本数据类型包括Undefined、Null、Boolean、Number和String五种

  引用类型由于其值的大小会改变,所以不能将其存放在栈中,否则会降低变量查询速度,因此其存储在堆(heap)中,存储在变量处的值是一个指针,指向存储对象的内存处(按址访问)

  [注意]对于引用类型的值,可以为其添加属性和方法,也可以改变和删除其属性和方法;但基本类型不可以添加属性和方法

Undefined

  Undefined类型只有一个值,就是undefined。当声明的变量未初始化时,该变量的默认值是undefined

var test;//undefined
console.log(test == undefined);//true
var test = undefined;//undefined

  对于尚未声明过的变量只能执行一项操作,使用typeof操作符检测其数据类型,但严格模式下会导致错误

typeof(test);//undefined

出现场景

  [1]已声明未赋值的变量

  [2]获取对象不存在的属性

  [3]无返回值的函数的执行结果

  [4]函数的参数没有传入

  [5]void(expression)

类型转换

Boolean(undefined):  false
Number(undefined):  NaN
String(undefined):  'undefined'

Null

  Null类型只有一个值,就是null。逻辑角度看,null值表示一个空对象指针,如果定义的变量将用于保存对象,最好将该变量初始化为null。实际上undefined值是派生自null值的,所以undefined == null

  [注意]null是空对象指针,而[]是空数组,{}是空对象,三者不相同

        console.log(null == undefined);//true

出现场景

  对象不存在时

类型转换

  Boolean(null):   false
  Number(null):   0
  String(null):    'null'

  [注意]因为undefined和null不是构造器类型,所以不能添加自定义属性

包装类型

  包装类型是特殊的引用类型。每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而可能调用一些方法来操作这些数据。包装类型共包括Boolean、Number和String三种

var s1 = 'some text';
var s2 = s1.substring(2);
//在上述过程中,实际上发生了三个步骤
var s1 = new String('some text'); //(1)创建String类型的一个实例 
var s2 = s1.substring(2); //(2)在实例上调用指定的方法
s1 = null//(3)销毁这个实例

  [注意]引用类型和基本包装类型的主要区别是对象的生存期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着不能在运行时为基本类型值添加属性和方法

var s1 = 'some text';
s1.color = 'red';
alert(s1.color);//undefined

创建方式

显式创建包装类型共两种方式:

  [1]Object方式[不建议使用]

var s = new Object('abc');
var b = new Object(true);
var n = new Object(123);

  [2]构造函数方式[不建议使用]

var s = new String('abc');
var b = new Boolean(true);
var n = new Number(123);

  [注意]使用new调用基本包装类型的构造函数与直接调用同名的转型函数是不一样的

var value = '25';
var number = Number(value);
console.log(typeof number);//number
var obj = new Number(value);
console.log(typeof obj);//object

Boolean

  Boolean类型只有两个值:true 和 false。Boolean包装类型是与布尔值对应的引用类型,在布尔表达式中使用Boolean对象容易造成误解

出现场景

  [1]条件语句导致系统执行的隐士类型转换

  [2]字面量或变量定义

类型转换

  Number(true): 1     ||   Number(false) : 0
  String(true):'true'     ||   String(false):'false'

Boolean()

  Boolean(undefined):false
    Boolean(null):false

  Boolean(非空对象包括空数组[]和空对象{}):true

  Boolean(非0): true || Boolean(0和NaN):false

  Boolean(非空包括空格字符串):true || Boolean(''):false

  [注意]true不一定等于1,false也不一定等于0

包装类型继承的方法

  valueOf():返回基本类型值true 或 false

  toString()和toLocaleString():返回字符串'true' 或'false'

console.log(typeof true.valueOf(),true.valueOf());//boolean true
console.log(typeof false.valueOf(),false.valueOf());//boolean false
console.log(typeof true.toString(),true.toString());//String 'true'
console.log(typeof false.toString(),false.toString());//String 'false'
console.log(typeof true.toLocaleString(),true.toLocaleString());//String 'true'
console.log(typeof false.toLocaleString(),false.toLocaleString());//String 'false'

Number

  javascript只有一种数字类型,既可以表示32位的整数,还可以表示64位的浮点数

  关于Number类型的详细信息移步到此

String

  String类型是javascript中唯一没有固定大小的原始类型

下面接着来理解下JavaScript基本数据类型的包装对象

现象:为什么可以对字符串的操作采用对象的表示法?

例如: 

var s = "this is a String";
var len = s.length;

解析:

JavaScript三个基本数据类型都有相应的对象类;分别为Sring,Number,Boolean类;
JavaScript可以灵活的将一种类型的值转换为另一种类型;
当我们在对象环境中使用字符串时,即当我们试图访问这个字符串的属性或方法时;
JavaScript会为这个字符串值内部地创建一个String包装对象;
String对象会暂时代替原始的字符串值,完成我们的访问;
这个被内部创建的String对象是瞬间存在的,它的作用是使我们可以正常访问属性和方法;
String对象在使用过后会被系统丢弃掉;
而原始值并不会被改变;

以上同样适用于数字和布尔值类型;

使用Object()函数,任何数字、字符串、布尔值都可以转换为它对应的包装对象;

例如:

var number_wrapper  = Object (3);

================ End

javascript标准对象与包装对象的更多相关文章

  1. 理解JavaScript的临时包装对象

    Javascript语言中的对象和基础类型string.number.boolean都可以使用"."符号访问属性和方法,但是本质上只有对象才可以使用".",那么 ...

  2. JavaScript语言基础-包装对象

  3. JavaScript 包装对象

    万物皆对象 在JavaScript里,万物皆对象.但是某些对象有别于其它对象,我们可以用 typeof 来获取一个对象的类型,它总是返回一个字符串. typeof 123; // 'number' t ...

  4. JavaScript包装对象

    JavaScript是面向对象的语言,使用”.”操作符可以访问对象的属性和方法,而对于基本类型(null, undefined, bool, number, string)应该是值类型,没有属性和方法 ...

  5. javascript类型系统——包装对象

    × 目录 [1]定义 [2]生存期 [3]显式创建[4]转型函数[5]比较运算 前面的话 javascript对象是一种复合值,它是属性或已命名值的集合.通过'.'符号来引用属性值.当属性值是一个函数 ...

  6. JavaScript之包装对象

    JavaScript对象是一种复合值:它是属性和已命名值的集合.通过"."符号来引用属性值.当属性值是一个函数时,称为方法. ①一段你常用但却未必明白其真正底层原理的代码: var ...

  7. 每日分享!~ vue JavaScript中为什么可以读取到字符串的长度!(包装对象)

    首先需要知道什么是包装对象? 对象是JavaScript语言下最主要的数据类型,三种原始的值-----数值,字符串,布尔值,在一定条件下会自动的转为对象.也就是原始类型的包装对象: 也就是通过如下方式 ...

  8. javascript深入浅出——学习笔记(包装对象和类型检测)

    3包装对象:https://www.imooc.com/video/5676 当我们尝试把基本类型已对象的方式访问时,javascript会把该基本类型转换为对应的包装类型对象(临时对象),相当于ne ...

  9. JavaScript 基本包装类型,包装对象

    前言 javascript对象是一种复合值,它是属性或已命名值的集合.通过'.'符号来引用属性值.当属性值是一个函数时,称其为方法.通过o.m()来调用对象o中的方法.我们发现,字符串也同样具有属性和 ...

随机推荐

  1. 【POJ1733】Parity game

    [POJ1733]Parity game 题面 vjudge 题解 比较简单的分类并查集 将一个查询操作看作前缀和\(s_r-s_{l-1}\)的奇偶性 将每个点拆成一奇一偶然后分别连边即可 如果一个 ...

  2. LeetCode:35. Search Insert Position(Easy)

    1. 原题链接 https://leetcode.com/problems/search-insert-position/description/ 2. 题目要求 给定一个已经排好序的数组和一个目标值 ...

  3. java-IO处理类的序列化与反序列化

    package TestIo; import java.io.*; /** * 序列化 * * * 对象序列化 * * 一 创建对象 需要说明,想序列化的对象一定要是实现Serivalizable接口 ...

  4. MySQL高级-慢查询日志

    一.慢查询日志是什么 1. 2. 3. 2.开启了慢查询日志后,什么样的SQL才会记录到慢查询日志里面呢? 3.案例 1.查看当前多少秒算慢 2.设置慢的阙值时间 3.为什么设置后看不出变化? 4.记 ...

  5. rsync同步的艺术

    转自:http://roclinux.cn/?p=2643 如果你是一位运维工程师,你很可能会面对几十台.几百台甚至上千台服务器,除了批量操作外,环境同步.数据同步也是必不可少的技能. 说到“同步”, ...

  6. Vue框架核心之数据劫持

    本文来自网易云社区. 前瞻 当前前端界空前繁荣,各种框架横空出世,包括各类mvvm框架横行霸道,比如Angular.Regular.Vue.React等等,它们最大的优点就是可以实现数据绑定,再也不需 ...

  7. Linux系统中ElasticSearch搜索引擎安装配置Head插件

    近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...

  8. SpringMVC+mybatis+maven+Ehcache缓存实现

    所谓缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. 缓存主要可分为二大类: 一.通过文件缓存,顾名思义文 ...

  9. <cerrno>

    文件头名称: <cerrno>(errno.h) 文件头描述: 文件内定义了如下的宏  errno 最后一个错误代码 加上其他至少的三个宏常量:EDOM,ERANGE 和EILSEQ 宏定 ...

  10. def语句和参数

    如果调用print()或len()函数,你会传入一些值,放在括号内,在这里成为“参数”.也可以自己定义接受参数的函数.在文件编辑器中输入这个例子: def hello(name): print('He ...