JS数据类型& 推断

以下内容摘自阮一峰-JavaScript-规范参考教程

数据范例

JavaScript 言语的每个值,都属于某一种数据范例。JavaScript 的数据范例,共有六种。(ES6 又新增了第七种 Symbol 范例的值)

数值(number):整数和小数(比方1和3.14)
字符串(string):文本(比方Hello World)。
布尔值(boolean):示意真伪的两个特别值,即true(真)和false(假)
undefined:示意“未定义”或不存在,即由于现在没有定义,所以此处临时没有任何值
null:示意空值,即此处的值为空。
对象(object):种种值构成的鸠合。

平常,数值、字符串、布尔值这三种范例,合称为原始范例(primitive type)的值,即它们是最基本的数据范例,不能再细分了。对象则称为合成范例(complex type)的值,由于一个对象每每是多个原始范例的值的合成,能够看做是一个寄存种种值的容器。至于undefined和null,平常将它们算作两个特别值。

对象是最庞杂的数据范例,又能够分红三个子范例。

  • 对象(object)
  • 数组(array)
  • 函数(function)

推断数据范例

JavaScript 有三种要领,能够肯定一个值究竟是什么范例。

  • typeof运算符
  • instanceof运算符
  • Object.prototype.toString要领

typeof运算符

typeof运算符能够返回一个值的数据范例。

数值、字符串、布尔值离别返回number、string、boolean。

typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"

函数返回function。

function f() {}
typeof f
// "function"
      

undefined返回undefined

typeof undefined
// "undefined"

这个特征平常用在推断语句

if (typeof v === "undefined") {
  // ...
}  
  

对象返回object。

typeof window // "object"
typeof {} // "object"
typeof [] // "object"*

