JavaScript 数据类型

一、JavaScript 定义了几种数据类型? 哪些是原始类型?哪些是复杂类型?

  • 最新的 ECMAScript 标准定义了 7 种数据类型:

原始类型

  1. Number;数值类型;值:整数和小数。
  2. String;字符串类型;值:字符串组成的文本。
  3. Boolean;布尔类型;值:true、false。
  4. Undefined;值:undefined(表示“未定义”或不存在,即由于目前没有定义)。
  5. Null;值null(表示无值,即此处的值就是“无”的状态)。
  6. Symbol;值:symbol(ECMAScript 6 新定义,表示唯一值)。
    复杂类型
  7. Object;对象类型;值:各种 “ key:value ” 组成的集合。
    区别
    原始类型(基本类型)都是存放着一个确定的值,它们对内存的占用大小是确定的,存放着栈内存中。
    复杂类型存放的内容是不确定的,占用的内存也是变化的,它的栈内存用固定的内存存放它在内存中的位置,而可变化的内容存放着堆内存中。
    基本类型变量存的是值,复杂类型的变量存的是内存地址。
    基本类型在赋值的时候拷贝值,复杂类型在赋值的时候只拷贝地址,不拷贝值。

二、三、如何判断一个变量是否是数字、字符串、布尔、函数?

JavaScript有三种方法,可以确定一个值到底是什么类型。

  • typeof运算符
  • instanceof运算符
  • Object.prototype.toString方法(以后再做介绍)
  1. typeof 是用于返回一个值的数据类型,对于常见的几大数据类型都可以用typeof 数据类型的方式进行判断。
  • 一元运算符,运算格式:
typeof xxx
  • 返回结果是类型的字符串
  • 数值、字符串、布尔值分别返回number、string、boolean。
typeof 123;      //number
typeof '123';    //string
typeof false;    //boolean
  • 函数返回function。
function f() {};
typeof f;          //function
  • undefined返回undefined。
typeof undefined;   //undefined
  • 除此以外,其他情况都返回object。(局限性)
typeof window;     //object
typeof {};        //object
typeof [];         //object
typeof null;     //object
  1. instanceof 是用于判断某个对象是不是构造函数的一个实例,举例来说就是一个新声明的变量是不是调用了构造函数的内置属性或方法,区分狭义对象、数组、日期、函数等。
  • 二元运算符
    instanceof 是一个二元运算符,左边a是被运算的值,右边b是运算的类型。格式是这样的
a instanceof b
  • 使用instanceof的都必须是对象。所以不属于object类型的基本类型是无法应用instanceof的,或者无法得到你想要的结果。
1 instanceof Number
//false
new Number(1) instanceof Number
//true
'string' instanceof String
//false
new String('string') instanceof String
//true
  • 返回结果是布尔值(Boolean):true/false
    所以instanceof是一个判断,而typeof是求值
var o = {};
var a = [];
o instanceof Array;     //false
a instanceof Array;     //true

四、NaN是什么? 有什么特别之处?

  • NaN 是一种特殊的 Number 类型值。
    通常作为没有得到预期数值的返回值,如作为 Math 的某个方法的返回值出现的(例如:Math.sqrt(-1))或者尝试将一个字符串解析成数字但失败了的时候(例如:parseInt("blabla"))
  • NaN是JavaScript之中唯一不等于自身的值。
typeof NaN   // "number"
NaN !== NaN  // true
 NaN === NaN  // false
  • 任何涉及NaN的数值操作都会返回NaN,如NaN+10返回NaN

五、如何把非数值转化为数值?

在JavaScript中,有3个函数可以把非数值转换为数值,这三个函数分别是:Number() 、parselnt() 和 parseFloat()。第一个函数,即转型函数 Nurnber() 可以用于任何数据类型,而另两个函数则专门用于把字符串转换成数值。这3个函数对于同样的输入会返回不同的结果。

Number() 函数

  • 如果是 Boolean 值,true 和 false 将分别被转换为 1 和0;
  • 如果是数字值,只是简单的传入和返回;
  • 如来是null 值,返回 0;
  • 如果是 undefined,返回NaN ;
  • 如果是字符串,遵循下列规则:

