发布于 2026-01-06 7 阅读
0

JavaScript 基础入门 🧑‍💻

JavaScript 基础教程🧑‍💻

介绍

介绍

  • 嗯,我们学习都是从某个地方开始的JavaScript,我希望也能有这样的入门指南,让我能够掌握JS的基础知识。

  • 如果您对 JavaScript 并不陌生,那么这本书将是巩固技能或打下更坚实基础的绝佳读物。

享受阅读

什么是 Javascript?

JS 是一种同步单线程语言

Synchronous它逐行执行代码。——
Single-Threaded一次只执行一行。

JS 的工作原理是什么?

  • JavaScript 在执行上下文中运行,
    它包含两个组成部分,即Memory……Code

  • 内存也称为Variable Environment

  • 代码也称为Thread of Execution

吊装

  • JS 代码提升是指 JavaScript 代码在执行时,甚至在执行第一行代码之前,就会扫描整个代码以查找函数和变量的声明。
  • 为其分配内存,作为Global Execution Context变量/标识符,undefined并在必要时创建引用functions


var x = 10; // x will be undefined before execution

function getName() {
  console.log("Hello World");
} // gets copied entirely


Enter fullscreen mode Exit fullscreen mode

未定义 vs 未定义

  • 由于 JavaScript 会创建一个全局执行上下文,
  • 它为所有已声明的变量和函数分配内存。
  • 默认情况下,它会undefined为该变量分配内存。当执行变量赋值语句时,它会将相应的值赋给该变量。

例如undefined



var a;
console.log(a === undefined); //true


Enter fullscreen mode Exit fullscreen mode

未定义

当 JS 尝试查找初始扫描中未找到的变量时,它会给出错误信息。这意味着没有为该变量分配内存。

例如Not Defined



var a = 10;
console.log(x); //here x is not defined in the scope


Enter fullscreen mode Exit fullscreen mode

ReferenceError: x is not defined

时间死区 -

让我们来看这个例子



console.log(a); // Error
console.log(b); // undefined
let a = 10;
var b = 10;


Enter fullscreen mode Exit fullscreen mode

ReferenceError: cannot access 'a' before initialization

letconst它们不在全局对象上 而是存储在与全局对象不同的内存空间中并且由于指向该对象,因此在其中找不到它们。
SCRIPTconsole.loggloballet a = 10;

时间死区示例



1. let c;
2. const a = 10;
3. if (a === 10) {
4.   c = "Temporal Dead Zone Ended";
5. }


Enter fullscreen mode Exit fullscreen mode

上面的例子表明,在变量cora被赋予任何值之前,它将一直停留在一个名为Temporal Dead Zone💀的特殊区域中。

let v/s const v/s var

  1. 如果出现这种情况let,则const不允许进行任何重新声明。
  2. 连游戏机都用不了😅


console.log("This will not print");
let a = 10;
var a = 10; // Redeclaration of identifier 'a'


Enter fullscreen mode Exit fullscreen mode

导致
SyntaxError: Identifier 'a' has already been declared.



var a = 10;
var a = "Please like this article";


Enter fullscreen mode Exit fullscreen mode

没有错误,允许进行 re 声明。var

如何避免时间盲区?

- 始终将变量声明放在文件顶部,这样文件一启动就能立即获取所有已声明的变量。-
通过这种方式,我们可以将所有变量声明移到文件顶部,从而将死区窗口缩小到接近于零。

JavaScript 代码块

代码块是一组用代码覆盖的语句,{}目的是将其作为一个单独的语句提供。

例子



if (true) console.log("Single Statement");


Enter fullscreen mode Exit fullscreen mode

这就是为什么我们不需要花括号{}的原因,if condition因为它是一个单独的语句。
我们通常用{}花括号来提供一个代码块,以便包含多个语句。

例子



if(condition){
  line1;
  line2;
  ...
} else {...}

function hello(){
 line1;
 line2;
 ...
}


Enter fullscreen mode Exit fullscreen mode

块级作用域与全局作用域

let&const是块级作用域,而var是全局作用域。

如何?

再举个例子!假设我们执行这段代码



{
  var a = 10; //global
  let b = 20; //block
  const c = 30; //block
}


Enter fullscreen mode Exit fullscreen mode

证明

浏览器控制台验证

影子

这是 JavaScript 中的一个概念,其中使用 `using` 声明的变量var会隐藏全局作用域变量。



var a = 10;
{
  var a = 100; // this 'a' shadows the global scoped 'a'
}
console.log(a); // results 100


Enter fullscreen mode Exit fullscreen mode

但是let,它们const的作用方式不同,因为它们并不存在于当前范围之外。



