最全Javascript数据类型剖析

数据范例

最新的 ECMAScript 范例定义了 7 种数据范例:

  1. 6种原型数据范例(primitive type):
  • undefined. 变量未定义时的属性。
  • null. 一个表明 null 值的特别关键字。 JavaScript 是大小写敏感的,因而 null 与 Null、NULL或其他变量完整差别。
  • Boolean. 布尔值,true 和 false.
  • Number. 示意数字,比方: 42 或许 3.14159。
  • String. 示意字符串,比方:”Howdy”
  • Symbol ( 在 ECMAScript 6 中新增加的范例).。一种数据范例,它的实例是唯一且不可转变的。
  1. 以及 Object 对象。(complex type 庞杂范例)

undefined 范例

Undefined范例只要一个值undefined,示意”缺乏值”,就是此处应当有一个值,然则还没有定义。重要的用法:

(1)变量被声清楚明了,但没有赋值时,就即是undefined。

(2) 挪用函数时,应当供应的参数没有供应,该参数即是undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默许返回undefined。

PS: 值 undefined 并差别于未定义的值。然则,typeof 运算符并不真正辨别这两种值。

var i;
console.log(i) ; // undefined

function f(x){console.log(x)}
f();  // undefined

var  o = new Object();
console.log(o.p);  // undefined

var func = f();
console.log(func);  // undefined

console.log(typeof y); //"undefined"

null 范例

null范例的默许值是null,从逻辑角度讲,是示意一个空对象指针,示意”没有对象”,即该处不该当有值。重要用法:

(1) 作为函数的参数,示意该函数的参数不是对象。

(2) 作为对象原型链的尽头。

Object.getPrototypeOf(Object.prototype)  // null

区分undefined:

当一个变量声明后,未初始化,则该值为undefined,假如这个值是为了保留对象,则修正其默许初始化的值,改成null。 所以当检测其范例时,会显现范例为object。

typeof null        // object (汗青缘由,不是'null')
typeof undefined   // "undefined"
null === undefined // false
null  == undefined // true
null === null // true
null == null // true
!null // true
Number(null) // 0
Number(undefined) // NaN
isNaN(1 + null) // false
isNaN(1 + undefined) // true

Boolean 范例

布尔范例,该范例有两个值:true false。Bloolean()函数,可以将其他范例的值转换为布尔范例。同时也存在隐式范例转换。

这里辨别一下Truthy范例和Falsy范例值。

Falsy范例值包含:
"",
0,
null,
undefined,
NaN,
false

除了Falsy范例值之外的都被称为Truthy范例值,它们会被转换为
true

Boolean(null)         // false
Boolean('hello')      // true 
Boolean('0')          // true 
Boolean(' ')          // true 
Boolean([])           // true 
Boolean(function(){}) // true

Number 范例

依据 ECMAScript 范例,JavaScript 中只要一种数字范例:基于 IEEE 754 范例的双精度 64 位二进制花样的值(-(263 -1) 到 263 -1)。它并没有为整数给出一种特定的范例。除了可以示意浮点数外,另有一些带标记的值:+Infinity,-Infinity 和 NaN (非数值,Not-a-Number)。
整数可以用十进制(基数为10)、十六进制(基数为16)、八进制(基数为8)以及二进制(基数为2)的字面值来示意。

0, 117 and -345 (十进制, 基数为10)
015, 0001 and -0o77 (八进制, 基数为8) 
0x1123, 0x00111 and -0xF1A7 (十六进制, 基数为16或"hex")
0b11, 0b0011 and -0b11 (二进制, 基数为2)

浮点数(风趣的一点是,在盘算前其存储为字符串)所占有的内存空间是整数的两倍。
语法:[(+|-)][digits][.digits][(E|e)[(+|-)]digits]

3.14      
-.2345789 // -0.23456789
-3.12e+12  // -3.12*1012
.1e-23    // 0.1*10-23=10-24=1e-24

NaN:
1、即非数值,是一个特别的值,这个数值用于示意一个原本要返回数值的操纵数,未返回数值的状况。比方任何数值除以0,本是不符合范例的,js里,如许的操纵返回NaN(然则现实上,只要0除以0时返回NaN,其他则无限值)。

2、NaN有两个差别寻常的特性:任何触及NaN的操纵都邑返回NaNNaN值与任何值都不相称,包含本身。
3、isNaN()函数,这个函数可以推断,通报的参数是不是“不是数值”这里触及数值转换的题目,比方“10”这个字符串就可以转换为10,然则“blue”这个字符串则没法转换为数字,所以isNaN("blue")==true

+0 === -0  //true
42 / +0; // Infinity
42 / -0; // -Infinity
NaN == NaN //false

