JavaScript保姆级教程 ——— 重难点详细解析(万字长文,建议收藏)(下)

简介: 笔记

5. call和apply及bind三者的区别(面试重点)


this指向,apply,call,bind的区别是一个经典的面试问题

同时在项目中会经常使用到的原生的js方法。

也是ES5中的众多坑的一个

5.1 从this说起


this指向 = 谁调用,指向谁(这是错误的!!!)

this永远指向最后一个调用它的那个对象(正解)

如何解决this指向问题

2.png

  1. 使用ES6中箭头函数
  2. 函数内部使用_this = this
  3. 使用apply,call,bind方法
  4. new实例化一个对象

5.2 谈谈apply,call,bind

  • apply()
let obj = {
    name : "小明",
    func1: function () {
        console.log(this.name)
    },
    func2: function () {
        setTimeout(  function () {
            this.func1()
        }.apply(name),1000);
    }
};
obj.func2()            // 小明

apply() 方法调用一个函数,其具有一个指定的this值,以及作为一个数组(或者类似数组的对象)提供的参数,fun.apply(thisArg, [argsArray])


thisArg:在fun函数运行时指定的this值。指定this的值并不一定是函数执行时真正的this值,如果是原始值的this会指向该原始值的自动包装对象。


argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给fun函数。参数为null或者undefined,则表示不需要传入任何参数。


call()

let obj2 = {
    name : "小红",
    func1: function () {
        console.log(this.name)
    },
    func2: function () {
        setTimeout(  function () {
            this.func1()
        }.call(name),1000);
    }
};
obj2.func2()            // 小红

call() 调用一个函数,其具有一个指定的this值,以及若干个参数列表,fun.call(thisArg, arg1, arg2, …)


thisArg:在fun函数运行时指定的this值。指定this的值并不一定是函数执行时真正的this值,如果是原始值的this会指向该原始值的自动包装对象。


arg1, arg2, …:若干个参数列表


bind()

let obj3 = {
    name : "小猪",
    func1: function () {
        console.log(this.name)
    },
    func2: function () {
        setTimeout(  function () {
            this.func1()
        }.bind(name)(),1000);
    }
};
obj3.func2()            // 小猪

bind() 创建一个新的函数,当被调用时,将其this的关键字设置为提供的值,在调用新函数时,在任何提供一个给定的参数序列。


bind创建了一个新函数,必须手动去调用。


5.3 区别


apply和call基本类似,他们的区别只是传入的参数不同。

apply传入的参数是包含多个参数的数组

call传入的参数是若干个参数列表

bind方法会创建一个新的函数,当被调用的时候,将其this关键字设置为提供的值,我们必须手动去调用3.png


6. Javascript的事件流模型(面试重点)


事件冒泡:事件开始由最具体的元素接受,然后逐级向上传播

4.png

事件捕捉:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的(与上面相反)


DOM事件流:三个阶段:事件捕捉,目标阶段,事件冒泡


7. 防抖与节流(面试精选)


7.1 函数防抖


当持续触发事件时,一段时间内只能触发一次。将几次操作合并为一此操作进行。比如说有一条赛车通道,赛车通过的时间为5s,5s之后到达终点,执行领奖操作

5.png

这5s之内只允许一辆赛车在通道内,如果第一辆赛车还在通道内,此时第二辆赛车已经进来了,那么销毁第一辆赛车,从第二辆车入场重新计时5s执行领奖操作

6.png

应用场景(数据抖动问题)

let telInput = document.querySelector('input');
telInput.addEventListener('input', function(e) {
        //如果直接每次发请求,会导致性能问题
        //数据请求
        let timeOut = null;
        if(timeOut){
      clearTimeout(timeOut)
    }else{
      timeOut = setTimeout(()=>{
        $.ajax({})
        },2000)
      }
})

7.2 函数节流


当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流,顾名思义,节制流入或流出。

比如说水龙头放水,一旦打开开关,水流就会很快,我们要做的就是限制流出

应用场景(客运站问题)


把整个事件处理器比喻成客运站,如果客运大巴到站就走,那么路上肯定会发生交通拥堵,而且车大部分是空的


因为没给时间上客,虚假繁忙的情况肯定是不好的,那么怎么处理呢?


设置一个时间间隔,时间间隔内只允许执行一次,客运站大巴设定一个时间,到点才会走

let throttle = function(func, delay) {            
  let prev = Date.now();            
  return function() {                
    var context = this;                
    var args = arguments;                
    var now = Date.now();                
    if (now - prev >= delay) {                    
      func.apply(context, args);                    
      prev = Date.now();                
    }            
  }        
}        
function demo() {            
  //do something
    //ajax({})
    //...      
}        
box.addEventListener('touchmove', throttle(demo, 2000));

8. JS中的虚拟DOM是什么?(面试重点)


7.png8.1 为什么要有虚拟dom?


文档对象模型或 DOM 定义了一个接口,该接口允许 JavaScript 之类的语言访问和操作 HTML 文档

但是此接口需要付出代价,大量非常频繁的 DOM 操作会使页面速度变慢

虚拟dom的出现就是为了解决操作dom的性能问题

