JS的一些小知识点

189 阅读3分钟
  1. JS的类型
  • 常见值类型:boolean,symbol,string,number,undefined
  • 引用类型:array,object,function,null
  1. typeof 运算符
  • 识别所有值类型
  • 识别函数
  • 判断是否是引用类型(不可在细分)
  1. == 除了判断==null的时候其他都用===,其中if(obj == null) 等价于if(obj === null || obj === undefined) null == undefined 结果为 true

  2. 0'',undefined,null,NAN,falsefalsely值 ,falsely值是指!!即,两次取反,返回的值

  3. Object.__proto__null

6. instanceof (a instanceof Array)的实现原理其实就是判断a的__proto__是否指向了Array的prototype

  1. 闭包
  • 函数作为返回值
function fn(){
	const a = 100;
    return function(){
    	console.log(a)
    }
}
const fn1 = fn()
const a = 200
fn1()// 100
  • 函数作为参数
function print(fn){
	const a =100
    fn()
}
const a = 200
function fn(){
	console.log(a)
}
print(fn)//200

闭包是自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方查找

  1. hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。

  2. call,apply,bind实现

  • call
Function.prototype.mycall = function(obj){
  //获取剩余元素
  const args = [...arguments].slice(1)
  obj.fn = this//this指向调用的fn1
  console.log(this)
  const newfn = obj.fn(...args)
  delete obj.fn
  return newfn
  
}
function fn1(a, b, c) {
    console.log('this', this)
    console.log(a, b, c)
    return 'this is fn1'
}
fn1.call([1,2],3,4,5)
fn1.mycall([1,2],3,4,5)
  • apply
Function.prototype.myapply = function(obj){
  //获取剩余元素
  const args = [...arguments].slice(1)
  obj.fn = this
  const newfn = obj.fn(...args[0])//相当于包这一个array
  return newfn
  
}
function fn1(a, b, c) {
    console.log('this', this)
    console.log(a, b, c)
    return 'this is fn1'
}
fn1.apply([1,2],[3,4,5])
fn1.myapply([1,2],[3,4,5])
  • bind
Function.prototype.mybind = function(){
  //获取剩余元素
  const t = [...arguments].shift()
  const args = [...arguments].slice(1)
  self= this
  return function (){
    self.apply(t,args)
  }
  
}
function fn1(a, b, c) {
    console.log('this', this)
    console.log(a, b, c)
    return 'this is fn1'
}
const fn2 =fn1.bind([1,2],3,4,5)
fn2()
const fn3 =fn1.mybind([1,2],3,4,5)
fn3()
  1. 异步应用场景
  • 网络请求,如ajax图片加载
  • 定时任务,setTimeout promise的出现是为了解决callback hell (回调地狱) 问题
  1. eventloop 异步:ajax和setTimeout都是使用了回调,基于event loop dom也是使用了回调,基于eventloop

  2. promise 三个状态 pending resolved rejected pending状态不会触发then和catch

thencatch无论是哪个,只要是里面没有返回一个error都是resolved的promise

const p = Promise.resolve().then(()=>{console.log(1); throw Error('Err')})//rejected
        p.catch(()=>{console.log(2)}) //resolved
        .then(()=>{console.log(3)})	//resolved

const p = Promise.resolve().then(()=>{console.log(1); throw Error('Err')})//rejected
        p.catch(()=>{console.log(2)}) //resloved
        .catch(()=>{console.log(3)})

async 封装promise,执行async函数,return 一个promise对象await相当于promise.then try...catch...可捕获异常,代替了promise的catch

!(async function fn1 (){
            const p= Promise.reject('err')
            const res = await p
            console.log(res)
        })()

!(async function fn1 (){
            const p= Promise.resolve(100)
            const res = await p
            console.log(res)
        })()

  1. for.. of..(for in)和forEach不同,他是必须等一个回调结束才会调取下一个,也就是说2,4,6会1秒钟一个的出现
const arr =[1,2,3]
        arr.forEach(async (i)=>{
            const p = await add(i)
                console.log(p)
        })
------
function add(num){
            return new Promise((resolve)=>{
                setTimeout(()=>
                resolve(num+num),1000)
            })
        }
        const arr =[1,2,3]
        !(async function fn1(){
            for(let i of arr){
                console.log(i)
                const p = await add(i)
                console.log(p)
            } 
        })()

为什么宏任务的执行时间比微任务 是因为宏任务是在DOM渲染之后触发的,而微任务是在DOM渲染之前触发的 微任务是由ES6规定的,宏任务是由浏览器规定的