JS基础知识学习总结

JS 学习总结

1. typeof能判断的类型?(JS变量类型)

答:undefined、number、string、boolean、symbol、object、function

2. 何时使用===,何时使用==(强制类型转换)

答:任何时候都用===,除非是判断==null

3. window.onload和DOMContentLoaded的区别(页面加载过程)

答:window.onload是在页面元素全部加载结束后触发,二DOMContentLoaded是在页面的骨架渲染出来,而图片等资源尚未渲染时触发,用户等待时间短

4. JS创建10个<a>标签,点击弹出对应的序号(JS作用域)

答:

for(let i = 0; i < 10; i++){
  const a = document.createElement('a');
  a.href="javascript:;";
  a.addEventListener('click', function () {
    alert(i)
  })
  a.innerHTML = `标签${i}`;
  document.body.appendChild(a)
}

5. 手写节流throttle和防抖debounce(性能、体验优化)

  • 防抖debounce
  function debounce (fn ,delay = 500) {
    let timer = null
    return function () {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout( () => {
        fn.apply(this, arguments)
      }, delay)
    }
  }

  const input = document.getElementById('input')input.addEventListener('keyup', debounce(function(){
    console.log(this.value)
  }, 1000))
  
  • 节流throttle
  function throttle(fn, delay = 100) {
    let timer = null
    return function () {
      if (timer) {
        return
      }
      timer = setTimeout(() => {
        fn.apply(this, arguments)
        timer = null
      }, delay);
    }
  }
  
  const div = document.getElementById('div')
  div.addEventListener('drag', throttle(function(e){
    console.log(e.offsetX, e.offsetY)
  }, 200))

6. Promise解决什么问题?(JS异步)

答:回调地狱

7. 值类型和引用类型的区别(值类型和引用类型)

答:值类型是存放在栈中。引用类型是放在堆中,栈中存放的是该变量在堆中的内存地址。

8. 手写深拷贝 (值类型和引用类型)

/**
 * 深拷贝
 * @param {Object} obj 要拷贝的对象
 */
function deepClone(obj) {
  if (typeof obj !== 'object' || obj === null) return obj
  let newObj
  if (obj instanceof Array) {
    newObj = []
  } else {
    newObj = {}
  }
  for (let key in obj) {
    if (obj.hasOwnProperty(key))
      newObj[key] = deepClone(obj[key])
  }
  return newObj
}

9. 如何准确判断一个变量是不是数组?(原型链)

答:a instanceof Array

10. 手写一个简易的jQuery, 考虑插件和扩展性 (class)

答:

class jQuery {
  constructor(selector) {
    this.selector = selector
    const res = document.querySelectorAll(selector)
    for(let i = 0; i < res.length; i++) {
      this[i] = res[i]
    }
    this.length = res.length
  }

  get (index) {
    return this[index]
  }

  each (fn) {
    for(let i = 0; i < this.length; i++) {
      fn(this[i])
    }
  }

  on (type, fn) {
    return this.each(function (ele) {
      ele.addEventListener(type, fn, false)
    })
  }
}

const p = new jQuery('p')
console.log(p.get(0))

// 插件
jQuery.prototype.dialog = function (info) {
  alert(info)
}

// 造轮子
class myJQuery extends jQuery {
  constructor(selector) {
    super(selector)
  }

  // 扩展自己的方法
  addClass(className) {
  }

  style(data) {
  }
}

11. class的原型本质,怎么理解?(原型和原型链)

答:所有的实例都有隐式原型__proto__,所有的class都有显示原型prototype,实例的隐式原型__proto__强等于class的显示原型 prototype,而class的显示原型prototype的隐式原型__proto__等于父类的显示原型prototype

12. this的不同应用场景,如何取值?(作用域)

  • 作为普通函数this指向window
  • 使用call、apply、bind,传入什么this就指向什么
  • 作为对象方法被调用,指向调用它的对象
  • 在class方法被调用,指向调用它的对象
  • 箭头函数,不改变this指向,this是上级作用域的this

13. 手写bind函数(this)

答:

const obj = {
  name: 'yibo'
}

function fn(a, b) {
  console.log(this)
  console.log(a + b)
  return a + b
}

function myBind(obj) {
  const context = this
  const newArguments = Array.prototype.slice.call(arguments)
  newArguments.shift()
  return function () {
    return context.apply(obj, newArguments)
  }
}

const res = fn(1, 2)
console.log(res)

Function.prototype.myBind = myBind
const myFn = fn.myBind(obj, 5, 8)
const res2 = myFn()
console.log(res2)

14. 实际开发中闭包的应用场景,举例说明

答:

// 闭包隐藏数据,只提供API
function createCache () {
  // 闭包中的数据,被隐藏,不被外接访问
  const data = {}
  return {
    set: function (key, val) {
      data[key] = val
    },
    get: function (key) {
      return data[key]
    }
  }
}

const c = createCache()

c.set('a', 100)
console.log(c.get('a'))

15. 同步和异步的区别是什么?(JS异步和单线程)

答:同步会阻塞代码执行,异步不会阻塞代码执行

16. 手写用Promise加载一张图片(Promise)

答:

    const url = 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg'
    
    function loadImg(src) {
      return new Promise((resolve, reject) => {
        console.log('start')
        const img = document.createElement('img')
        img.onload = () => {
          console.log('loaded')
          resolve(img)
        }
        img.onerror = () => {
          resolve(new Error(`图片加载失败${src}`))
        }
        img.src = src
        console.log('end')
      })
    }
    
    loadImg(url)
    .then(img => {
      document.body.appendChild(img)
      return img
    })
    .then(img => {
      console.log(img.height)
    })
    .catch(err => console.log(err))

17. 前端使用异步的场景有哪些?

答:网络请求、图片加载、定时任务

18. DOM是哪种数据结构?

答:树形结构

19. DOM操作的常用API

增删改查:getElementsByTagName、getAttribute、setAttribute、createElement、appendChild、removeChild

20. attribute和property的区别

property: 修改对象属性,不会体现到HTML结构中

attribute:修改HTML属性,会改变HTML结构

两者都可能引起DOM重新渲染

21. 一次性插入多个DOM节点,考虑性能

答:

const list = document.getElementById('list')
// 创建一个文档片段
const fragment = document.createDocumentFragment()
for(let i = 0; i < 10; i++){
const li = document.createElement('li')
li.innerHTML = i
// 插入到文档片段,文档片段是在内存中
fragment.appendChild(li)
}
// 将文档片段一次性插入
list.appendChild(fragment)

22. 如何识别浏览器的类型

答:UA,navigator.userAgent

23. 分析拆解URL各个部分

答:${protocol}${host}${pathname}${search}${hash} === ${href}

24. 编写一个通用的事件监听函数

答:

function bindEvent(ele, type, selector, fn) {
  if(!fn) {
  fn = selector
  selector = null
}
ele.addEventListener(type, function(event){
  const target = event.target
  if(selector){
    if(target.matches(selector)){
      fn.call(target, event)
    }
  }
  else {
    fn.call(target, event)
  }
})
}

25. 描述事件冒泡的流程

答:基于DOM属性结构,事件会顺着触发元素往上冒泡,应用场景:代理

26. 无限下拉的图片列表,如何监听每个图片的点击?

答:事件代理,用e.target获取触发元素,用matches来判断是否是触发元素

27. 手写一个简易的ajax

答:

function ajax(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.onreadystatechange = function () {
      if(xhr.readyState === 4) {
        if(xhr.status === 200) {
        	resolve(JSON.parse(xhr.responseText))
        }else if(xhr.status === 404){
        	reject(new Error('404 not found'))
        }
      }
    }
    xhr.send()
  })
}

const url = '/data/test.json'
ajax(url)
.then(res=>console.log(res))
.catch(err=>console.log(err))

28. 描述cookie、localStorage、sessionStorage 的区别

答:容量、API易用性、是否跟随http请求发送出去
cookie
本身用于浏览器和server通讯
被”借用“到本地存储来
可用window.cookie=’‘来修改
缺点
存储大小:最大4kb
http请求时需要发送到服务端,增加请求数据量
只能用document.cookie=’'来修改,太过简陋
localStorage、sessionStorage
HTML5专门为存储而设计,最大可存5M
API简单易用,setItem、getItem
不会随http请求发送到服务器端
localStorage数据会永久存储,除非代码或手动删除
sessionStorage数据只存在于当前会话,浏览器关闭则清空
一般用localStorage更多一些

29. 从输入url到渲染出页面的整个过程

答:下载资源:各种资源类型,下载过程。渲染页面:结合HTML、CSS、JavaScript、图片等

30. window.onload和DOMContent的区别

答:

window.addEventListener('load', funciton () {
// 页面的全部资源加载完才会执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded', function () {
// DOM 渲染完即可执行,此时图片、视频可能还没加载完
})

31. 为何建议把CSS放在head中?

答:让DOM在生成之前就和CSS整合,然后一次性渲染完。

32. 为何建议把JS放在body之后?

答:页面渲染过程比较长,被js阻碍

33. 常见的web前端攻击方式有哪些?

答:XSS跨站请求攻击:替换特殊字符 <、 >、

猜你喜欢

转载自blog.csdn.net/jal517486222/article/details/105837210