js查漏补缺

数据类型

基本数据类型

Number,String,Boolean,null,undefined,symbol

symbol可生产唯一的、不可变的标识

let a =Symbol() //可以带参数Symbol("food")
let b=Symbol()
console.log(a==b);//false

引用数据类型

Object,Array,Function,Date,Set等

基本数据类型存放在栈中,引用数据类型地址存在栈中,值存在堆中

数据类型检测

typeof

检测基本数据类型

 typeof 1 // 'number'
 typeof '1' // 'string'
 typeof undefined // 'undefined'
 typeof true // 'boolean'
 typeof Symbol() // 'symbol'
 typeof null // 'object'
 typeof [] // 'object'
 typeof {} // 'object'
 typeof console // 'object'
 typeof console.log // 'function'

instanceof

通过判断对象是否是该构建函数生成的实例对象

// 定义构建函数
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('xxx')
car instanceof String // true
let str = 'xxx'
str instanceof String // fals

区别:

typeof返回一个变量的基本数据类型,instanceof返回布尔值

typeof适合判断基本数据类型,instanceof适合判断引用对象

推荐:Object.prototype.toString可以检测所有类型

BOM

window,location,navigator,history

window.open可以导航到一个特定的url,也可以打开一个新的浏览器窗口

location.reload()可以强制重新刷新当前页面

history.go(),接受一个整数或字符串参数

history.go(3)  //向前跳转三个记录
history.go(-1)  //向后跳转一个记录

history.forward()  :向前跳转一个记录
history.back()     :回退一个记录
history.length    :获取历史记录长度

call、apply、bind

都是修改this指向的,第一个参数是指定this的指向

call除了第一个参数外,传参是参数列表

apply除了第一个参数外,传参是数组,跟array长相类似

bind会返回改变this指向后的函数,不会立即执行

let obj={name:'zhangsan'}
function fn (...args){
    console.log(this,args); 
}

fn.call(obj,1,2)        //{ name: 'zhangsan' } [ 1, 2 ]
fn.apply(obj,[1,2])        //{ name: 'zhangsan' } [ 1, 2 ]

const bindFn= fn.bind(obj,1,2)  //{ name: 'zhangsan' } [ 1, 2 ]
bindFn()

事件冒泡和事件捕捉

冒泡从小到大(从子到父),捕捉从大到小(从父到子)

闭包

一个函数和对其周围状态的引用捆绑在一起,这样的组合就是闭包

function init(){
    let name="张三"
    function changeName(){
        name='李四'  //使用别的函数里面的变量
    }
    changeName()
    console.log(name);   
}
init()

作用:创建私有变量,延长变量的生命周期

计时器,延迟调用,回调等都是闭包的具体用处。

浅拷贝深拷贝

浅拷贝

Object.assign,Array.prototype.slice(),Array.prototype.concat(),...展开运算符

只有引用对象会受影响

let obj={
    name:"李四",
    likes:['足球,篮球']
}

let newObj=Object.assign({},obj)
newObj.name="张三"
newObj.likes[0]='乒乓球'

console.log(obj); //{ name: '李四', likes: [ '乒乓球' ] }
const arr=["One", "Two", "Three"]

let newArr=arr.concat()
let newArr=arr.slice()
let newArr=[...arr]

深拷贝

