以下内容摘自阮一峰-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