如果字符串中只包含数字,则将其转换为十进制数值,即"1"会变成1 , "123"会变成123,而"011"会变成11(注意,前导的0被忽略了);

如果字符串中包含有效的浮点格式, 如"1.1",则将其转换为对应的浮点数值(同样,也会忽略前导零);
如果字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整数值;
如果字符串是空的(包含空字符) ,则将其转换为0;
如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。

  • 如果是对象,则调用对象的 valueOf() 方法,然后依照前面的规则转换返回的值。如果转换的结果是 NaN,则调用对象的 toString() 方法,然后再次依照前面的规则转换返回的字符串值。
var num1 = Number("Hello world!");  // NaN
var num2 = Number("   ");  // 0
var num3 = Numberl("000011");  // 11
var num4 = Number(true);  // 1

parseInt() 函数

  • 由于 Number() 函数在转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是 parseInt() 函数。
  • parselnt() 函数在转换字符串时,更多的是看其是否符合数值模式,它会忽略字符串前面的空格,直至找到第一个非空格字符;如果第一个字符不是数字字符或者负号,parseInt() 就会返回 NaN;也就是说,用parselnt() 转换空字符时会返回 NaN(Nurnber() 对空字符返回 0); 如果第一个字符是数字字符,parselnt() 会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。例如,"1234blue"会被转换为1234 ,因为"blue"会被完全忽略;类似地,"'22.5"会被转换为22 ,因为小数点并不是有效的数字字符。
  • 如果字符串中的第一个字符是数字字符,parselnt() 也能够识别出各种整数格式(即前面讨论的十进制、八进制和十六进制数) 。也就是说,如果字符以"0x"开头且后跟数字字符,就会将其当作一个十六进制整数;如果字符串以"0"开头且后跟数字字符,则会将其当作一个八迸制数来解析。

ES5不再允许将带有前缀0的数字视为八进制数,而是要求忽略这个0。但是,为了保证兼容性,大部分浏览器并没有部署这一条规定。

var num1 = parselnt ("1234blue") ;  // 1234
var num2 = parselnt (" ") ;   // NaN
var num3 = parselnt ("0xA") ;  // 10(十六进制数)
var num4 = parseInt(22.5);   // 22
var num5 = parselnt ("070") ;  // 56(八进制数)
var num6 = parselnt("70");  //70(十进制数)
var num7 = parselnt ("0xf") ;  // 15(十六进制数)
  • 如果知道被解析的是十六进制格式的字符串,那么指定基数16 作为第二个参数,可以保证得到正确的结果,例如:
var num = parselnt("0xAF", 16);   //175
  • 实际上,如果指定了16 作为第二个参数,字符串可以不带前面的"0x",如下所示:
var num1 = parseInt( 'AF' , 16);   //175
var num2 = parselnt ("AF") ;   // NaN
  • 指定基数会影响到转换的输出结果。例如:
var num1 = parselnt ("10", 2);  // 2(按照二进制解析)
var num2 = parseInt("10", 8);  // 8(按照八进制解析)
var num3 = parselnt("10", 10);  // 10(按照十进制解析)
var num4 = parselnt("10", 16);  // 16(按照十六进制解析)

parseFloat() 函数

  • 与 parseInt () 函数类似,parseFloat () 也是从第一个字符(位置0)开始解析每个字符。而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。也就是说,字符串中的第一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。举例来说,"22.34.5"将会被转换为22.34 。
  • 除了第一个小数点有效之外, parseFloat () 与 parselnt() 的第二个区别在于它始终都会忽略前导的零。parseFloat() 可以识别前面讨论过的所有浮点数值格式,也包括十迸制整数格式,但十六进制格式的字符串则始终会被转换成0。由于 parseFloat() 只解析十进制值,因此它没有用第二个参数指定基数的用法。最后还要注意一点:如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后都是零),parseFloat() 会返回整数。以下是使用 parseFloat() 转换数值的几个典型示例:
