这是我参与「第四届青训营 」笔记创作活动的的第3天。
JavaScript基础
• 与其他语言的不同:js可以在运行的时候动态地改变某个变量的类型;
• 其他语言是根据类来继承,而js是根据原型来继承;
• 弱类型语言,在运行时才能确定变量类型;
• 其他语言的作用域分为静态作用域和动态作用域,而js采用词法作用域(静态),变量在编译过程中会产生一个确定的作用域;
• 单线程的设计会存在阻塞问题,为此 JavaScript 中任务被分为同步和异步任务;事件循环(Event Loop)机制;
零碎知识点
-
JS严格区分大小写
-
三种弹框输出语句:
-
控制台输出的三种打印等级:
console.log(''); //普通打印 console.warn(''); //警告打印 console.error(''); //错误打印 -
开发技巧:用变量定义常量
-
一个没有初始化的变量其值为undefined
-
所有的基本数据类型的值保存在栈内存中;(String/Number/Boolean/Null/Undefined)
对象保存到堆内存中,每创建一个新的对象,就会在堆内存中开辟出一个新的空间;而变量(对象的引用)保存了对象的内存地址,保存在栈内存当中。
So,if 两个变量保存的是同一个对象的引用,当一个变量修改属性时,另一个也会受影响。
即:对于引用类型的数据,赋值相当于地址拷贝。
另:if 希望赋值的引用数据类型之间相互不受影响,使用
Object.assign()// 复制对象:把 obj1 赋值给 obj3。两者之间互不影响 var obj3 = Object.assign({}, obj1); -
不能使用 JS 进行对精确度要求比较高的运算
-
取余运算 余数 = m % n;
• 结果的正负性,取决于 m,而不是 n
• if n = 0 则结果是NaN
-
任何值和 NaN 运算的结果都是 NaN;
任何值和NaN做任何比较都是false(包括其本身==)。
任何值做加法运算,都会转换为String再运算;
任何值做 - 、 * 、 / 、 % 运算时,会将这些值转换为 Number 然后再运算。
-
const声明的常量不能再自加
-
对任何数据类型前使用 + ,能将其转化为number
-
注意非布尔值的与或运算的返回值!
应用:[容错处理(兜底)]
if (result.resultCode == 0) { var a = result && result.data && result.data.imgUrl || 'http://img.smyhvae.com/20160401_01.jpg'; } -
switch 语句的结束与 default 的顺序无关。
-
单独的 if 语句里不能用 break 和 continue,否则会报错
-
三个基本包装类: String()、Number()、Boolean() 可以将基本数据类型的数据转换为对象(即‘隐式类型转换’)。
PS:调用完以后,会再将其还原为基本数据类型。
-
JS中的对象分3种:自定义对象、内置对象(字符串对象,数学对象,日期对象,数组对象)、浏览器对象。
17. Math.floor() 向下取整
Math.ceil() 向上取整
Math.round() 正数四舍五入取整,负数五舍六入取整
Math.random() 生成 [0,1)之间的随机浮点数
生成 [x, y) 之间的随机数:
Math.round(Math.random()*(y-x)+x)
生成 [x, y]之间的随机整数: Math.floor(Math.random() * (max - min + 1)) + min
7种数据类型
7种:两大类:基础类型(Null,Undefined,Number,String,Boolean,Symbol),引用类型(Object)。
---> 区别:基础类型的数据在被引用或拷贝时,是值传递,也就是说会创建一个完全相等的变量;而引用类型只是创建一个指针指向原有的变量,实际上两个变量是“共享”这个数据的,并没有重新创建一个新的数据。
-
number
两个特殊数值:
-
NaN(Not a Number)在进行数值运算时,如果得不到正常结果,就会返回 NaN,通过 number.isNaN 判断一个变量是否为该值;
Undefined 和任何数值计算的结果为 NaN。NaN 与任何值都不相等,包括 NaN 本身。
-
-
Infinity 无穷大,添-号为无穷小
PS: - 、 * 、 / 、 % 这几个符号会自动进行隐式转换,即
字符串 - 数值 = 数值常用方法:
• isInteger() 判断是否为整数 • toFixed(num) 小数点后面保留num位(四舍五入),返回字符串精度问题 0.1 + 0.2,得到的结果是 0.30000000000000004,如果直接和 0.3 作相等判断时会得到 false?
reason:计算的时候,JavaScript 引擎会先将十进制数转换为二进制,然后进行加法运算,再将所得结果转换为十进制。在进制转换过程中如果小数位是无限的,就会出现误差。
solution:消除无限小数位
□ WAY1:先转换成整数进行计算,然后再转换回小数,这种方式适合在小数位不是很多的时候。
□ WAY2:舍弃末尾的小数位。比如对上面的加法就可以先调用 toPrecision截取 12 位,然后调用 parseFloat 函数转换回浮点数。
parseFloat((0.1 + 0.2).toPrecision(12)) // 0.3
-
string
字符串里面的值不可被改变。虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间(即,字符串的所有方法,都不会改变原字符串 字符串的不可变性)。
常用方法:
-
查找
indexOf()/lastIndexOf()返回:子串第一次出现的索引/-1search()参数:字符串/正则表达式;返回:子串第一次出现的索引/-1includes()返回:true/falsestartsWith()参数:[内容,检索起始位置];返回:true/falseendsWith()参数:[内容,检索长度];返回:true/false -
获取
charAt(index)返回指定位置的字符(index字符串的索引号) str.charAt(0)str[index]h5新增特性charCodeAt(index)返回字符串指定位置的字符的 Unicode 编码 -
截取
slice()范围:[ )substring(开始索引,结束索引)参数:负数看成0,自动调整参数位置(小,大)substr(开始索引,截取长度)PS:ECMAscript没有对其标准化 -
其他
String.fromCharCode():根据字符的 Unicode 编码获取字符split(分隔符)字符串转换为数组replace(被替换的子串,新的子串)默认只会替换第一个被匹配到的字符;如果要全局替换,需要使用正则repeat()将字符串重复指定的次数trim()去除字符串前后的空白大小写转换:
toLowerCase() toUpperCase()
Q:编写一个函数来为输入值的数字添加千分位分隔符。
WAY1: 字符串转换为数组,反转,从左到右操作
function sep(n) { let [i, c] = n.toString().split(/(\.\d+)/) return i.split('').reverse().map((c, idx) => (idx+1) % 3 === 0 ? ',' + c: c).reverse().join('').replace(/^,/, '') + c }WAY2:通过引用类型,正则表达式对字符替换
function sep2(n){ let str = n.toString() str.indexOf('.') < 0 ? str+= '.' : void 0 return str.replace(/(\d)(?=(\d{3})+\.)/g, '$1,').replace(/\.$/, '') } -
-
boolean
-
undefined
常量
得到undefined的5种方式:
a. 引用已声明但未初始化的变量 var a;
b. 引用未定义的对象属性 var o = {}
c. 执行无返回值函数 (() => {})()
d. 执行 void 表达式 void 0
e. 全局常量 window.undefined 或 undefined。
判断一个值是否是undefined:
typeof x === 'undefined'任何数据类型和 undefined 运算都是 NaN。
-
null
js保留关键字
一个空的object,因此 typeof null 的返回值是 object;
任何值和 null 运算,null 可看做 0 运算; undefined == null true
-
object
null,空数组,空对象的类型都是object;
子类型:Date、Array、Set、RegExp
-
symbol
ES6引入的新数据类型,表示一个唯一的常量。
安全数字
最大:Number.MAX_SAFE_INTEGER
最小:Number.MIN_SAFE_INTEGER