_cloneDeep,JSON.parse(JSON.stringify()(会忽略undefined,symbol和函数)

递归克隆

function deep(obj){
    //set对象就return new set ,,map。函数等。。。
    
    if(Object.prototype.toString.call(obj)=="[object Function]"){
        return obj
    }
    let targetObj=Object.prototype.toString.call(obj)=="[object Array]"?[]:{}
    //先看是对象还是数组
    for(let i in obj){
        //忽略原型上的属性
        if(obj.hasOwnProperty(i)){
            //循环obj的i,如果是对象或者数组继续递归赋值
            let val=obj[i]
            if(i instanceof Array || i instanceof Object ){
                targetObj[i]=deep(val)
            }else{
                targetObj[i]=val
            }
        }
        
    }
    return targetObj
}

函数缓存

将函数运算过的结果缓存起来

主要依靠闭包、柯里化、高阶函数

柯里化

把接受多个参数的函数 转化为接受单一参数的函数

function add (x,y){
    return x+y
}
// 柯里化
function add1(x){
    return function(y){
        return x+y
    }
}
add1(2)(3)

高阶函数

接收其他函数作为参数,或者返回其他函数的函数

function foo(){
    let a =2
    function bar(){
        console.log(a);
        
    }
    return bar
}

let baz=foo()
baz()

字符串方法

//增
let str1 = "hello ";
let str2 = str1.concat("world");
console.log(str2); // "hello world"

//删除 
//slice,截取包括前面不包括后面
//substr,截取包括前面也包括后面
//substring,截取包括前面不包括后面

let stringValue = "hello";
console.log(stringValue.slice(2)); // "llo"
console.log(stringValue.slice(1, 3)) //"el"

console.log(stringValue.substr(2)); // "llo"
console.log(stringValue.substr(1, 3)) //"ell"

console.log(stringValue.substring(2))  //"llo"
console.log(stringValue.substring(1, 3)) //"el"

//改
//trim():清空空格,toUpperCase(),toLowerCase()大小写
//replace("要替换对象","替换内容")
let repStr="abcd"
let res=repStr.replace('a',"f")
console.log(res);//fbcd


//查
//indexOf,查询是否存在字符串,有返回索引,没有返-1
let str3='mes'
console.log(str3.indexOf('e'));//1
//includes,查询是否存在字符串,返回布尔值

let str4="abc"
console.log(str4.includes('a')); //true

//转化方法
//spit,转化为数组
let str5 = "12+23+34"
let arr = str5.split("+") // [12,23,34]

//length,返回字符串长度
console.log(str5.length);//8

数组方法

//增 push,unshift,splice,concat

//删 pop,shift,splice,slice

//改 splice
// let arr1=[1,2,3,4]
// arr1.splice(1,0,9)
// console.log(arr1);//[ 1, 9, 2, 3, 4 ]

//查
//indexOf,返回元素索引,未找到返回-1
//includes,返回布尔值
//find,回调,返回符合第一个匹配的元素.   findIndex,返回第一个符合条件的元素下标

//reverse,元素反转, sort排序,join返回元素组成的字符串
//some,every 满足条件返回true或者false
//filter,返回满足条件的元素组成的新数组
//forEach,map
//reduce,累加处理
// new Set去重

事件循环

先同步,后异步,异步中先微任务后宏任务

微任务:promise.then()等

宏任务:script,定时器等

console.log(1);
setTimeout(() => {
  console.log(2);
}, 0);
new Promise((resolve, reject) => {
  console.log("new Promise"); //promise里面是同步,.then后面才是异步
  resolve();
}).then(() => {
  console.log("then");
});
console.log(3);

//结果1   new Promise    3    then   2



async await

async function fn1() {
  console.log(1);
  await fn2();
  console.log(2); //会阻塞,变成微任务
}
async function fn2() {
  console.log("fn2");
}
setTimeout(()=>{
    console.log(4);
},1)
fn1();
console.log(3)


//打印 1     fn2    3   2   4

async function async1() {
  console.log("2");
  await async2();
  console.log("6"); //会阻塞,加入微任务列表
}

async function async2() {
  console.log("3");
}

console.log("1");

setTimeout(function () {
  console.log("8");
});

async1();

new Promise(function (resolve) {
  console.log("4");
  resolve();
}).then(function () {
  console.log("7");
});

console.log("5");

本地储存

cookie

小型文本文件,指某些网站为了辨别用户身份而储存再本地终端的数据。大小不超过4kb,有name和value组成。但是cookie每次请求都会发生,如果不使用https并对其加密,容易泄露。

cookie的数据会自动传递到服务器

sessionStorage,localStorage,sessionStorage页面关闭就会删除数据 大小5m

indexedDB 数据库,储存没有上线,但是有一定门槛

大文件断点续传

125页,待续

防抖和节流

防抖:类似游戏回城,打断重新回。n秒后再执行该事件,如果n秒内重复触发,则重新计时。

//防抖主要用于搜索框输入,文本编译器实时保存

 
//定义一个全局变量
  let timer: any = null
  function dfn() {
    //如果timer存在,就清除。
    if (timer !== null) {
      clearTimeout(timer)
    }
    //1秒后会打印,还没到1秒再次执行dfn,timer此时存在,就会cleartimer,在重新执行setTiomeout
    timer = setTimeout(() => {
      console.log("防抖");

    }, 1000)

  }

节流:n秒内不管触发多少次,只执行一次

//节流,主要是用于高频事件,比如快速点击,scroll事件,resize事件等

let timer: any = null
function jfn() {
    //如果timer存在,就直接结束jfn
    if (timer !== null) {
      return
    }
    //1秒后会打印,还没到1秒再次执行jfn,timer此时存在,会直接return
    timer = setTimeout(() => {
      console.log("节流");
      timer = null

    }, 1000)

  }

函数式编程

一种方案简单、功能独立、对作用域外没有任何副作用的编程范式

函数式编程:

1)功能独立——不依赖于程序的状态(比如可能发生变化的全局变量);

2)纯函数——同一个输入永远能得到同一个输出;

3)有限的副作用——可以严格地限制函数外部对状态的更改。

垃圾回收机制

引用计数

跟踪每个对象的引用次数。当一个对象被引用时,它的引用计数加一;当引用失效时,引用计数减一。当引用计数为零时,表示该对象不再被使用,可以被回收。

let obj1 = { a: 1 }; // 对象 { a: 1 } 的引用计数为 1
let obj2 = obj1; // 对象 { a: 1 } 的引用计数为 2
 
obj1 = null; // 对象 { a: 1 } 的引用计数减为 1
obj2 = null; // 对象 { a: 1 } 的引用计数减为 0,可以被回收

标记清除

通过定期遍历所有对象,标记那些仍然在使用的对象,然后清除那些未被标记的对象。

标记阶段:

从根对象(如全局对象、活动函数等)开始,遍历所有可以访问到的对象,并标记它们。

清除阶段:

遍历所有对象,清除那些未被标记的对象。

let obj1 = { a: 1 }; // 对象 { a: 1 } 被标记为活动对象
let obj2 = { b: 2 }; // 对象 { b: 2 } 被标记为活动对象
 
obj1 = null; // 对象 { a: 1 } 不再被引用,在下一次垃圾回收时将被清除
obj2 = null; // 对象 { b: 2 } 不再被引用,在下一次垃圾回收时将被清除

NEW操作符

new操作符做了哪些事:1,先创建一个新的空对象。2,新对象的原型指向构造函数的prototype。

3,执行构造函数。4,返回处理后的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值