深入理解JS | 青训营笔记

59 阅读4分钟

js基本概念

基本特点

  • 借鉴C语言的基本语法
  • 借鉴java的数据类型和内存管理
  • 借鉴SCHEME语言,将函数提升到一等公民身份
  • 借鉴SELF语言,使用基于原型(ProtoType)的继承机制

浏览器进程与渲染进程的展开

image.png

js基本概念

  1. 单线程: GUI线程和JS线程不能同时执行,互斥。

image.png 2. 动态,弱类型 定义变量不需要指定类型,而在其他语言中,比如C,C++都需要指定类型

image.png

  1. 面向对象,函数式:这两个东西与面向对象编程和函数式编程是一个概念,前面的老师讲过编程范式,如果认真听的话应该还记得这件事,简单复习下,

面向对象编程的思维方式是把现实世界中的事物抽象成程序世界中的类和对象,通过封装、继承和多态来演示事物事件的联系。

在JS中使用函数式编程,要求我们尽量使用纯函数,将大部分的逻辑的主要功能进行抽离,封装成新的函数。在调用该函数的时候只需传入需要的配置,就能实现向实例中添加新功能的作用。比如这是个简单的函数编程的例子。

// 将字符串转换为大写并添加感叹号
const toUpperCase = str => str.toUpperCase();
const exclaim = str => `${str}!`;
const shout = str => exclaim(toUpperCase(str));

console.log(shout('hello world')); // 输出: HELLO WORLD!
  1. 解释类语言 JIT

JS是一种解释型语言,程序在运行时边编译边运行,因此需要用到解释器才可执行代码,且执行效率天生比编译型语言低

JIT:即时编译,是一种编译技术,它可以在运行时将代码编译为机器语言,以提高程序的执行效率。

  1. 安全,性能差

JavaScript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言。它不允许访问本地的硬盘,不能将数据存入服务器,不允许对网络文档进行修改和删除。边解释,边执行,所以性能会相对差,

数据类型

分为基本数据类型,和引用数据类型

image.png

作用域

规定了变量分为可访问性和可见性,作用域分为动态作用域和静态作用域,js是静态作用域,通过作用域可以知道代码如何查找标识符。js中的作用域分为三种,全局作用域,函数作用域,块作用域。

image.png

变量提升

变量提升(hoisting)是JavaScript中的一个特性,它指的是在执行代码之前,变量和函数声明会被移动到它们所在作用域的顶部。

举例

console.log(x); // 输出: undefined
var x = 10;

在这个例子中,我们在声明变量 x 之前就使用了它。由于变量提升的原因,这段代码实际上相当于:

var x;
console.log(x); // 输出: undefined
x = 10;

变量 x 被提升到了它所在作用域的顶部,并且被初始化为 undefined。因此,在声明变量 x 之前使用它不会报错,而是输出 undefined

函数声明也会被提升,下面是一个例子:

foo(); // 输出: Hello, world!

function foo() {
  console.log('Hello, world!');
}

在这个例子中,我们在声明函数 foo 之前就调用了它。由于函数声明提升的原因,这段代码实际上相当于:

function foo() {
  console.log('Hello, world!');
}

foo(); // 输出: Hello, world!

函数 foo 被提升到了它所在作用域的顶部,因此,在声明函数 foo 之前调用它不会报错,而是正常输出 Hello, world!

a()
var a = foo(); // 输出: Hello, world!

function foo() {
  console.log('Hello, world!');
}
// Uncaught TypeError: a is not a function

如果像上面那样将函数赋值给a,还是会报错,因为上面这段代码相当于

// 变量提升 
var a = undefined

a() // undefined不是一个function
var a = foo(); // 输出: Hello, world!

function foo() {
  console.log('Hello, world!');
}
// Uncaught TypeError: a is not a function

改为let,做一个实验

a()
let a = foo(); 

function foo() {
  console.log('Hello, world!');
}
// Cannot access 'a' before initialization

let a = foo();,这里使用了 let 关键字来声明变量 a。使用 let 和 const 声明的变量不会被提升,所以会在第一行 a() 会报错,因为在这一行之前并没有定义变量 a。在 JavaScript 中,如果你试图访问一个未定义的变量,就会抛出一个错误。