JavaScript 知识点总结
传值和传址
var num1 = 1
var num2 = num1
num2 = 2
console.log(num1) //1
console.log(num2) //2
var obj1 = {a:1}
var obj2 = obj1
obj2.a = 2
console.log(obj1.a) //2
console.log(obj2.a) //2
赋值语句,把右边的数据/变量赋值给左边
基础数据类型是传值:数字,字符串,布尔,null,undefined
复杂数据类型是传址:对象,数组,键值对,函数
栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈,简单数据类型存放到栈里面
堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收复杂数据类型存放到堆里面
判断数据类型
var array = []
console.log(typeof'123') //string
console.log(typeof array) //object
console.log(typeof {}) //object
console.log(typeof null) //object 空对象
console.log(array instanceof Array) //true
//window,instanceof 只有同一个全局window 才会返回true
Object.prototype.toString.call([]) //[Object Array]
-
typeof 用于判断字符串、数字、布尔值
-
instanceof 要在同一个全局window
语法:
object instanceof constructor
- object:某个实例对象
- constructor:某个构造函数
- 最准确的方法
Object.prototype.toString.call( )
数组常用方法
数组和字符串转换
array.join('符号')
: 把数组转为字符串,不改变原数组(用符号替换逗号,不填默认逗号)string.split('符号')
: 以符号为标准进行分割字符串,返回数组
数组首尾操作
array.push(参数)
: 把参数添加到数组尾部,改变原数组,此方法返回最新的数组长度为数字array.pop()
: 删除数组尾部一个元素,改变原数组,此方法返回删除的那个元素array.unshift(参数)
: 把参数添加到数组头部,改变原数组,此方法返回最新的数组长度为数字array.shift()
: 删除数组头部 一个元素,改变原数组,此方法返回删除的那个元素
数组序列
-
array.reverse()
: 反转数组,改变原数组 -
array.sort((a,b)=>{return a-b})
: 排序return 数字 < 0 升序; > 0 降序(默认)a-b升序;b-a降序
数组拼接
arr1.concat(arr2)
: 数组拼接,不更改原数组,返回拼接后的新数组array.splice('开始截取的数组下标','截取长度','填充替换的数组')
: 截取删除数组,更改原数组,返回拼接后的新数组array.slice('开始截取的数组下标','结束截取的数组下标,并且不包括')
: 截取删除数组,不更改原数组,
数组常用方法模块
- forEach : 为数组里面每一项进行操作,没有返回值
userList.forEach(el=>{
el.address = 'XXX'
})
- map : 为数组里面每一项进行操作,并返回一个新数组
var res = userList.map(el=>{
if(el.age > 20){
return el
}
}).filter(el=>el)
- filter : 循环过滤符合条件的数组,返回一个新数组,return布尔值
var res = userList.filter(el => el.age > 20)
-
find : 查找符合条件的元素返回,只会返回符合条件的第一个,return true的时候元素返回
-
findIndex : 查找符合条件的元素下标返回
-
some : 有真则真 返回布尔值
-
every : 所有真才真,有假则假 返回布尔值
-
reduce : 遍历
var res = arr.reduce((p,n)=>p+n)
对象的深拷贝和浅拷贝
浅拷贝:复杂数据类型的传址
深拷贝:完全赋值一份数据一致的非同一个地址的数据
-
把对象转换成字符串,然后再转换为对象
JSON.parse(JSON.stringify(obj))
缺点:undefined和函数无法赋值
- 标准常用的深拷贝方法是递归进行拷贝
this指向以及改变
this指的是当前代码执行的上下文
顶层全局作用域windows,声明的全局变量挂载在windows上
普通函数的this是执行的时候绑定的,箭头函数是声明的时候绑定的
var obj = {
oson1:{
oson2:{
fn1:()=>{
console.log("箭头函数this",this) //在全局作用下声明(看var的位置),this指向windows
},
fn2:function(p1,p2){
console.log("普通函数this",this) //执行时绑定,this指向oson2:{fn1:f,fn2:f}
console.log("输出参数:",p1,p2)
}
}
}
}
改变this指向的三个方法
-
apply 改变this指向并立即执行函数,参数以数组形式写
obj.oson1.oson2.fn2.apply({a:123},['A','B'])
-
call 改变this指向并立即执行函数,参数逗号分隔
obj.oson1.oson2.fn2.call({a:456},'C','D')
-
bind 语法和call一样,但是改变完不会立即执行
obj.oson1.oson2.fn2.bind({a:789},'e','f')
异步解决方案
-
callback 回调函数
把函数当作一个参数传到另外一个函数中,当需要用这个函数是,再回调运行()这个函数.
function getData(callback){ setTimeout(()=>{ callback('data') },100) } getData((res)=>{ console.log(res) })
-
promise
有三种状态,pending => resolve/reject
function p1(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('结果') },100) }) } p1().then(res=>{ console.log('promise',res) }).catch(err=>{ console.log('promise err',err) }) //Promise.all 多个一部执行完进行操作 function p_1(){ //.... } function p_2(){ //.... } function p_3(){ //.... } Promise.all([p_1(),p_2(),p_3()]).then(res=>{ console.log(res) }).catch(err=>{ console.log(err) })
-
async/await
function fun(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve([1,2,3]) },100) }) } async function getData(){ const res = await fun() console.log(res) }
原型链
prototype 只有函数对象才有(构造函数原型对象)
proto 所有对象都有此属性,总是指向对应的构造函数的原型对象
constructor __proto__下面的constructor指向构造函数
对象访问属性的时候,在自身属性查找,找不到再去__proto__原型链上查找,知道找不到为止返回undefined
原型链的终点Object
const app = new Vue()
console.log(app.__proto__===Vue.prototype)
console.log(app.__proto__.__proto__===Object.prototype)//===Vue.prototype.__proto__(Vue.prototype的构造函数原型对象)
constructor 主要判断对象的原型是否是某个对象
console.log(app.__proto__.constructor === Vue)
console.log(app.__proto__.__proto__.constructor === Object)
闭包
「函数」和「函数内部能访问到的变量」的总和,就是一个闭包。
函数套函数,并把内部函数return
作用:封装变量,收敛函数
优点:不会造成变量污染
闭包被子函数引用的变量不会被回收,有可能造成内存泄漏
SPA单页面应用
SPA : 整个项目只有一个html文件,路由切换进行页面切换
优点
-
用户体验及交互比较流畅
-
提取组件开发,易于后期维护
-
减轻服务器压力(交由js渲染)
缺点
-
不利于SEO优化 (不利于搜索引擎优化)引擎爬虫只会爬取html而不会爬取js
-
第一次进入比较慢 (已有按需加载策略)
MVC和MVVM
-
View视图 -(用户行为)-> Controller控制器 -(通知数据更改)-> Model 数据层 -(通知视图更改)->View视图
(model跟view进行了交互)
-
View视图 <-(用户行为)-> ViewModel <-(数据更改)-> Model(数据层)
model跟view没有直接交互,双向绑定通过ViewModel进行交互