发表于: 2019-11-14 23:05:50
1 1322
今天完成的事:
复习css、js深度思考,准备复盘评审。
明天计划的事:
学习js、vue高级使用技巧
遇到的问题:
暂无
收获:
整理了一些js知识点
JavaScript
JavaScript是一门什么样的语言?有哪些特点?
运行在浏览器的V8引擎中的脚本语言,不要编译就可以由解释器直接运行的,此外变量松散定义,属于弱类型语言。
说几条JavaScript的基本规范?
- 不要在同一行声明多个变量
- 用===替代==
- switch语句要有default分支
- 构造函数首字母大写,常量用大写字母
- 使用对象字面量替代new Function(){}
页面渲染原理
- 浏览器解析HTML生成一个DOMTree
- 接着解析CSS会产生CSSRuleTree
- 解析完成后,浏览器引擎会通过DOMTree和CSSRuleTree来构造RenderingTree。
- 浏览器调用
预编译
- 首先扫描var关键字,提升到顶端;
- 然后扫描function定义,提到var之前
- 然后再顺序执行
defer和async
- 在
<script>
元素中设置defer属性,相当于告诉浏览器立刻下载,延迟执行。会等页面解析完后,按指定顺序执行 - async属性会告诉浏览器立刻下载,一旦下载完就会开始执行,且不能保证按照指定它们的先后顺序执行。
数据类型
原始类型有哪几种?null是对象吗?
原始类型有:boolean,string,number,null,undefined,symbol 6种。
null不是对象,typeof null会输出object,是因为以前32为系统会将000开头的代表为对象,但null表示为全零所以被错误判断成object
原始类型和引用类型的区别
1.原始类型存储的是值,引用类型存储的是指针。 2.原始数据类型直接存储在栈中,引用数据类型存储在堆中。
使用typeof可以得到哪些类型?
undefined,string,number,boolean,object,function
typeof只能区分除null的原始类型,引用类型只能区分function。
什么是提升?什么是暂时性死区?var,let及const区别
- 函数提升优先于变量提升,函数提升会将整个函数挪到作用域顶部,变量提升只将声明提到作用域顶部
- var存在提升,可以在声明前使用,let,const因为暂时性死区,不能在声明前使用
- var在全局作用域下声明变量会导致变量挂载到window上,其他两者不会
- let和const作用基本一致,但const声明的变量不能再次赋值
- let和const不允许重复声明
原始类型
为什么0.1+0.2!=0.3?如何解决这个问题?
在计算机中,数字以二进制形式存储。在JavaScript中数字采用IEEE754的双精度标准进行存储,因为存储空间有限,当出现无法整除的小数时会取一个近似值。
在0.1+0.2中0.1和0.2都是近似表示的,所以相加时两个近似值进行计算导致最后结果为0.3000,0000,0000,0004,此时对于JS来说不够近似于0.3,所以出现了0.1+0.2!=0.3
解决方法:parseFloat((0.1+0.2).toFixed(10)) === 0.3 // true
null和undefined的区别
undefine: 表示变量被声明了但没有赋值。
null:变量被定义赋值了,但是为空,没有任何属性方法和值
Symbol的使用场景
作为属性名的使用
var mySymbol=Symbol(); var a={}; a[mySymbol]='hello' 复制代码
操作符
何时使用===,何时使用==
==会进行类型转换后再比较,===不会,尽量都用===.
以下两种情况可以用==
- 判断对象属性是否存在
var obj={} if(obj.a == null){ // 相当于obj.a===null || obj.a===undefined } 复制代码
- 判断函数参数是否存在
function fn(a, b){ if(b == null){ // 相当于b===null || b===undefined } } 复制代码
Object.is()与===,==的区别?
Object.is()可以说是升级版,Object.is(NaN,NaN)会返回true,Object.is(-0,+0)返回false
引用类型
Array类型
如何判断一个变量是数组?
1.判断是否具有数组某些方法
if(arr.splice){}
2.instanceof(某些IE版本不正确)
arr instanceof Array
3.Array.isArray()
4.Object.prototype.toString.call(arr); // '[object Array]'
5.constructor方法
arr.constructor === Array
将类数组转化为数组
let arrayLike = { '0' : 'a', '1' : 'b', '2' : 'c', length : 3 }; let arr1 = Array.prototype.slice.call(arrayLike); let arr2 = [].slice.call(arrayLike); let arr3 = Array.from(arrayLike); 复制代码
数组的方法
// 会改变原数组 pop() // 末尾删除 push() // 末尾新增 shift() // 开头删除 unshift() // 开头新增 reverse() // 数组反转 sort() // 排序 splice() // 修改数组(删除插入替换) // 不会改变原数组 concat() // 合并数组 slice() // 选择数组的一部分 indexOf() // 顺序查找指定元素下标 lastIndexOf() // 倒序查找指定元素下标 复制代码
// 迭代方法 // every()查询数组是否每一项都满足条件 // some()查询数组中是否有满足条件的项 // filter()过滤,返回true的项组成的数组 // map()对每一项运行给定函数,返回每次函数调用结果组成的数组 // forEach()对每一项运行给定函数,无返回值 var numbers = [1,2,3,4,5,4,3,2,1]; numbers.every(function(item,index,array){ return item>2; }) // false numbers.some(function(item,index,array){ return item>2; }) // true numbers.filter(function(item,index,array){ return item>2; }) // [3,4,5,4,3] numbers.map(function(item,index,array){ return item*2; }) // [2,4,6,8,10,8,6,4,2] numbers.forEach(function(item,index,array){ // 执行某些操作 }) // 无返回值 复制代码
// 归并方法 // reduce()从第一项开始逐个遍历到最后 // reduceRight()从最后一项开始向前遍历到第一项 var values = [1,2,3,4,5]; values.reduce(function(prev,cur,index,array){ return prev+cur; }) // 15 // reduceRight()结果一样,顺序相反 复制代码
原生sort使用的是哪些排序算法?
插入排序和快速排序结合的排序算法
['1','2','3'].map(parseInt)的答案是?
[1,NaN,NaN]
因为parentInt需要两个参数(val,radix),radix表示解析进制,而map传入三个(element,index,array)导致对应的radix不合法导致解析错误。
Date()类型
获取2019-02-16格式的日期
function formatDate(dt){ if(!dt){ dt=new Date() } var year = dt.getFullYear(); var month = dt.getMonth()+1; var day = dt.getDate(); if(month<10){ month= '0'+month; } if(day<0){ day = '0'+day; } var formatDt = year+'-'+month+'-'+day return formatDt; } 复制代码
其他一些方法
getHour() // 返回时 getMinutes() // 返回分 getSeconds() // 返回秒 getDay() // 返回星期天数 getTime() // 返回毫秒数
评论