Javascript中的数据类型知多少
JavaScript 是一种弱类型或者说动态语言。这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。这也意味着你可以使用同一个变量保存不同类型的数据
根据ECMAScript 5.1的规范,javascript中共有六种数据类型,分别为:Undefined
, Null
, Boolean
,Number
, String
、Object
。前五种属于基本类型,最后一种属于Object类型。
最新的ECMAScript 6 又加了一种类型:Symbol (ECMAScript 6 新定义)
基本数据类型
Undefined:
只有一个值,为undefined
,意味着“空值(no value)”,适用于所有数据类型。Null:
只有一个值,为null
,意味着“空对象(no object)”,只适用于对象类型。(literal)Boolean
:有两个值,为true
与false
Number
:的值是遵循IEEE 754标准的64位浮点数的集合,没有整型数据结构。此外还包含三个特殊的值:NaN
、Infinity
、-Infinity
String
:值是有穷个Unicode字符的集合。必须用'
或"
括起来。
一、String
JavaScript的字符串类型用于表示文本数据。它是一组16位的无符号整数值的“元素”。在字符串中的每个元素占据了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数量
与 C 语言不同,JavaScript 中字符串是不可变的(译注:如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)
Javascript中一切都是object-based
创建string,也有两种类型
1、使用字面量方式创建的字符串,为基本类型的string //string 实际上保存就是的值,是一个基本类型
2、使用String()
创建的字符串,为基本类型的string // string
3、使用构造函数 new String()
的方式创建的字符串,为对象类型的 //string 实际上保存的是一个指向字符串对象的指针
看代码
var obj = 'abc';
obj.something = 1;
var firstChar = obj.charAt(0); //"a"
console.log(obj.something); //undefined
//实际上js做了这样的处理
var obj = 'abc';
var temp = new String(obj);
var firstChar = temp.charAt(0); //"a"
temp.something = 1;
temp = null;
console.log(obj.something); //undefined
原因是,创建了一个临时的引用类型变量去访问属性,修改属性,然后就被释放了
再看一个例子
var str1 = "javascript"; //typeof str1 == string
var str2 = String("javascript"); //typeof str2 == string 不推荐
var str3 = new String('javascript'); //typeof str3 == object
new Sting 和 string的区别
s1 = "2 + 2"; // creates a string primitive
s2 = new String("2 + 2"); // creates a String object
console.log(eval(s1)); // returns the number 4
console.log(eval(s2)); // returns the string "2 + 2"
也就是说使用对象的时候,不会做类型转换
字符串对象的转换 valueof -》 string
console.log(eval(s2.valueOf())); // returns the number 4
二、boolean
不要将原始值true false,和值为true false的Boolean对象相混淆
1、如果Boolean构造函数的参数不是一个布尔值,则该参数会被转换成一个布尔值
2、如果参数是 0
, -0
, null
,false
, NaN
, undefined
, 或者空字符串 (""),生成的Boolean对象的值为false. 其他任何值,包括任何对象或者字符串"false"
, 都会创建一个值为true的Boolean对象
var x = new Boolean(false); if(x){
console.log(x.valueOf(),typeof x); // false object
}
上面会执行,很神奇的代码
不要通过新建Boolean
对象的方法来将一个非布尔值转化成布尔值. 直接使用Boolean函数才是正确的
var x = Boolean(expression); // 这样用
var x = new Boolean(expression); // 而不要这样!
初始化的时候
//false
var bNoParam = new Boolean();
var bZero = new Boolean(0);
var bNull = new Boolean(null);
var bEmptyString = new Boolean("");
var bfalse = new Boolean(false); //true
var btrue = new Boolean(true);
var btrueString = new Boolean("true");
var bfalseString = new Boolean("false");
var bSuLin = new Boolean("Su Lin");
三、Number
根据 ECMAScript 标准,JavaScript 中只有一种数字类型:基于 IEEE 754 标准的双精度 64 位二进制格式的值(-(253 -1) 到 253 -1)。它并没有为整数给出一种特定的类型。除了能够表示浮点数外,还有一些带符号的值:+Infinity
,-Infinity
和 NaN
(非数值,Not-a-Number)
数字类型只有一个整数,它有两种表示方法: 0 可表示为 -0 和 +0("0" 是 +0 的简写)。 在实践中,这也几乎没有影响。 例如 +0 === -0
为真。 但是,你可能要注意除以0的时候:
42 / +0; // Infinity
42 / -0; // -Infinity
如果参数无法被转换为数字,则返回 NaN
。
在非构造器上下文中 (如:没有 new 操作符),Number
能被用来执行类型转换
isNAN 类型判断
Number.isNaN(NaN); // true
Number.isNaN(Number.NaN); // true
Number.isNaN(0 / 0) // true // e.g. these would have been true with global isNaN()
Number.isNaN("NaN"); // false
Number.isNaN(undefined); // false
Number.isNaN({}); // false
Number.isNaN("blabla"); // false // These all return false
Number.isNaN(true);
Number.isNaN(null);
Number.isNaN(37);
Number.isNaN("37");
Number.isNaN("37.37");
Number.isNaN("");
Number.isNaN(" ");
原型链继承的关系
console.log(Number.prototype.__proto__ == Object.prototype); //true
console.log(Number.prototype.__proto__.__proto__ == Object.prototype.__proto__);//true
console.log(Object.prototype.__proto__ === null);//true
console.log(typeof Number);//function
使用 Number
转换 Date
对象
var d = new Date("December 17, 1995 03:24:00");
console.log(Number(d));
四、Null
null
是一个 JavaScript 字面量,表示空值(null or an "empty" value),即没有对象被呈现(no object value is present)。它是 JavaScript 原始值 之一。
null
是一个字面量 (而不是全局对象的一个属性,undefined
是 )
console.log(null); //null
console.log(undefined);//undefined console.log(window.null);//undefined
console.log(window.undefined);//undefined
null与undefined的区别
console.log(foot);//Uncaught ReferenceError: foot is not defined var foo;
console.log(foo);//undefined var bar =null;
console.log(bar);//null typeof null // object (bug in ECMAScript, should be null)
typeof undefined // undefined
null === undefined // false
null == undefined // true
所以判断null,可以判断类型 + 值
五、Undefined
在JavaScript中,undefined这个词有多重含义.首字母大写的Undefined表示的是一种数据类型,小写的undefined表示的是属于这种数据类型的唯一的一个值.但这两种undefined都只能存在于文档或规范中,不能存在于JavaScript代码中.在JavaScript代码中,你看到的undefined最有可能是全局对象的一个属性
,该属性的初始值是就是前面所说的原始值undefined
,还有种情况就是,这个undefined
是个局部变量,就像其他普通变量一样,没有任何特殊性,它的值不一定是undefined
,但通常情况下都是的.下面我们所说的undefined
,都指的是window.undefined
这个属性.
在ES3中(Firefox4之前),window.undefined
就是一个普通的属性,你完全可以把它的值改变成为任意的真值,但在ES5中((Firefox4之后),window.undefined
成了一个不可写,不可配置的数据属性,它的值永远是undefined
.
一个未初始化的变量的值为undefined
,一个没有传入实参的形参变量的值为undefined
,如果一个函数什么都不返回,则该函数默认返回undefined
.
你可以使用严格相等运算符来判断一个值是否是undefined
:
var foo;
console.log(foo === undefined);//true
console.log(typeof foo === 'undefined');//true
console.log(window.foo === undefined);//true console.log(bar === undefined);//Uncaught ReferenceError: bar is not defined
console.log(typeof bar === 'undefined');//true
console.log(window.bar === undefined);//true console.log(typeof undefined == 'undefined'); //true
console.log(typeof null == 'object');//true
console.log(null == undefined);//true
console.log(null === undefined);//false
总结
Null
的值是null
,表示一个空对象指针,没有指向任何对象Undefined
的值是undefined
,表示申明变量或对象的属性却未初始化undefined
值是派生自null
的,所以对他们执行相等测试会返回true
- 数值、布尔值、对象和字符串值都有
toString()
方法。但null
和undefined
值没有这个方法
多数情况下,调用toString()
方法不必传递参数。但是,在调用数值的toString()
方法时,可以传递一个参数:输出数值的基数
var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010"
alert(num.toString(8)); //"12"
alert(num.toString(10)); //"10"
alert(num.toString(16)); //"a"
在不知道要转换的值是不是null
或undefined
的情况下,还可以使用转型函数String()
,这个函数能够将任何类型的值转换为字符串。String()
函数遵循下列转换规则:
● 如果值有toString()
方法,则调用该方法(没有参数)并返回相应的结果
● 如果值是null
,则返回"null
"
● 如果值是undefined
,则返回"undefined
"
六、Object
Javascript中一切皆Object
// Objects
typeof {a:1} === 'object'; // 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型
typeof [1, 2, 4] === 'object'; typeof new Date() === 'object'; // 下面的容易令人迷惑,不要这样使用!
typeof new Boolean(true) === 'object';
typeof new Number(1) ==== 'object';
typeof new String("abc") === 'object'; // 函数
typeof function(){} === 'function';
typeof Math.sin === 'function';
实例化一个空Object
var o = new Object();
var o = new Object(undefined);
var o = new Object(null);
var o = {};
原型
定义属性为__proto__: 值
或 "__proto__": 值
时,不会创建名为__proto__属性。如果给出的值是对象或者
null
,那么对象的[[Prototype]]会被设置为给出的值。(如果给出的值不是对象也不是null,那么对象的原型不会改变。)
var obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype); var obj2 = { __proto__: null };
assert(Object.getPrototypeOf(obj2) === null); var protoObj = {};
var obj3 = { "__proto__": protoObj };
assert(Object.getPrototypeOf(obj3) === protoObj); var obj4 = { __proto__: "not an object or null" };
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty("__proto__"));
在对象字面值中,仅有一次变更原型的机会;多次变更原型,会被视为语法错误。
不使用冒号记法的属性定义,不会变更对象的原型;而是和其他具有不同名字的属性一样是普通属性定义。
var __proto__ = "variable"; var obj1 = { __proto__ };
assert(Object.getPrototypeOf(obj1) === Object.prototype);
assert(obj1.hasOwnProperty("__proto__"));
assert(obj1.__proto__ === "variable"); var obj2 = { __proto__() { return "hello"; } };
assert(obj2.__proto__() === "hello"); var obj3 = { ["__prot" + "o__"]: 17 };
assert(obj3.__proto__ === 17);
与JSON的区别
- JSON 只允许
"property": value
syntax形式的属性定义。属性名必须用双引号括起来。且属性定义不允许使用简便写法。 - JSON中,属性的值仅允许字符串,数字,数组,true,false,或者其他JSON对象。
- JSON中,不允许将值设置为函数。
Date
等对象,经JSON.parse()
处理后,会变成字符串。JSON.parse()
不会处理计算的属性名,会当做错误抛出。
defineProperty
Object.defineProperty()
方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象
// 使用 __proto__
Object.defineProperty(obj, "key", {
__proto__: null, // 没有继承的属性
value: "static" // 没有 enumerable
// 没有 configurable
// 没有 writable
// 作为默认值
}); // 显式
Object.defineProperty(obj, "key", {
enumerable: false,
configurable: false,
writable: false,
value: "static"
}); // 回收同一对象
function withValue(value) {
var d = withValue.d || (
withValue.d = {
enumerable: false,
writable: false,
configurable: false,
value: null
}
);
d.value = value;
return d;
}
// ... 和 ...
Object.defineProperty(obj, "key", withValue("static")); // 如果 freeze 可用, 防止代码添加
// value, get, set, enumerable, writable, configurable
// 到对象原型上
(Object.freeze||Object)(Object.prototype);
configurable
当且仅当这个属性描述符值为 true 时,该属性可能会改变,也可能会被从相应的对象删除。默认为 false
。
enumerable
true
当且仅当该属性出现在相应的对象枚举属性中。默认为 false。
value
与属性相关的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
。
writable
true
当且仅当可能用 赋值运算符 改变与属性相关的值。默认为false
。
存取描述符同时具有以下可选键值:
get
一个给属性提供 getter 的方法,如果没有 getter 则为undefined
。方法将返回用作属性的值。默认为undefined
。set
一个给属性提供 setter 的方法,如果没有 setter 则为undefined
。该方法将收到作为唯一参数的新值分配给属性。默认为undefined
。- 附上几个简单粗暴的校验方式
//低版本ie中undefined变量可以被修改,所以使用void 0 获取真实的undefined值,
var isUndefined = function(obj) {
//or: return typeof obj === 'undefined';
return obj === void 0;
};
//typeof null 的结果是"object"。
var isNull = function(obj) {
return obj === null;
};
// boolean值,number值和string值需要考虑两种情况,值为字面量时使用typeof和Object.prototype.toString能检测;
// 值为构造函数构建的时候需要使用Object.prototype.toString或者instanceof检测
var isBoolean = function(obj) {
return Object.prototype.toString.call(obj) == '[object Boolean]';
};
var isNumber = function(obj) {
return Object.prototype.toString.call(obj) == '[object Number]';
};
var isString = function(obj) {
return Object.prototype.toString.call(obj) == '[object String]';
};
var isNaN = function(obj) {
return obj !== obj;
}; //typeof 操作符在引用类型的变量里能对function有效。
var isFunction = function(obj) {
//or: return Object.prototype.toString.call(obj) == '[object Function]';
return typeof obj === 'function'; };
var isDate = function(obj) {
return Object.prototype.toString.call(obj) == '[object Date]';
}
var isArray = function(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
var isObject = function(obj) {
//or: return obj === Object(obj);
return Object.prototype.toString.call(obj) == '[object Object]';
}
var isRegExp = function(obj) {
//or: return obj === Object(obj);
return Object.prototype.toString.call(obj) == '[object RegExp]';
} var has = function(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
};
//判断数组,字符串,对象是否为空
var isEmpty = function(obj) {
if (obj == null) return true;
if (isArray(obj) || isString(obj)) return obj.length === 0;
for (var key in obj) if (has(obj, key)) return false;
return true;
};
原理:在任何值上调用Object原生的toString()
方法,都会返回一个[object NativeConstructorName]
格式的字符串。每个类在内部都有一个[ [Class] ]属性,这个属性就指定了上述字符串中的构造函数名NativeConstructorName
参考来源
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects
Javascript中的数据类型知多少的更多相关文章
- JavaScript 中的数据类型
Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...
- javaScript中的数据类型
一.综述 javaScript中的数据类型分为两类: 简单类型:Boolean,Number,String 引用类型:Object 其他:undefined代表变量没有初始化,null代表引用类型为空 ...
- Javascript中的数据类型之旅
虽然Javascript是弱类型语言,但是,它也有自己的几种数据类型,分别是:Number.String.Boolean.Object.Udefined.Null.其中,Object属于复杂数据类型, ...
- 【译】Javascript中的数据类型
这篇文章通过四种方式获取Javascript中的数据类型:通过隐藏的内置[[Class]]属性:通过typeof运算符:通过instanceof运算符:通过函数Array.isArray().我们也会 ...
- javascript 中检测数据类型的方法
typeof 检测数据类型 javascript 中检测数据类型有好几种,其中最简单的一种是 typeof 方式.typeof 方法返回的结果是一个字符串.typeof 的用法如下: typeof v ...
- 鉴定JavaScript中的数据类型
众所周知,JavaScript是一门弱类型的语言,但是这并不代表JavaScript中没有数据类型.JavaScript中常见的数据类型有string.number.object等等,通常我们使用ty ...
- JavaScript中基本数据类型之间的转换
在JavaScript中共有六种数据类型,其中有五种是基本数据类型,还有一种则是引用数据类型.五种基本数据类型分别是:Number 数值类型.String 字符串类型.Boolean 布尔类型, nu ...
- JavaScript中基本数据类型和引用数据类型的区别(栈——堆)
JavaScript中基本数据类型和引用数据类型的区别 1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据 ...
- 面试说:聊聊JavaScript中的数据类型
前言 请讲下 JavaScript 中的数据类型? 前端面试中,估计大家都被这么问过. 答:Javascript 中的数据类型包括原始类型和引用类型.其中原始类型包括 null.undefined.b ...
随机推荐
- 5-05. QQ帐户的申请与登陆(25)(map运用)(ZJU_PAT)
题目链接:http://pat.zju.edu.cn/contests/ds/5-05 实现QQ新帐户申请和老帐户登陆的简化版功能. 最大挑战是:据说如今的QQ号码已经有10位数了. 输入格式说明: ...
- poj 3041 Asteroids 题解
Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 20686 Accepted: 11239 Descr ...
- HorizontalScrollView的使用演示样例
MainActivity例如以下: package cc.cv; import android.os.Bundle; import android.view.LayoutInflater; impor ...
- TreeMap源代码深入剖析
第1部分 TreeMap介绍 A Red-Black tree based NavigableMap implementation. The map is sorted according to th ...
- ubuntu14.04开启root用户 设置root密码 配置国内镜像源 设置分辨率
一.Ubuntu 默认是不允许 root 通过 ssh 直接登录的,可以修改 /etc/ssh/sshd_config,设置 1 PermitRootLogin yes 然后重启 ssh 服务即可 1 ...
- Candy leetcode java
题目: There are N children standing in a line. Each child is assigned a rating value. You are giving c ...
- Ngxtop-Nginx日志实时分析利器
ngxtop实时解析nginx访问日志,并且将处理结果输出到终端,功能类似于系统命令top,所以这个软件起名ngxtop.有了ngxtop,你可以实时了解到当前nginx的访问状况,再也不需要tail ...
- [Functional Programming] Build a Linear congruential generator
What we are going to do in this post, is to build a random number generator. As you might know that ...
- Python访问MongoDB数据库
#encoding: utf-8 __author__ = 'Administrator' #import pymongo from pymongo import MongoClient,GEO2D ...
- HDU 4620 Fruit Ninja Extreme 暴搜
题目大意:题目就是描述的水果忍者. N表示以下共有 N种切水果的方式. M表示有M个水果需要你切. W表示两次连续连击之间最大的间隔时间. 然后下N行描述的是 N种切发 第一个数字C表示这种切法可以切 ...