前言
在《你所不知道的javascript上篇》书籍 以及《javascript权威指南》等书籍里面, 均有介绍js的数据类型,对象,原型,继承。结合工作经验, 以及借用一些开源库和框架的源码, 进行一次梳理。 首先介绍数据类型 ~~
数据类型
js 目前有以下几大数据类型
undefined
null
string
boolean
number
-
symbol
(ES6新增) object
undefined
类型
原始值类型. 表示某个变量已经声明, 但是未分配内存空间给予该变量.
var foo;
console.log(foo); /* 申明变量, 却没有赋值 */
function bar (a) {
console.log(a); /* 函数形参声明, 却没有对应实参赋值 */
}
bar();
function foo2 () {}
var bar2 = foo2(); /* 函数无return 或者, return 不带任何返回值 */
var o = {foo: 'foo'}
console.log(o.bar); /* 在对象中寻找不存在的属性 */
var foo = 'foo';
foo = undefined; /* 显示将某个变量指向undefined, 消除引用标记 */
null
类型
原始值类型. 声明变量此时为一个空的原始值. 由于历史原因, 使用typeof null
返回 object
表示为一个对象.
如果要验证一个变量是否为null, 可以有以下几种方式
function is_null (o) {
return o === null;
}
function is_null (o) {
return Object.prototype.toString.call(o) === '[object Null]';
}
string
类型
原始值类型. string
属于不可变值类型, 当一个字符串进行相加后, 返回一个新的字符串引用。
var str = 'hello world';
str = str + ' liyanlong';
// 1. 栈内存 创建一个str变量
// 2. 'hello wolrd' 内容存储在堆中, 并将引用赋给 str变量
// 3. 获取str的变量引用, 与新字符串 ` liyanlong` 进行连接操作. 产生新的引用地址并传给str
简单理解: string
类型的内容与 object
的 内容都存储在堆中。不同的一点是, 无法对string
的堆进行修改, 任何连接,分割字符串的操作都会产生一个新的堆引用。
boolean
类型
原始值类型, 只有true
, false
两个原始值.
typeof true // boolean
typeof false // boolean
number
类型
原始值类型. 存储一切数值类型, 包括正负数, 整数, 小数, 科学计数.
typeof NaN // number
typeof Infinity // number
typeof 0 // number
typeof 1e2 // number
typeof -0.5 // number
检查一个变量是否可成为无法成为合法的 number
类型
window.isNaN('12') // false
window.isNaN('foo') // true
检查number是否为有限的number
(非无穷)值
window.isFinite('123') // true
window.isFinite(Infinity) // false
symbol
类型
原始值类型. 属于ES6新增的一种数据类型. ES6允许属性的key
为 symbol
类型. 以此可以提供一个私有的属性
let obj = (function () {
let key = Symbol('你好');
let obj = {
};
obj[key] = '私有变量';
return {
get foo () {
return this[key];
}
};
})();
obj.foo = 'hello world';
console.log(Object.getOwnPropertyNames(obj)); // ['foo']
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(你好)]
let anotherKey = Symbol('你好');
console.log(obj[anotherKey]) // undefined
typeof anotherKey // 'symbol'
object
类型
引用类型. js中常见的引用对象 有Array
, Object
, Date
.
var arr = [];
var o = {};
var date = new Date()
typeof o // object
typeof arr // object
typeof date // object
函数也属于对象类型, 它是一种可调用的对象, 并且能创建调用栈执行内部代码. 只是函数在执行typeof
时,返回的是function
function Foo() {
}
typeof Foo // function
Foo instanceof Object // true
值类型与引用类型
值类型属于不可变类型, 由于具有固定长度大小, 因此可以存放在栈内存中,而引用类型属于可变类型, 一个对象可以赋予多个属性及值,属性值又可以为一个新的引用对象。因此将引用类型存放在堆中
包装类型
为了方便boolean
, number
, string
基本类型的处理及调用, 当我们在执行toString()
, valueOf()
, +操作符
以及函数方法的时候, 会隐世转换为Boolean
,Number
, String
对象类型. 执行后返回的又是基本类型。
var bool = true
var number = 1
var string = 'hello world'
console.log(bool + number) // 2
// 相当于
console.log(Boolean(bool).valueOf() + number) // 2
console.log(bool + string) // true hello world
// 相当于
console.log(Boolean(bool).toString() + string) // true hello world
string.charAt(0) // h
// 相当于
console.log(String(string).charAt(0)) // h
// 基础类型不属于包装的对象类型
bool instanceof Boolean // false
number instanceof Number // false
string instanceof String // false
小结
数据类型是每一个语言的基础. 由于js属于弱类型脚本语言, 因此数据只有在赋值后才能直到变量的数据类型. 下一次我们具体介绍js对象的概念.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。