javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > js底层原理

JavaScript底层原理解析与面试深度知识点

作者:宁风NF

本文讲解了JavaScript中关于底层原理与面试相关等知识点,文章围绕着“是什么、为什么、怎么用”结构讲解,加上代码示例,让你全面详细地吸收知识,附上实战练习与思考题,感兴趣的朋友跟随小编一起看看吧

第十四阶段:底层原理与面试深度知识点

  1. JS 执行上下文、执行栈、变量对象 VO、活动对象 AO

执行上下文:

执行栈:

变量对象 VO:

活动对象 AO:

  1. 作用域链创建过程
function outer() {
    let outerVar = 'outer';
    function inner() {
        let innerVar = 'inner';
        console.log(outerVar); 
    }
    inner();
}
outer();

inner 函数执行时,其作用域链为 inner 函数的 AO-> outer 函数的 AO-> 全局 VO。当查找 outerVar 时,先在 inner 函数的 AO 中找,没找到则到 outer 函数的 AO 中找,最终找到。

  1. 原型链完整查找流程
function Animal(name) {
    this.name = name;
}
Animal.prototype.speak = function () {
    return `${this.name} makes a sound.`;
};
function Dog(name, breed) {
    Animal.call(this, name);
    this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const myDog = new Dog('Buddy', 'Golden Retriever');
console.log(myDog.speak()); 

这里 myDog 对象查找 speak 方法,先在自身找,没找到,通过 __proto__Dog.prototype 找,还没找到,再通过 Dog.prototype.__proto__Animal.prototype 找到。

  1. Event Loop 完整执行流程(浏览器 + Node 对比)

浏览器中的 Event Loop:

Node 中的 Event Loop:

对比:

  1. 宏任务微任务优先级细节
console.log('同步任务');
setTimeout(() => {
    console.log('宏任务 setTimeout');
}, 0);
Promise.resolve().then(() => {
    console.log('微任务 Promise.then');
});

输出顺序为:“同步任务”-> “微任务 Promise.then”-> “宏任务 setTimeout”。

  1. 函数提升、变量提升底层原理

函数提升:

func(); 
function func() {
    console.log('函数被调用');
}

这里 func 函数在声明之前被调用,因为函数声明被提升到了作用域顶部。

变量提升:

console.log(a); 
var a = 10;

这里会输出 undefined,因为 var a 被提升,但 a = 10 不会提升。

  1. Promise 微任务调度机制
console.log('同步任务');
Promise.resolve().then(() => {
    console.log('Promise 微任务');
});
console.log('同步任务');

输出顺序为:“同步任务”-> “同步任务”-> “Promise 微任务”。

  1. 类与原型底层等价转换(class 本质是语法糖)
// class 写法
class Animal {
    constructor(name) {
        this.name = name;
    }
    speak() {
        return `${this.name} makes a sound.`;
    }
}
// 等价的原型写法
function AnimalProto(name) {
    this.name = name;
}
AnimalProto.prototype.speak = function () {
    return `${this.name} makes a sound.`;
};

这里 class Animal 本质上就是对 AnimalProto 函数及其原型操作的一种语法封装,classconstructor 对应函数的参数和内部赋值,class 的方法定义对应在原型上添加方法。

  1. 可迭代协议、迭代器协议底层规范

可迭代协议:

const myArray = [1, 2, 3];
const iterator = myArray[Symbol.iterator]();
console.log(iterator.next()); 
console.log(iterator.next()); 
console.log(iterator.next()); 
console.log(iterator.next()); 

这里数组是可迭代对象,因为它实现了 Symbol.iterator 方法。

迭代器协议:

  1. 模块化加载机制(ES Module 与 CommonJS 差异)

加载时机:

import { func } from './module.js';
// 这里在编译时就确定了依赖关系
const module = require('./module.js');
// 这里在运行时才加载模块

导出方式:

// 具名导出
export const func1 = () => console.log('Func1');
// 默认导出
export default () => console.log('Default export');
function func1() {
    console.log('Func1');
}
exports.func1 = func1;
// 或者
module.exports = {
    func1: function () {
        console.log('Func1');
    }
};

导入方式:

import { func1 } from './module.js';
import myDefault from './module.js';
const { func1 } = require('./module.js');
const myModule = require('./module.js');

循环依赖处理:

// a.js
const b = require('./b.js');
console.log('a.js:', b.value);
exports.value = 'a 的值';
// b.js
const a = require('./a.js');
console.log('b.js:', a.value);
exports.value = 'b 的值';

在 CommonJS 中,a.js 中打印 b.value 可能得到 undefined,而 ES Module 对这种情况有更合理的处理方式。

实战练习:

  1. 混合多层 Promise、定时器、同步代码,手动推导打印顺序
  2. 将 class 语法手动转换为原生构造函数 + 原型代码

思考题:

  1. 变量提升底层原理是什么?
  2. Promise.then 为什么属于微任务?
  3. ES Module 加载是同步还是异步?

到此这篇关于JavaScript底层原理解析与面试深度知识点的文章就介绍到这了,更多相关js底层原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文