变量
变量是对”值“的具名引用,说直白点儿就是为”值“赋个名字,然后引用它,变量的名字就是变量名
变量有变量提升和区块作用域的概念,变量名的命名(标识符)是区分大小写的,还有一些不合法的标识符以及保留字不能作为命名,var 声明的作用域是全局的,let和const后面会补充
JS中的变量都是保存在栈内存中的
1. 基本数据类型的值直接在栈内存中存储,值与值之间是独立存在,修改一个变量不会影响其他变量 2. 对象是保存代堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个变量修改属性时,另一个也会受到影响
类型
javascript中有8种数据类型(7种原始类型和1种引用类型)
原始数据类型
分为7种:number,string,boolean,null,undefined,bigint,symbol
引用数据类型
就1种:object,其内部又分为array,function,object等等
判断值类型
三种方法:
typeof运算符instanceof运算符Object.prototype.toString()方法
1、typeof运算符可以返回一个值的数据类型
- 数值、字符串、布尔值分别返回
number、string、boolean - 函数返回
function - bigint类型的返回
bigint,如1n、BigInt(1)等 undefined返回undefined- 对象返回
object:数组[]返回object,instanceof运算符可以进一步判断数组类型是Array, 后面会补充 null返回object:这是由于历史原因造成的
2、instanceof运算符返回一个布尔值,表示对象是否为某个构造函数的实例,instanceof运算符的左边是实例对象,右边是构造函数。它会检查右边构建函数的原型对象(prototype),是否在左边对象的原型链上
-
由于任意对象(除了
null)都是Object的实例,所以instanceof运算符可以判断一个值是否为非null的对象 -
instanceof运算符只能用于对象,不适用原始类型的值 -
对于
undefined和null,instanceof运算符总是返回false -
利用
instanceof运算符,还可以巧妙地解决,调用构造函数时,忘了加new命令的问题function Fubar (foo, bar) { if (this instanceof Fubar) { this._foo = foo; this._bar = bar; } else { return new Fubar(foo, bar); } }
3、Object.prototype.toString()方法的作用是返回一个对象的字符串形式,默认情况下返回类型字符串
-
数组、字符串、函数、Date 对象都分别部署了自定义的toString方法,覆盖了
Object.prototype.toString方法,最好直接使用Object.prototype.toString.call(value)方法 -
不同数据类型的值返回结果如下:
- 数值:返回`[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]` - 等等... -
利用这个特性,可以写出一个比
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