let b = 10;
{
  let b = 100;
}
console.log(b); // results 10

let c = 1;
{
  let c = 10;
}
console.log(c); // results 1


Enter fullscreen mode Exit fullscreen mode

非法跟踪😵‍💫

当我们尝试let使用var. 来限定已声明变量的作用域时,就会出现问题。



let a = 100;
{
  var a = 10; // Error! Illegal Shadowing
  let a = 2; // works just fine!
}


Enter fullscreen mode Exit fullscreen mode

SyntaxError: Identifier 'a' has already been declared

停业😶‍🌫️

函数与其词法作用域捆绑在一起就是闭包。

举个例子就很容易了。



function first() {
  var a = 10;
  function second() {
    console.log(a);
  }

  return second;
}
...
let getFunction = first();

/* after this line, instance of 
first() function is popped out of 
the call stack */
...
getFunction(); // outputs: 10;


Enter fullscreen mode Exit fullscreen mode

理论上这不应该奏效,因为标识符a必须位于作用域之外。但是,当second()函数返回时,它也包含了词法作用域。这正是闭包的本质。

关于 setTimeout 和闭包的棘手面试题

问题陈述 - 以 1 秒的间隔打印 1 到 5 的数字。

你可能会觉得这个问题很简单,然后写出类似这样的代码👇



for (var i = 0; i <= 5; i++) {
  setTimeout(() => {
    console.log(i);
  }, i * 1000);
}


Enter fullscreen mode Exit fullscreen mode

上面的代码会出错(为什么?),let每行都会打印 6。只需将 a替换为 a即可修复此问题。var

如果什么?

面试官要求你只用什么方式完成var

放松,别紧张。我会告诉你该写什么代码,并解释它的工作原理。

这就是你感兴趣的代码😆
以及解释



for (var i = 0; i <= 5; i++) {
  // used var
  function closure(i) {
    setTimeout(() => {
      console.log(i);
    }, i * 1000);
    closure(i);
  }
}


Enter fullscreen mode Exit fullscreen mode

找出问题所在

  • 之前的代码存在一个问题,var那就是 JavaScript 会维护一个执行上下文,它的工作方式setTimeout()是存储回调函数并为其附加一个计时器,然后执行下一行。

  • i由于回调函数中不存在该变量,因此它指向i循环外部的引用for

  • 现在它会创建 5 个带有定时器的函数副本,但定时器到期后,JavaScript 不会等待,for循环就会结束。一切都太迟了。最终,函数的值i会变成6最终状态。

解决问题

修复 1:使用 let 声明

我们上面已经讨论过,这let是块级作用域,答案就在那一行里。

当我们使用它时,let它会为其内存分配创建单独的块。而之前,var所有 5 个变量functions都指向全局执行上下文中可用的同一内存空间。

解决方法 2:使用闭包或函数

i实际上,每次setTimeout()调用时,这都会为他们提供一个新副本。

书写功能类型

函数声明



function hello() {
  console.log("Like This Blog and star the repo");
}


Enter fullscreen mode Exit fullscreen mode

函数表达式



const callAPI = async function () {
  const data = fetch("https://somesite.io/get/data/1232");
  return data;
};


Enter fullscreen mode Exit fullscreen mode

参数与实参



function greet(name) {
  // identifier name is a parameter
  console.log(`Hello ${name}`);
}

greet("Gautam"); // "Gautam" is an Argument


Enter fullscreen mode Exit fullscreen mode

一等函数

  • 函数本身包含函数arguments

  • 函数能够作为值使用,并能够返回和传递给arguments另一个函数function



function first(doesSomething) {
  doesSomething();
}

first(() => {
  console.log("hello World");
});


Enter fullscreen mode Exit fullscreen mode

JavaScript 中的回调函数

这些函数作为参数传递给其他函数,并在需要时分别使用。



setTimeout(function () {
  console.log("Timer");
}, 5000);
function x(y) {
  console.log("x");
}

x(function y() {
  console.log("y");
});


Enter fullscreen mode Exit fullscreen mode

箭头函数

  • 这些函数是在 ES6 或 EcmaScript 6 (2015) 中引入的。
  • 它们只是让我们能够编写更简洁的语法。



function addOne(addNumber) {
  return 1 + addNumber;
}


Enter fullscreen mode Exit fullscreen mode



const addOne = (addNumber) => 1 + addNumber;


Enter fullscreen mode Exit fullscreen mode

上述方法允许我们在不使用关键字的情况下编写函数function


如果你喜欢这篇文章,请点赞这篇博客,并前往GitHub获取代码,也请给代码仓库点个星标。

文章来源:https://dev.to/localhostd3veloper/javascript-essentials-40he