JavaScript 数据类型使用小结
数据类型
原始类型(基本类型、标准类型):string、number、boolean、null、undefined
直接访问并操作实际值。特殊值 null、undefined。引用类型(对象类型、构造器类型):对象
常见内置对象:Object、Array、Date、Function、RegExp、Error等;
自定义对象:使用 new Object() 创建或字面形式创建(大括号内定义属性、属性值);
引用类型的值是保存在内存中的对象。
基本类型中的 number、string、boolean 都有对应的包装类型。
创建
a、new Object() 创建和使用自定义对象
var book = new Object();
book.name = "JavaScript";
book.year = 2015;
book.website = "www.w3cschool.cn";
b、字面形式:大括号内定义属性
// 创建对象(用字符串作为属性名称,对于有空格或其他特殊字符的属性名称很有用)
var book = {
name : "JavaScript",
year : 2015,
website: "www.w3cschool.cn"
};
var book = {
"name": "Java Script",
"year": 2015,
"website": "www.w3cschool.cn"
};
// 创建数组
var colors = [ "A", "B", "C" ];
var colors = new Array("A", "B", "C");
// 创建函数
function myMethod(value) {
return value;
}
var myMethod = new Function("value", "return value;");
// 正则表达式
var numbers = /\d+/g;
var numbers = new RegExp("\\d+", "g");
简介
日期
构造函数
- new Date();
- new Date(value);
value 代表自1970年1月1日00:00:00 (世界标准时间) 起经过的毫秒数,咱中国(东八区)应该从 1970年1月1日08:00:00 算起。 - new Date(dateString);
dateString 日期的字符串值。该字符串应该能被 Date.parse() 方法识别(符合 IETF-compliant RFC 2822 timestamps 或 version of ISO8601)。
测试分隔符范围 - new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
注意:Date 对象只能通过 Date 构造函数来实例化日期对象,如果以常规函数调用它(即不加 new 操作符)将会返回一个字符串,而不是一个日期对象。
方法
// 获取日期
new Date();// Tue Dec 12 2017 11:44:38 GMT+0800 (中国标准时间)
new Date().toString();// "Tue Dec 12 2017 11:45:32 GMT+0800 (中国标准时间)"
new Date().toDateString();// "Tue Dec 12 2017"
new Date().toLocaleDateString();// "2017/12/12"
Date.now();// 1513050291452
new Date(2017,01,01);// 表示2017-12-01
new Date('2017-12-01');// 等同于上面
new Date(yyyy, mm, dd - 1);// 上一日
new Date(yyyy, mm, dd + 1);// 下一日
new Date(yyyy, mm - 1, dd);// 上一月
// 获取日期中指定部分:月(0-11)、日(1-31)、周(0周日-6周六)、时(0-23)、分(0-59)、秒(0-59)
var date = new Date();
var y = date.getFullYear();
var mon = (date.getMonth() + 1) < 10 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1);
var d = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
var w = date.getDay();
var h = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
var m = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var s = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
对象
判断对象是否有某属性
1、in 关键字:可判断对象的自有属性和继承来的属性是否存在。
var o={x:1};
"x" in o; // true,自有属性存在
"y" in o; // false
"toString" in o; // true,是一个继承属性
2、对象的 hasOwnProperty() 方法:只能判断自有属性是否存在,对于继承属性会返回false。
var o={x:1};
o.hasOwnProperty("x"); // true,自有属性中有x
o.hasOwnProperty("y"); // false,自有属性中不存在y
o.hasOwnProperty("toString"); // false,这是一个继承属性,但不是自有属性
3、undefined :可判断自有属性和继承属性。
var o={x:1, x1:undefined };
o.x!==undefined; // true
o.x1!==undefined; // false,缺陷:属性值为 undefined 的判断不准确
o.y!==undefined; // false
o.toString!==undefined // true
4、条件语句中直接判断
var o={};
if(o.x) o.x+=1; // 如果x是 undefine、null、false、""、0、-0、NaN,它将保持不变
// 判断是否空对象
function isEmptyObject(obj) {
var name;
for (name in obj) {
return false;
}
return true;
}
JSON
JSON.stringify(value[, replacer [, space]])
参考JSON.stringify的三个参数
能接收 3 个参数,后面 2 个参数是可选的。
第一个参数:
stringily 对 data 里的数据类型有一些要求:
1、非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中;
2、就是不能保证hash结构的顺序是按照定义输出;
JSON.stringify({x: 5, y: 6});
// '{"x":5,"y":6}' 或者 '{"y":6,"x":5}' 都可能
3、布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
4、undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。
var obj = {"undefined":undefined,"func":function(){},"symbol":Symbol("")};
JSON.stringify(data); //"{}"
var arr = [undefined,Symbol(""),function(){}];
JSON.stringify(arr); //[null,null,null]
5、所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
JSON.stringify({[Symbol("foo")]: "foo"}); //'{}'
6、不可枚举的属性会被忽略
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) );
// '{"y":"y"}'
类型转换
- 巧用 + 和 - 规则转换
把变量转换成数字:num-0;
把变量转换成字符串:num+”; - a == b
“1.23” == 1.23
0 == false
null == undefined
类型相同,同 ===;类型不同,尝试类型转换后比较。
number == string :string 转 number 后比较
null == undefined :相等 - a === b
类型不同,返回 false ,类型相同:
null === null
undefined === undefined
类型检测
参考 javascript 六种数据类型(一)、类型识别、数据类型、剖析 JavaScript 各种蛋疼的类型转换、JavaScript 数据类型的判断(这里有一个将类型检测封装成了 JS 插件)
JavaScript 的数据类型可以分为:基本类型和对象类型。
基本类型:undefined、null、string、number、boolean
引用类型:Object、Array、Date、Function、RegExp、Error
总结:判断基本类型用 typeof(null 除外),判断引用类型用 instanceof 。通用判断基本类型和引用类型用Object.prototype.toString.call()。
- typeof
返回一个字符串,指示未经计算的操作数的类型。
适用: 基本类型 (null 除外)。
不适:对象类型(function 除外)。
特殊:typeof null 返回“object”(这是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了。现在,null 被认为是对象的占位符,从而解释了这一矛盾,但从技术上来说,它仍然是原始值)。
typeof("1"); // "string"
typeof(1); // "number"
typeof(true); // "boolean"
typeof(undefined); // "undefined"
typeof(null); // "object",竟然把 null 当作了对象
typeof({}); // "object"
typeof([]); // "object"
typeof(new Date()); // "object"
typeof(new Function()); // "function",竟然认出了函数
typeof(/\d/); // "object"
typeof(new Error()); // "object"
instanceof
适用:内置对象、自定义对象
不适:基本类型坑:不同 window 或 iframe 之间的对象类型检测不能使用 instanceof。
基于原型链操作:obj instanceof Object。
使用 instaceof 和 construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array == object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;切记,不然很难跟踪问题!
原理:判断左边的左操作数的对象的原型链上是否有右边这个构造函数的prototype属性。
左操作数为对象,不是就返回false,右操作数必须是函数对象或者函数构造器,不是就返回typeError异常。Object.prototype.toString
适用:基本类型(null 和 undefined 除外)、内置对象
不适:自定义对象兼容性:IE6/7/8 检测 null 或 undefined 返回“[object Object]”,若忽视 IE 可使用。
console.log(Object.prototype.toString.call(null)) IE6/7/8 期望[object Null],但返回[object Object]
// 谷歌浏览器测试
Object.prototype.toString.call(""); // "[object String]"
Object.prototype.toString.call(1); // "[object Number]"
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({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(new Date()); // "[object Date]"
Object.prototype.toString.call(new Function()); // "[object Function]"
Object.prototype.toString.call(/\d/); // "[object RegExp]"
Object.prototype.toString.call(new Error()); // "[object Error]"
- constructor
适用:基本类型(null 和 undefined 除外)、内置对象、自定义对象
坑:constructor 可以被改写,使用要小心。
任何对象都有 constructor 属性,继承自原型的,constructor会指向构造这个对象的构造器或者构造函数。但 constructor 可以被改写,使用时需小心。
function getConstructiorName(obj) {
return obj && obj.constructor && obj.constructor.toString().match(/function\s*([^(]*)/)[1];
}
getConstructiorName([]) === "Array"; // true
- duck type(是程序设计中动态类型和某些静态语言的一种对象推断风格)
比如不知道一个对象是不是数组,可以判断它是不是有join、push这样一些数组的方法。通过一些特征判断对象是否属于某些类型,这个有时候也常用。