接下来的一系列学习笔记都来自于阮一峰老师的JavaScript 教程,重新回顾一遍JavaScript基础。
本篇是对于这个教程中数据类型的相关总结。
在学习基础知识之前,先来看一下关于JavaScript的相关介绍和特点:
- JavaScript 是一种轻量级的脚本语言。
- 是一种嵌入式语言,本身不提供任何与 I/O相关的 API,都要靠宿主环境(host)提供
- 从语法角度看,JavaScript 语言是一种“对象模型”语言
- JavaScript 并不是纯粹的“面向对象语言”,还支持其他编程范式(比如函数式编程)
下面以提问的方式来对JavaScript的数据类型来进行学习和总结:
JavaScript中有几种数据类型?
JavaScript 的数据类型,共有六种,(ES6 又新增了第七种 Symbol 类型的值).
主要包括:数值(number),字符串(string),布尔值(boolean),undefined,null,以及对象(object)。
其中对象又包括狭义的对象object,函数和数组。
判断数据类型的方法?
JavaScript 有三种方法,可以确定一个值到底是什么类型。
- typeof运算符
- instanceof运算符
- Object.prototype.toString方法
不过需要注意,null使用typeof运算符会返回object。
为何typeof 用来检查一个没有声明的变量不报错?
- 因为 typeof undefined // "undefined"
null 和 undefined 有什么区别?
- null是一个表示“空”的对象,转为数值时为0;
- undefined是一个表示"此处无定义"的原始值,转为数值时为NaN。
布尔值的转化规则?
如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true。
- undefined
- null
- false
- 0
- NaN
- ""或''(空字符串)
为何说JavaScript 语言的底层根本没有整数?
- JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,1与1.0是相同的,是同一个数。1 === 1.0 // true
+0 和 -0的区别?
- 几乎所有场合,正零和负零都会被当作正常的0。唯一有区别的场合是,+0或-0当作分母,返回的值是不相等的。
数值NaN有什么特殊性?
- 属于Number类型,
typeof NaN // 'number'
- NaN不等于任何值,包括它本身
- indexOf方法不能判定NaN
- NaN与任何数(包括它自己)的运算,得到的都是NaN
- NaN在布尔运算时被当作false
为何使用isNaN之前,最好判断一下数据类型?
- 因为isNaN只对数值有效,如果传入其他值,会被先转成数值。当isNaN为true的值,有可能不是NaN。
如何把长字符串分成多行?
- 在每一行的尾部使用反斜杠
为什么对象的所有键名加不加引号都可以?
- 因为对象的所有键名都是字符串
如果行首是一个大括号,它到底是表达式还是语句?
- JavaScript 引擎的做法是,如果遇到这种情况,无法确定是对象还是代码块,一律解释为代码块。如果要解释为对象,最好在大括号前加上圆括号。
delete命令可以删除对象的所有属性吗?
- 只能删除对象本身的属性,无法删除继承的属性,即使delete返回true,该属性依然可能读取到值。
for...in 循环 和普通for循环的区别
- for...in 遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。它不仅遍历对象自身的属性,还遍历继承的属性。
- 标准的for循环中的i是number类型,表示的是数组的下标,但是foreach循环中例如
for(var i in array)
的i表示的是数组的key是string类型 - for循环是对数组的元素进行循环,而不能引用于非数组对象
arguments 对象跟数组的关系?
- arguments对象包含了函数运行时的所有参数,具有length属性,可以判断函数调用时到底带几个参数
- arguments是类数组,“类似数组的对象”的根本特征,就是具有length属性。只要有length属性,就可以认为这个对象类似于数组
- 虽然arguments很像数组,但它是一个对象。数组专有的方法(比如slice和forEach),不能在arguments对象上直接使用
- 将arguments转为真正的数组:
Array.prototype.slice.call(arguments)
JavaScript 的作用域?
JavaScript 有两种作用域:全局作用域和函数作用域
- 全局作用域:变量在整个程序中一直存在,所有地方都可以读取;
- 函数作用域,变量只在函数内部存在。
- (ES6 新增了块级作用域)
函数本身的作用域在哪里?
函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。
var a = 'out';
var x = function () {
console.log(a);
};
function f() {
var a = 'inter';
x();
}
f() // 'out'
函数参数的传递方式?
- 函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递
- 如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递(pass by reference)。因此在函数内部修改参数,将会影响到原始值。
如果在函数体内修改参数值,会不会影响到函数外部?
- 如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递,不影响;
- 如果是复合类型的值(数组、对象、其他函数),传递方式是传址传递。在函数内部修改参数,将会影响到原始值;
- 如果函数内部修改的,不是参数对象的某个属性,而是替换掉整个参数,这时不会影响到原始值;
什么是闭包?
当我们需要获取到某个函数f1的局部变量时,我们可以在函数f1内定义一个函数f2,则在函数B中可以获到f1中的局部变量,把函数f2作为返回值return回来,我们就可以在函数f1的外部获取到它的局部变量,此时,这个函数f2就是闭包。
闭包,即能够读取其他函数内部变量的函数。
闭包的用处:
- 读取函数内部的变量,让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
- 封装对象的私有属性和私有方法
为何不能滥用闭包?
- 内存消耗会很大,造成网页的性能问题。
立即调用的函数表达式(IIFE)的作用是什么?
- 不必为函数命名,避免了污染全局变量
- IIFE 内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
数组的某个位置是空位与某个位置是undefined的区别?
- 如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。
网友评论