面试官最爱问的JavaScript八股文,我用这5段代码给你讲明白(附手写实现)
面试官最爱问的JavaScript八股文我用这5段代码给你讲明白附手写实现1. 原型链从代码看透JavaScript的继承本质面试中关于原型链的问题往往以请解释new一个对象的过程开场。让我们用一段代码揭开这个机制的神秘面纱function Person(name) { this.name name; } Person.prototype.sayHi function() { console.log(Hi, Im ${this.name}); }; const p new Person(Alice); p.sayHi(); // 输出: Hi, Im Alice这段简单的代码背后隐藏着JavaScript最核心的继承机制。当执行new Person()时引擎会依次完成以下操作创建一个空对象其__proto__指向Person.prototype将构造函数内部的this绑定到这个新对象执行构造函数内部的代码为对象添加属性如果构造函数没有返回对象则自动返回这个新对象易错点提醒直接修改prototype会切断原有原型链Person.prototype {...}__proto__是非标准属性生产环境建议使用Object.getPrototypeOf()箭头函数不能作为构造函数因为它没有prototype属性面试技巧当被问到如何实现继承时可以先从最简单的原型链继承讲起再逐步引出ES6的class语法糖展示你对语言演进的理解。2. this指向5种绑定规则的实战代码this的指向问题堪称JavaScript面试的必考题。下面这段代码浓缩了所有this绑定规则const obj { name: obj, print: function() { console.log(this.name); }, printArrow: () { console.log(this.name); } }; // 默认绑定 function defaultBind() { console.log(this window); // 浏览器中为true } // 隐式绑定 obj.print(); // obj // 显式绑定 obj.print.call({ name: call }); // call // new绑定 new obj.print(); // undefined // 箭头函数 obj.printArrow(); // 取决于外层作用域关键记忆点绑定类型判定条件典型场景默认绑定独立函数调用全局函数、回调函数隐式绑定上下文对象调用obj.method()显式绑定call/apply/bind强制指定thisnew绑定构造函数调用new Constructor()箭头函数词法作用域保持外层this3. 闭包与模块模式封装私有变量的艺术闭包问题通常会以实现一个计数器的形式出现。看这段实现私有变量的代码function createCounter() { let count 0; // 私有变量 return { increment() { return count; }, get value() { return count; } }; } const counter createCounter(); counter.increment(); console.log(counter.value); // 1 console.log(counter.count); // undefined闭包的三大实战应用数据封装如上例函数工厂参数定制化异步编程保持回调状态常见陷阱在循环中创建闭包时如果不使用立即执行函数或let声明所有闭包会共享同一个变量引用。4. 异步编程从Promise到手写async/await现代JavaScript面试必考异步处理。这段代码展示了Promise的核心机制class MyPromise { constructor(executor) { this.state pending; this.value undefined; this.onFulfilledCallbacks []; const resolve (value) { if (this.state pending) { this.state fulfilled; this.value value; this.onFulfilledCallbacks.forEach(fn fn()); } }; executor(resolve); } then(onFulfilled) { return new MyPromise((resolve) { const wrappedFn () { const result onFulfilled(this.value); resolve(result); }; if (this.state fulfilled) { wrappedFn(); } else { this.onFulfilledCallbacks.push(wrappedFn); } }); } } // 使用示例 new MyPromise(resolve { setTimeout(() resolve(42), 100); }).then(value { console.log(value); // 输出: 42 return value 1; }).then(console.log); // 输出: 43异步编程演进路线回调地狱 → Promise链式调用Generator Promise → async/await顶级awaitES20225. 性能优化防抖与节流的代码实现高频事件处理是前端性能优化的重点。下面是防抖和节流的经典实现// 防抖连续触发时只执行最后一次 function debounce(fn, delay) { let timer null; return function(...args) { clearTimeout(timer); timer setTimeout(() { fn.apply(this, args); }, delay); }; } // 节流固定时间间隔执行 function throttle(fn, interval) { let lastTime 0; return function(...args) { const now Date.now(); if (now - lastTime interval) { fn.apply(this, args); lastTime now; } }; } // 使用对比 window.addEventListener(resize, debounce(() { console.log(防抖处理后的resize); }, 200)); window.addEventListener(scroll, throttle(() { console.log(节流处理后的scroll); }, 100));应用场景选择指南技术适用场景典型案例防抖连续事件结束后处理搜索框输入、窗口resize节流保持固定频率处理滚动事件、动画渲染6. ES6核心特性从解构到Proxy的代码演示现代JavaScript开发离不开ES6特性。这段代码展示了几个关键特性// 解构赋值 const [first, ...rest] [1, 2, 3]; const { name, ...others } { name: Alice, age: 25 }; // 箭头函数与this const obj { values: [1, 2, 3], print: function() { this.values.forEach(v { console.log(this obj); // true }); } }; // Proxy拦截 const reactive (target) new Proxy(target, { get(obj, prop) { console.log(读取 ${prop}); return obj[prop]; }, set(obj, prop, value) { console.log(设置 ${prop} ${value}); obj[prop] value; return true; } }); const data reactive({ count: 0 }); data.count; // 触发日志输出必须掌握的ES6特性块级作用域let/const模板字符串默认参数与剩余参数模块化import/export类语法糖迭代器与生成器Promise/async/await各种新增APIArray/Object方法等
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2449184.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!