var num1 = parseFloat ("1234blue") ;  // 1234(整数)
var num2 = parseFloat("0xA");   // 0
var num3 = parseFloat("22.5");  // 22.5
var num4 = parseFloat("22.34.5");  // 22.5
var num5 = parseFloat("0908.5");   // 908
var num6 = parseFloat("3.125e7");   // 31250000

六、==与===有什么区别?

  • x == y 在对比 x 和 y 的值之前,会尝试对 x 和 y 做类型转换,变成同一种类型后,再对比。
  • x===y会对比x和y是否同类型,不同类型会返回false,不会发生转换。
    == 会做类型转换,=== 不做类型转化

七、break与continue有什么区别

  • 都是为了控制代码循环执行,执行到之后都会立即跳出循环
  • break退出循环后,会继续执行后续的语句
for(var i=0;i<3;i++){
  for(var j=0;j<3;j++){
    console.log(j)
    break
  }
  console.log('我')
}
//0
//'我'
//0
//'我'
//0
//'我'
  • continue退出循环后,会再从最外层循环开始执行(注意外层循环次数没有累加)
for(var i=0;i<2;i++){
  for(var j=0;j<3;j++){
    console.log(j)
    continue
  }
  console.log('我')
}
//0
//1
//2
//"我"
//0
//1
//2
//"我"

八、void 0 和 undefined在使用场景上有什么区别

  • undefined 全局作用域下不能被重写,但是在局部作用域中,可以被重写的。所以undefined现常用于全局环境。
  • void 运算符通常只用于获取 undefined 的原始值,一般使用 void(0)(等同于 void 0)。在上述情况中,也可以使用全局变量undefined 来代替(假定其仍是默认值)。
  • 而 void 可以给任何给定的表达式求值,并返回 undefined,并且 void 不可被重写,因此void 0是在局部作用域中替代undefined的最佳选择

九、以下代码的输出结果是?为什么?

  1. console.log(1+1);
    console.log(1+1);      // 2
    "+" 两边都是数值类型,做数值运算。
  2. console.log("2"+"4");
    console.log("2"+"4");    //24
    "+" 两边都是字符串类型,直接拼接。
  3. console.log(2+"4");
    console.log(2+"4");    //24
    "+" 一边是数值类型,另一边是字符串类型,数值类型转为字符串类型后拼接。
  4. console.log(+"4");
    console.log(+"4");    //4
    "+" 只有右侧一个操作数,转换我数值类型。

十、 以下代码的输出结果是?

  • var a = 1;
    a+++a;
    typeof a+2;
var a = 1;       
console.log(a+++a);     //3
console.log(typeof a+2);     //number2

因为"…++"优先级高于"+"优先级高于"++…","a+++a" 相当于"(a++)+a",即"1+2"返回 3 ;
"typeof a+2"相当于"(typeof a)+2",即"number+2",做字符串拼接返回number2。

十一、 以下代码的输出结果是? 为什么

 var a = 1;
 var b = 3;
 console.log( a+++b );   //4

因为"…++"优先级高于"+"优先级高于"++…","a+++b" 相当于"(a++)+b",即"1+3"返回 4;

十二、遍历数组,把数组里的打印数组每一项的平方

 var arr=[3,4,5]
for(var i in arr){
  console.log(arr[i]*arr[i])
}
//9
//16
//25

十三、 遍历 JSON, 打印里面的值

var obj = {
 name: 'hunger', 
 sex: 'male', 
 age: 28 
}
for(var key in obj){
  console.log(key+':'+obj[key])
}
//"name:hunger"
//"sex:male"
//"age:28"

十四、 以下代码输出结果是? 为什么

var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val) 
//"number2"

优先级:typeof>"+">"||",所以相当于"number2" || c>0,返回"number2"。

var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)
//"bb"
//undefined

优先级:"==">"+"&&",所以相当于true && undefined,返回undefined。

var data2 = d = 0 || console.log('haha')
console.log(data2)
//"haha"
//undefined

相当于data2=d=0|| undefined,0布尔值为false,所以返回undefined。

var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)
//2

优先级:"=">"!">"+",相当于var x=true + (false,true),加号优先将操作数转为数字,所以得到2。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容