多年来,我形成了一个关于JavaScript的心智模型,给了我信心。在这里,我分享的是它的一个非常压缩的版本。它的结构像一个词汇表,每个主题都有几句话。...这个概念并不基本,但却是一个常见的错误来源。你可以学习它的工作原理未雨绸缪,但很多人都尽量避免它。 字面量。字面量是指你通过在程序中写下一个值来引用它。...你很少会与这种机制直接互动,但它解释了为什么我们的冰激凌对象有一个我们从未定义过的toString方法——它来自原型。 函数。一个函数是一个特殊的值,有一个目的:它代表你程序中的一些代码。...它给了我们一个特殊的值(一个函数),代表我们的这段代码,所以如果我们想的话,以后可以调用它。 函数声明。...例如,setTimeout接收一个回调函数,然后......在超时后回调你。但回调函数并没有什么特别之处。它们是普通的函数,当我们说 "回调 "时,我们只是在谈论我们的期望。
答案其实是: for(倒序) 最让我感到惊讶的事情是,当我在本地计算机上进行测试之后,我不得不接受 for(倒序)是所有 for 循环中最快的这一事实。...而 forEach 是 Array 原型的一个方法,与普通的 for 循环相比,forEach 和 for…of 需要花费更多的时间进行数组迭代。...(译者注:但值得注意的是,for…of 和 forEach 都从对象中获取了数据,而原型并没有,因此没有可比性。) 循环的类型,以及我们应该在何处使用它们 1....2. forEach 这个方法需要接受一个回调函数作为输入参数,遍历数组的每一个元素,并执行我们的回调函数(以元素本身和它的索引(可选参数)作为参数赋予给回调函数)。...forEach 还允许在回调函数中使用一个可选参数 this。
checkForUpdates()是你的程序可能定义的回调函数,setTimeout()是你调用以注册回调函数并指定在何种异步条件下调用它的函数。...相反,调用者传递一个回调函数,当结果准备就绪或发生错误时调用。在这种情况下,调用者提供了一个期望两个参数的回调函数。...现在我们已经检查了 Promise 链,我们可以回到错误处理并更详细地讨论它。在讨论之前,我想强调的是,在进行异步编程时,仔细处理错误非常重要。...catch() 回调可以抛出新错误,但如果它正常返回,那么返回值将用于解析和/或实现相关的 Promise,并且错误将停止传播。...这里描述的大多数其他知名 Symbols 用作原型对象的方法名称。) 当我们使用extends创建一个子类时,结果子类构造函数会继承自超类构造函数的属性。
答案其实是:for(倒序) 最让我感到惊讶的事情是,当我在本地计算机上进行测试之后,我不得不接受 for(倒序)是所有 for 循环中最快的这一事实。...这个细微的差别不是很重要,你可以忽略它。 而 forEach 是 Array 原型的一个方法,与普通的 for 循环相比,forEach 和 for…of 需要花费更多的时间进行数组迭代。...(译者注:但值得注意的是,for…of 和 forEach 都从对象中获取了数据,而原型并没有,因此没有可比性。) 循环的类型,以及我们应该在何处使用它们 1....2. forEach 这个方法需要接受一个回调函数作为输入参数,遍历数组的每一个元素,并执行我们的回调函数(以元素本身和它的索引(可选参数)作为参数赋予给回调函数)。...forEach 还允许在回调函数中使用一个可选参数 this。
; console.log(this.variable); // “我是一个全局变量!” 在这里,当我们声明变量时,它被附加到 window 对象上。...当一个函数被定义为对象方法时,this 将引用拥有该方法的对象。...并坚持使用它的原始 this。 所以,箭头还是不箭头? 箭头函数就像你拥有的那个最喜欢的工具 —— 超级有用,但不适合每一项工作。当你想保持 this不变时,尤其是在回调中,它们是非常有价值的。...与“this”有关的常见失误:要注意什么 我们认为我们已经掌握了它的时候,它给了我们一个曲线球。这就像试图抓住一个滑溜的鱼;一旦你失去焦点,它就消失了。...我们忘记了‘new’ console.log(window.name); // 输出:Buddy 事件监听器和回调:当你在事件监听器或回调函数中使用this时,确保你知道它引用的是什么。
构造函数用于在 JavaScript 中创建对象。当您定义一个构造函数时,还可以将属性和方法附加到其 prototype 属性上。这些属性和方法然后变得可以被该构造函数创建的所有对象实例访问。...每个这样的对象都有一个原型,该原型作为对另一个对象的引用。__proto__ 属性简单地是对这个原型对象的引用。 当你试图访问对象上的一个属性或方法时,JavaScript 会进行查找过程来找到它。...} var a = 5; bar(); 代码定义了两个函数 foo() 和 bar(),以及一个值为5的变量 a。...当我们定义了foo函数,它被赋予了访问自己的局部作用域和全局作用域的权限。这一特性在我们无论在哪里调用foo函数时都是一致的,无论是在bar函数内部还是在其他模块中运行。...我强烈建议你查看我的关于强制转换的详细博客文章。它以清晰和彻底的方式解释了这个概念。这里是链接。
JS有一些概念,人们往往会对它掉以轻心,有时可能会忽略不计。原型、闭包和事件循环等概念仍然是大多数JS开发人员绕道而行的晦涩领域之一。正如我们所知,无知是一件危险的事情,它可能会导致错误。 ?...当我们说“浏览器是 JS 的家”时我真正的意思是浏览器提供运行时环境来执行我们的JS代码。 浏览器的主要组件包括调用堆栈,事件循环,任务队列和Web API。...但事实并非如此,我们可以有多个任务队列。由浏览器选择其中的一个队列并在该队列中处理回调。 在底层来看,JavaScript中有宏任务和微任务。...错误 解析:展开语法 和 for-of 语句遍历iterable对象定义要遍历的数据。...在Mozilla文档中,如果一个对象实现了@@iterator方法,那么它就是可迭代的,这意味着这个对象(或者它原型链上的一个对象)必须有一个带有@@iterator键的属性,这个键可以通过常量Symbol.iterator
JS有一些概念,人们往往会对它掉以轻心,有时可能会忽略不计。原型、闭包和事件循环等概念仍然是大多数JS开发人员绕道而行的晦涩领域之一。正如我们所知,无知是一件危险的事情,它可能会导致错误。...当我们说“浏览器是 JS 的家”时我真正的意思是浏览器提供运行时环境来执行我们的JS代码。 浏览器的主要组件包括调用堆栈,事件循环*,任务队列和Web API*。...问题5 : 不会响应 解析: 大多数时候,开发人员假设在事件循环图中只有一个任务队列。但事实并非如此,我们可以有多个任务队列。由浏览器选择其中的一个队列并在该队列中处理回调。...---- 问题6 : 会导致TypeError错误 解析: 展开语法 和 for-of 语句遍历 iterable对象定义要遍历的数据。 Array 或 Map 是具有默认迭代行为的内置迭代器。...在Mozilla文档中,如果一个对象实现了 @@iterator方法,那么它就是可迭代的,这意味着这个对象(或者它原型链上的一个对象)必须有一个带有 @@iterator键的属性,这个键可以通过常量 Symbol.iterator
构造函数用于在 JavaScript 中创建对象。定义构造函数时,还可以将属性和方法附加到其原型属性。 然后,从该构造函数创建的对象的所有实例都可以访问这些属性和方法。...这些对象中的每一个都有一个原型,用作对另一个对象的引用。__proto__ 属性只是对此原型对象的引用。当原始对象不具备属性和方法时,原型对象用作属性和方法的后备源。...默认情况下,当您创建对象时,其原型设置为 Object.prototype。 当您尝试访问对象的属性或方法时,JavaScript 会遵循查找过程来查找它。...当我们定义 foo 函数时,它被授予访问其自己的本地作用域和全局作用域的权限。无论我们在哪里调用 foo 函数,无论是在 bar 函数内部还是将其导出到另一个模块并在那里运行,这个特征都保持一致。...当回调执行时,它们都会看到 i 的最终值,即 4,并尝试访问未定义的 arr[4]。
,如果我创建一个对象,更改它的原型,constructor就会变得不可靠了 function Fn(){}; Fn.prototype=new Array(); var f=new Fn();...(2)第二种方式是使用借用构造函数的方式,这种方式是通过在子类型的函数中调用超类型的构造函数来实现的,这一种方法解决了不能向超类型传递参数的缺点,但是它存在的一个问题就是无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到...当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。...说实话,看第一遍,我是不理解的,我需要去理一遍原型及原型链的知识才能理解。所以我觉得MDN对new的解释更容易理解: new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。...,整体上是按照由浅入深的顺序来的,小部分内容并非原创,相关的参考我都有在每条的末尾贴了链接,在这里要特别感谢各路大佬的博客,给了我很多帮助~ 前端是个大杂烩,各种框架层出不穷,但万变不离JS,务实基础才是根本
03、解释原型继承如何工作 原型继承允许一个对象通过建立原型链来继承另一个对象的属性。 04、null、未定义或未声明的变量之间有什么区别?...重置使您可以完全控制样式,但需要重新设置每个元素的样式。 规范化提供了更一致的基础,但可能需要额外的自定义才能满足您的设计要求。...匿名函数,也称为函数表达式,是在没有指定名称的情况下定义的函数。它们通常用于需要一个函数作为另一个函数的参数的情况或创建自调用函数时。...在事件循环的每次迭代期间,它首先处理所有微任务(例如 Promise 和排队回调),然后再继续处理下一个宏任务。 这确保了微任务具有更高的优先级,并在下一次渲染或 I/O 操作之前执行。...虽然本文提供了一般性的高级指南,但深入研究底层低级材料的细节至关重要。 为了全面了解,我强烈建议使用 frontendlead.com。该平台提供广泛的面试问题以及高质量的解决方案,包括详细的视频。
诚然,一个 promise 是这样的东西:它关联着一个预定义的类型,并能在被解决时,将一个此类型的 value 保留住。...(value) callback = nil } } 我们定义了一个实例变量callback,以在 promise 处于.pending状态时保留回调。...如我们之前所见,我们存储了第一次then的回调。但当我们第二次调用then时,promise 还是没有被解决,依然处于.pending状态,于是,我们将回调擦除换成了新的。...只有第二个回调会在将来被执行,第一个被忘记了。这使得测试虽然通过,但只有一个断言而不是两个。 解决办法也很简单,就是存储一个回调的数组,并在promise被解决时触发它们。 让我们更新一下。...就如给Optional和Array定义flatMap一样,我们也可以给Promise定义它。 困难来了。让我们一步步看看这个“flatMap”的then要怎么实现。
var关键字创建一个全局变量,当我们 push 一个函数时,这里返回的全局变量i。...因此,当我们在循环后在该数组中调用其中一个函数时,它会打印5,因为我们得到i的当前值为5,我们可以访问它,因为它是全局变量。 因为闭包在创建变量时会保留该变量的引用而不是其值。...它复制了这个封闭的词法作用域中this值,在这个例子中,this值在getName内部函数之外,也就是myFavoriteObj对象。 25. 对象的 prototype(原型) 是什么?...因此,当我们单击li元素时,它将打印5,因为这是稍后在回调函数中引用它时i的值。...什么是回调函数? 回调函数是一段可执行的代码段,它作为一个参数传递给其他的代码,其作用是在需要的时候方便调用这段(回调函数)代码。
在最近的面试中我一直在总结,每次面试回来也都会复盘,面了有七八家,也有那么几个offer,但终究不是很满意,总想再试试大一点的平台。下面是我这几天遇到的面试知识点。...,如果我创建一个对象,更改它的原型,constructor就会变得不可靠了 function Fn(){}; Fn.prototype=new Array(); var f=new Fn();...(2)第二种方式是使用借用构造函数的方式,这种方式是通过在子类型的函数中调用超类型的构造函数来实现的,这一种方法解决了不能向超类型传递参数的缺点,但是它存在的一个问题就是无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到...当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。...说实话,看第一遍,我是不理解的,我需要去理一遍原型及原型链的知识才能理解。所以我觉得MDN对new的解释更容易理解: new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
,如果我创建一个对象,更改它的原型,constructor就会变得不可靠了 function Fn(){}; Fn.prototype=new Array(); var f=new Fn();...(2)第二种方式是使用借用构造函数的方式,这种方式是通过在子类型的函数中调用超类型的构造函数来实现的,这一种方法解决了不能向超类型传递参数的缺点,但是它存在的一个问题就是无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到...当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。...说实话,看第一遍,我是不理解的,我需要去理一遍原型及原型链的知识才能理解。所以我觉得MDN对new的解释更容易理解: new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。...什么是回调函数?回调函数有什么缺点 回调函数是一段可执行的代码段,它作为一个参数传递给其他的代码,其作用是在需要的时候方便调用这段(回调函数)代码。
,如果我创建一个对象,更改它的原型,constructor就会变得不可靠了 复制代码 function Fn(){}; Fn.prototype=new Array(); var f=new...(2)第二种方式是使用借用构造函数的方式,这种方式是通过在子类型的函数中调用超类型的构造函数来实现的,这一种方法解决了不能向超类型传递参数的缺点,但是它存在的一个问题就是无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到...当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。...说实话,看第一遍,我是不理解的,我需要去理一遍原型及原型链的知识才能理解。所以我觉得MDN对new的解释更容易理解: new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。...什么是回调函数?回调函数有什么缺点 回调函数是一段可执行的代码段,它作为一个参数传递给其他的代码,其作用是在需要的时候方便调用这段(回调函数)代码。
领取专属 10元无门槛券
手把手带您无忧上云