+Infinity,-Infinity:
要搜检值是不是大于或小于 +/-Infinity,你可以运用常量 Number.MAX_VALUENumber.MIN_VALUE。别的在 ECMAScript 6 中,你也可以经由过程 Number.isSafeInteger() 要领另有 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 来搜检值是不是在双精度浮点数的取值局限内。 超越这个局限,JavaScript 中的数字不再平安了,也就是只要 second mathematical interger 可以在 JavaScript 数字范例中准确表现。

String 范例

这个算是比较熟习的了这里援用一下MDN的形貌。
JavaScript的字符串范例用于示意文本数据。它是一组16位的无标记整数值的“元素”。在字符串中的每一个元素占有了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数目。
差别于类 C 言语,JavaScript 字符串是不可变动的。这意味着字符串一旦被建立,就不能被修正。然则,可以基于对原始字符串的操纵来建立新的字符串。
重要强调一下ES2015的模板字符串:

// Basic literal string creation
`In JavaScript '\n' is a line-feed.`

// Multiline strings
`In JavaScript this is
 not legal.`

// String interpolation
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

// Construct an HTTP request prefix is used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
     Content-Type: application/json
     X-Credentials: ${credentials}
     { "foo": ${foo},
       "bar": ${bar}}`(myOnReadyStateChangeHandler);
       

String()函数可以将任何范例的值转换为字符串,包含
null转换为
'null'
undefined转换为
'undefined'

Symbol 范例

语法:Symbol([description])
1、每一个从Symbol()返回的symbol值都是唯一的。
直接运用Symbol()建立新的symbol范例,并用一个字符串(可省略)作为其形貌。以下代码建立了三个新的symbol范例。 字符串 “foo” 的作用仅为形貌,它每次都邑建立一个新的 symbol范例:

var sym1 = Symbol();
var sym2 = Symbol('foo');
var sym3 = Symbol('foo');
Symbol("foo") === Symbol("foo"); // false

还可以运用Symbol.for要领建立新的symbol范例,和前者区分Symbol.for()会把symbol值以一个key值登记到全局环境中,Symbol()就不会。Symbol.for()不会每次挪用就返回一个新的 Symbol 范例的值,而是会先搜检给定的key是不是已存在,假如不存在才会新建一个值。比方,假如你挪用Symbol.for("cat")30 次,每次都邑返回同一个 Symbol 值,然则挪用Symbol("cat")30 次,会返回 30 个差别的 Symbol 值。检察登记的Symbol值可以运用Symbol.keyFor要领,该要领返回一个已登记的 Symbol 范例值的key。

let sym1 = Symbol('foo');
let sym2 = Symbol('foo');
let sym3 = Symbol.for('foo');
let sym4 = Symbol.for('foo');
sym1 === sym2  //false
sym3 === sym4  //true
Symbol.keyFor(sym1) //undefined
Symbol.keyFor(sym3) //"foo"

2、 不再支撑new 运算符的语法:

var sym = new Symbol(); // TypeError

这会阻挠建立一个显式的 Symbol 包装器对象而不是一个 Symbol 值。缭绕原始数据范例建立一个显式包装器对象从 ECMAScript 6 最先不再被支撑。 但是,现有的原始包装器对象,如 new Boolean、new String以及new Number由于遗留缘由仍可被建立。

3、特别的范例转换
Symbol 值不能与其他范例的值举行运算。
Symbol 值可以显式转为字符串、布尔值,然则不能转为数值。

4、用于对象属性名(重要)
Symbol 值作为对象属性名时,不能用点运算符。平常经由过程方括号组织和Object.defineProperty,将对象的属性名指定为一个 Symbol 值。

let sym1 = Symbol();
let sym2 = Symbol();
let sym3 = Symbol();

let a = {
  [sym1]: 'Symbol1';
};
a[sym2] = 'Symbol2';
Object.defineProperty(a, sym3, { value: 'Symbol3' });

a.sym1 = 'Hello!';
a[sym1] // "Symbol1"
a['sym1'] // "Hello!"

Symbol 作为属性名,该属性不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回。然则,它也不是私有属性,有一个Object.getOwnPropertySymbols要领,返回一个数组,成员是当前对象的一切用作属性名的 Symbol 值。

更多的Symbol相干内容参考这篇文章——
传送门

对象

在盘算机科学中, 对象是指内存中的可以被标识符援用的一块地区。
对象属于庞杂数据范例,也可以说是援用范例(逻辑上等价于class/类)。相对于原始数据范例的直接存取(栈内存),庞杂数据范例的存储体式格局为援用(堆内存,栈内存保留对应的指针)。

Object 对象

ECMAScript 中的一切对象都由这个对象继续而来,Object 对象中的一切属性和要领都邑出现在其他对象中,所以明白了 Object 对象,就可以更好地明白其他对象。
本文重要引见以下几点:

  • Object()作为函数以及Object()组织函数
  • Object静态要领
  • Object实例要领

1、Object()与new Object()
Object函数可以把恣意值转换为对象;new Object()则是天生新对象,可以简写为{}。除语义上的差别外,二者的用法雷同,以下以Object()为例:

var obj = Object();
var obj = Object(undefined);
var obj = Object(null);
//以上语句等效,返回空对象
obj instanceof Object // true

var obj = Object(1);
obj instanceof Object // true
obj instanceof Number // true

var obj = Object('foo');
obj instanceof Object // true
obj instanceof String // true

var obj = Object(true);
obj instanceof Object // true
obj instanceof Boolean // true

假如参数原本就是一个对象便不需要转换,直接返回该对象:

var arr = [];
var obj = Object(arr); // 返回原数组
obj === arr // true

var value = {};
var obj = Object(value) // 返回原对象
obj === value // true

var fn = function () {};
var obj = Object(fn); // 返回原函数
obj === fn // true

2、Object静态要领
所谓“静态要领”,是指布置在Object对象本身的要领。比方:Object.key = value{key:value}
平常运用Object.keys要领和Object.getOwnPropertyNames要领来遍历对象的属性。区分在于后者可以罗列不可罗列的属性名,比方数组的length

var a = ['Hello', 'World'];

Object.keys(a) // ["0", "1"]
Object.getOwnPropertyNames(a) // ["0", "1", "length"]

其他静态要领:(传送门)
1)对象属性模子的相干要领

  • Object.getOwnPropertyDescriptor():猎取某个属性的形貌对象。
  • Object.defineProperty():经由过程形貌对象,定义某个属性。定义key为Symbol的属性的要领之一。
  • Object.defineProperties():经由过程形貌对象,定义多个属性。

2)掌握对象状况的要领

  • Object.preventExtensions():防备对象扩大。
  • Object.isExtensible():推断对象是不是可扩大。
  • Object.seal():制止对象设置。
  • Object.isSealed():推断一个对象是不是可设置。
  • Object.freeze():凝结一个对象。
  • Object.isFrozen():推断一个对象是不是被凝结。

3)原型链相干要领

  • Object.assign(target, ...sources):用于将一切可罗列属性的值从一个或多个源对象复制到目的对象。它将返回目的对象。
  • Object.create():该要领可以指定原型对象和属性,返回一个新的对象。
  • Object.getPrototypeOf():猎取对象的Prototype对象。

3、Object实例要领
定义在Object.prototype的·对象称为实例要领,一切Object的实例对象都继续了这些要领。
Object实例对象的要领,重要有以下六个。

  • Object.prototype.valueOf():返回当前对象对应的值。
  • Object.prototype.toString():返回当前对象对应的字符串情势。检测对象范例。
  • Object.prototype.toLocaleString():返回当前对象对应的当地字符串情势。
  • Object.prototype.hasOwnProperty():推断某个属性是不是为当前对象本身的属性,照样继续自原型对象的属性。
  • Object.prototype.isPrototypeOf():推断当前对象是不是为另一个对象的原型。
  • Object.prototype.propertyIsEnumerable():推断某个属性是不是可罗列。

数据范例推断

之所以会说到这个推断题目,重要缘由是typeof是不太靠谱的。起首JavaScript是动态数据范例的言语,许多范例搜检是不必要的。在详细完成上的题目,在现实的项目运用中,typeof也只要两个用处,就是检测一个元素是不是为undefined,或许是不是为function。由下面的表格可见一斑:

Value               function   typeof
-------------------------------------
"foo"               String     string
new String("foo")   String     object
1.2                 Number     number
new Number(1.2)     Number     object
true                Boolean    boolean
new Boolean(true)   Boolean    object
new Date()          Date       object
new Error()         Error      object
[1,2,3]             Array      object
new Array(1, 2, 3)  Array      object
new Function("")    Function   function
/abc/g              RegExp     object
new RegExp("meow")  RegExp     object
{}                  Object     object
new Object()        Object     object 

假如照样要推断的话,公认的靠谱解法是 Object.prototype.toString.call(x) === '[object type]'。详细完成可以参考jQuery.type()源码。别的经由过程组织函数建立的对象都可以用 instanceof 搜检。

参考

  1. http://www.ruanyifeng.com/blo…
  2. https://zhuanlan.zhihu.com/p/…
  3. https://developer.mozilla.org…
  4. https://developer.mozilla.org…
  5. https://javascript.ruanyifeng…
  6. https://segmentfault.com/q/10…
    原文作者:Alvabill
    原文地址: https://segmentfault.com/a/1190000013697141
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