null返回object。

 `typeof null // "object"

instanceof 运算符

instanceof运算符能够辨别数组和对象。
instanceof运算符返回一个布尔值,示意某个对象是不是为指定的组织函数的实例。

var o = {};
var a = [];

o instanceof Array // false
a instanceof Array // true

var v = new Vehicle();
v instanceof Vehicle // true

上面代码中,对象v是组织函数Vehicle的实例,所以返回true。

instanceof运算符的左侧是实例对象,右侧是组织函数。它会搜检右侧构建函数的原型对象(prototype),是不是在左侧对象的原型链上。因而,下面两种写法是等价的。

 v instanceof Vehicle
// 等同于
Vehicle.prototype.isPrototypeOf(v)
    

由于instanceof对全部原型链上的对象都有效,因而同一个实例对象,能够会对多个组织函数都返回true。

var d = new Date();
d instanceof Date // true
d instanceof Object // true

上面代码中,d同时是Date和Object的实例,因而对这两个组织函数都返回true。

instanceof的道理是搜检原型链,关于那些不存在原型链的对象,就没法推断。

Object.create(null) instanceof Object // false

上面代码中,Object.create(null)返回的新对象的原型是null,即不存在原型,因而instanceof就以为该对象不是Object的实例。

除了上面这类继续null的特别情况,JavaScript 当中,只假如对象,就有对应的组织函数。因而,instanceof运算符的一个用途,是推断值的范例。

var x = [1, 2, 3];
var y = {};
x instanceof Array // true
y instanceof Object // true

上面代码中,instanceof运算符推断,变量x是数组,变量y是对象。

注重,instanceof运算符只能用于对象,不实用原始范例的值。

var s = 'hello';
s instanceof String // false

上面代码中,字符串不是String对象的实例(由于字符串不是对象),所以返回false。

另外,关于undefined和null,instanceOf运算符老是返回false。

undefined instanceof Object // false
null instanceof Object // false

运用instanceof运算符,还能够奇妙地处理,挪用组织函数时,忘了加new敕令的题目。

function Fubar (foo, bar) {
  if (this instanceof Fubar) {
    this._foo = foo;
    this._bar = bar;
  }
  else {
    return new Fubar(foo, bar);
  }
}

上面代码运用instanceof运算符,在函数体内部推断this关键字是不是为组织函数Fubar的实例。假如不是,就表明忘了加new敕令。

Object.prototype.toString()

toString要领的作用是返回一个对象的字符串情势,默许情况下返回范例字符串。

var o1 = new Object();
o1.toString() // "[object Object]"

var o2 = {a:1};
o2.toString() // "[object Object]"

上面代码示意,关于一个对象挪用toString要领,会返回字符串[object Object],该字符串申明对象的范例。
字符串[object Object]自身没有太大的用途,然则经由过程自定义toString要领,能够让对象在自动范例转换时,获得想要的字符串情势。

var obj = new Object();

obj.toString = function () {
  return 'hello';
};

obj + ' ' + 'world' // "hello world"

上面代码示意,当对象用于字符串加法时,会自动挪用toString要领。由于自定义了toString要领,所以返回字符串hello world。

数组、字符串、函数、Date 对象都离别布置了自定义的toString要领,掩盖了Object.prototype.toString要领。

[1, 2, 3].toString() // "1,2,3"

'123'.toString() // "123"

(function () {
  return 123;
}).toString()
// "function () {
//   return 123;
// }"

(new Date()).toString()
// "Tue May 10 2016 09:11:31 GMT+0800 (CST)"

上面代码中,数组、字符串、函数、Date 对象挪用toString要领,并不会返回[object Object],由于它们都自定义了toString要领,掩盖原始要领。

**toString() 的运用:推断数据范例
Object.prototype.toString要领返回对象的范例字符串,因而能够用来推断一个值的范例。**

var obj = {};
obj.toString() // "[object Object]"

上面代码挪用空对象的toString要领,结果返回一个字符串object Object,个中第二个Object示意该值的组织函数。这是一个异常有效的推断数据范例的要领。

由于实例对象能够会自定义toString要领,掩盖掉Object.prototype.toString要领,所以为了获得范例字符串,最好直接运用Object.prototype.toString要领。经由过程函数的call要领,能够在恣意值上挪用这个要领,协助我们推断这个值的范例。

Object.prototype.toString.call(value)

上面代码示意对value这个值挪用Object.prototype.toString要领。

差别数据范例的Object.prototype.toString要领返回值以下。

数值:返回[object Number]。
字符串:返回[object String]。
布尔值:返回[object Boolean]。
undefined:返回[object Undefined]。
null:返回[object Null]。
数组:返回[object Array]。
arguments 对象:返回[object Arguments]。
函数:返回[object Function]。
Error 对象:返回[object Error]。
Date 对象:返回[object Date]。
RegExp 对象:返回[object RegExp]。
其他对象:返回[object Object]。

这就是说,Object.prototype.toString能够看出一个值究竟是什么范例。

Object.prototype.toString.call(2) // "[object Number]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(Math) // "[object Math]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"

运用这个特征,能够写出一个比typeof运算符更正确的范例推断函数。

    var type = function (o){
      var s = Object.prototype.toString.call(o);
      return s.match(/\[object (.*?)\]/)[1].toLowerCase();
    };
    
    type({}); // "object"
    type([]); // "array"
    type(5); // "number"
    type(null); // "null"
    type(); // "undefined"
    type(/abcd/); // "regex"
    type(new Date()); // "date"

在上面这个type函数的基础上,还能够加上特地推断某种范例数据的要领。

var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

['Null',
 'Undefined',
 'Object',
 'Array',
 'String',
 'Number',
 'Boolean',
 'Function',
 'RegExp'
].forEach(function (t) {
  type['is' + t] = function (o) {
    return type(o) === t.toLowerCase();
  };
});

type.isObject({}) // true
type.isNumber(NaN) // true
type.isRegExp(/abc/) // true

null 和 undefined

null与undefined都能够示意“没有”,寄义异常类似。将一个变量赋值为undefined或null,老实说,语法结果险些没区分。

在if语句中,它们都会被自动转为false,相称运算符(==)以至直接报告二者相称。

if (!undefined) {
  console.log('undefined is false');
}
// undefined is false

if (!null) {
  console.log('null is false');
}
// null is false

undefined == null
// true

null是一个示意“空”的对象,转为数值时为0;undefined是一个示意”此处无定义”的原始值,转为数值时为NaN

Number(null) // 0
5 + null // 5

Number(undefined) // NaN
5 + undefined // NaN

null,undefined 用法
关于null和undefined,大抵能够像下面如许明白。

null示意空值,即该处的值现在为空。挪用函数时,某个参数未设置任何值,这时候就能够传入null,示意该参数为空。比方,某个函数接收引擎抛出的毛病作为参数,假如运转过程当中未失足,那末这个参数就会传入null,示意未发作毛病。

undefined示意“未定义”,下面是返回undefined的典范场景。

// 变量声清楚明了,但没有赋值
var i;
i // undefined

// 挪用函数时,应当供应的参数没有供应,该参数即是 undefined
function f(x) {
  return x;
}
f() // undefined

// 对象没有赋值的属性
var  o = new Object();
o.p // undefined

// 函数没有返回值时,默许返回 undefined
function f() {}
f() // undefined

布尔值

布尔值代表“真”和“假”两个状况。“真”用关键字true示意,“假”用关键字false示意。布尔值只要这两个值。

以下运算符会返回布尔值:

两元逻辑运算符: && (And),|| (Or)
前置逻辑运算符: ! (Not)
相称运算符:===,!==,==,!=
比较运算符:>,>=,<,<=

假如 JavaScript 预期某个位置应当是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true。

undefined
null
false
0
NaN
""或''(空字符串)

布尔值每每用于顺序流程的掌握,请看一个例子。

if ('') {
  console.log('true');
}

// 没有任何输出
上面代码中,if敕令背面的推断前提,预期应当是一个布尔值,所以 JavaScript 自动将空字符串,转为布尔值false,致使顺序不会进入代码块,所以没有任何输出。

注重,空数组([])和空对象({})对应的布尔值,都是true。

if ([]) {
  console.log('true');
}
// true

if ({}) {
  console.log('true');
}
// true
    原文作者:orangecat00
    原文地址: https://segmentfault.com/a/1190000013243913
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