Javascript中的数据类型知多少

JavaScript
是一种弱类型或者说动态言语。那代表你不用提前评释变量的花色,在程序运营进度中,类型会被自动显然。那也意味你可以行使同二个变量保存差距类其余数目

根据ECMAScript
5.1
的正儿八经,javascript中共有五种数据类型,分别为:UndefinedNullBoolean,NumberStringObject。前二种属于中央类型,最后一种属于Object类型。

摩登的ECMAScript 6
又加了一系列型:Symbol (ECMAScript
6 新定义) 

基本数据类型

  • Undefined:唯有多个值,为undefined,意味着“空值(no
    value)”,适用于全数数据类型。
  • Null:唯有一个值,为null,意味着“空对象(no
    object)”,只适用于对象类型。(literal)
  • Boolean:有多个值,为truefalse
  • Number:的值是比照IEEE
    754正式的6肆位浮点数的聚合,没有整型数据结构。其余还蕴藏两个特出的值:NaNInfinity-Infinity
  • String:值是战国个Unicode字符的聚集。必须用'"括起来。

一、String

JavaScript的字符串类型用于表示文本数据。它是一组十六人的无符号整数值的“成分”。在字符串中的每一个成分占据了字符串的岗位。第一个成分的目录为0,下三个是索引1,依此类推。字符串的尺寸是它的要素的数目

与 C 语言差别,JavaScript
中字符串是不可变的(译注:如,JavaScript
中对字符串的操作必然重回了3个新字符串,原始字符串并从未被改动)

Javascript中一切都是object-based

成立string,也有两种档次

① 、使用字面量形式开创的字符串,为主导项目标string //string 实则保存就是的值,是一个基本类型

2、使用String()始建的字符串,为宗旨类型的string  // string

③ 、使用结构函数 new String()的法门开创的字符串,为对象类型的
//string 实在保存的是1个对准字符串对象的指针

看代码

 

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对象相混淆

壹 、借使Boolean构造函数的参数不是多个布尔值,则该参数会被转换到2个布尔值

二 、假设参数是 0-0null,falseNaNundefined,
只怕空字符串 (“”),生成的Boolean对象的值为false.
其余任何值,包含此外对象只怕字符串"false",
都会创立二个值为true的Boolean对象

var x = new Boolean(false);

if(x){
    console.log(x.valueOf(),typeof x); // false  object
}

地方会履行,很神奇的代码

毫不通过新建Boolean目的的不二法门来将2个非布尔值转化成布尔值.
直接使用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 标准的双精度 陆拾肆个人二进制格式的值(-(253 -1) 到
253 -1)。它并不曾为整数给出一种特定的档次。除了可以代表浮点数外,还有一些带符号的值:+Infinity-Infinity 和 NaN (非数值,Not-a-Number)

数字类型唯有2个平头,它有二种象征方法:
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 是三个字面量
(而不是大局对象的2个属性,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就是3个常见的性质,你完全可以把它的值改变成为任意的真值,但在ES5中((Firefox4之后),window.undefined成了二个不可写,不可配置的数目属性,它的值永远是undefined.

一个未开端化的变量的值为undefined,多少个没有传到实参的形参变量的值为undefined,若是3个函数什么都不回去,则该函数暗中认同重返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()方法。但nullundefined值没有那些方式

大部场合下,调用toString()艺术不必传递参数。不过,在调用数值的toString()办法时,能够传递3个参数:输出数值的基数

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"

在不精晓要转换的值是否nullundefined的动静下,还足以拔取转型函数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() 方法直接在一个目的上定义三个新属性,恐怕修改1个已经存在的品质,
并重临这么些目的

// 使用 __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

set1个给属性提供 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() 方法,都会重返3个[object NativeConstructorName] 格式的字符串。各种类在内部都有贰个[
[Class]
]属性,那脾天性就内定了上述字符串中的构造函数名NativeConstructorName

参照来源

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global\_Objects