8.2 虚拟dom是什么?好处是?


本质就是JS对象

真实节点抽象成JS对象(文档结构树)

虚拟节点(VNode)表示 DOM 树中的节点。当需要操纵时,可以在虚拟 DOM的 内存中执行计算和操作,而不是在真实 DOM 上进行操纵。

相对于直接操作dom,这自然会更快


9. 手写一个new,实现同等功能


function Person(name) {
    this.name = name
    this.sayName= function () {
        console.log(`我是 ${this.name}!`)
    }
}
function myNew(that, ...args) {
    const obj = Object.create(null)
    obj.__proto__ = that.prototype
    const res = that.call(obj, ...args)
    return res instanceof Object ? res : obj
}
let person= myNew(Person, '小明')
person.sayWorld(); // 我是小明


10. 获得页面url参数的值(常用)


function getQueryString(name) { 
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); 
  var r = window.location.search.substr(1).match(reg); 
  if (r != null) return unescape(r[2]); 
  return null; 
} 
目录
相关文章
|
2月前
|
JavaScript 前端开发 开发者
Nest.js控制器深度解析:路由与请求处理的高级特性
以上就是对 NestJS 控制层高级特性深度解析:从基本概念到异步支持再到更复杂场景下拦截其与管道等功能性组件运用都有所涉及,希望能够帮助开发者更好地理解和运用 NestJS 进行高效开发工作。
321 15
|
2月前
|
JavaScript 前端开发 IDE
TypeScript vs. JavaScript:技术对比与核心差异解析
TypeScript 作为 JavaScript 的超集,通过静态类型系统、编译时错误检测和强大的工具链支持,显著提升代码质量与可维护性,尤其适用于中大型项目和团队协作。相较之下,JavaScript 更灵活,适合快速原型开发。本文从类型系统、错误检测、工具支持等多维度对比两者差异,并提供技术选型建议,助力开发者合理选择。
602 1
|
2月前
|
存储 JavaScript 前端开发
JavaScript 语法全面解析
JavaScript 语法体系丰富且不断更新,从基础的变量声明、数据类型,到复杂的函数、对象、异步语法,每个知识点都需要开发者深入理解并灵活运用。本文梳理的 JS 语法核心内容,可为开发者提供系统的学习框架,后续还需通过大量实践(如编写交互组件、实现业务逻辑)巩固知识,逐步提升 JS 编程能力,应对前端开发中的各类挑战。
|
5月前
|
机器学习/深度学习 JavaScript 前端开发
JS进阶教程:递归函数原理与篇例解析
通过对这些代码示例的学习,我们已经了解了递归的原理以及递归在JS中的应用方法。递归虽然有着理论升华,但弄清它的核心思想并不难。举个随手可见的例子,火影鸣人做的影分身,你看到的都是同一个鸣人,但他们的行为却能在全局产生影响,这不就是递归吗?雾里看花,透过其间你或许已经深入了递归的魅力之中。
247 19
|
6月前
|
JSON 前端开发 Serverless
Mock.js 语法结构全解析
Mock.js 的语法规范介绍,从数据模板定义规范和数据占位符定义规范俩部分介绍, 让你更好的使用 Mock.js 来模拟数据并提高开发效率。
|
8月前
|
资源调度 JavaScript 前端开发
前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
7432 23
|
8月前
|
数据采集 前端开发 JavaScript
金融数据分析:解析JavaScript渲染的隐藏表格
本文详解了如何使用Python与Selenium结合代理IP技术,从金融网站(如东方财富网)抓取由JavaScript渲染的隐藏表格数据。内容涵盖环境搭建、代理配置、模拟用户行为、数据解析与分析等关键步骤。通过设置Cookie和User-Agent,突破反爬机制;借助Selenium等待页面渲染,精准定位动态数据。同时,提供了常见错误解决方案及延伸练习,帮助读者掌握金融数据采集的核心技能,为投资决策提供支持。注意规避动态加载、代理验证及元素定位等潜在陷阱,确保数据抓取高效稳定。
263 17
|
8月前
|
存储 JavaScript 前端开发
全网最全情景,深入浅出解析JavaScript数组去重:数值与引用类型的全面攻略
如果是基础类型数组,优先选择 Set。 对于引用类型数组,根据需求选择 Map 或 JSON.stringify()。 其余情况根据实际需求进行混合调用,就能更好的实现数组去重。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
8月前
|
消息中间件 JavaScript 前端开发
最细最有条理解析:事件循环(消息循环)是什么?为什么JS需要异步
度一教育的袁进老师谈到他的理解:单线程是异步产生的原因,事件循环是异步的实现方式。 本质是因为渲染进程因为计算机图形学的限制,只能是单线程。所以需要“异步”这个技术思想来解决页面阻塞的问题,而“事件循环”是实现“异步”这个技术思想的最主要的技术手段。 但事件循环并不是全部的技术手段,比如Promise,虽然受事件循环管理,但是如果没有事件循环,单一Promise依然能实现异步不是吗? 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您
|
8月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
825 29

热门文章

最新文章

推荐镜像

更多
  • DNS
  • 下一篇
    oss云网关配置