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
未定义 vs 未定义
- 由于 JavaScript 会创建一个全局执行上下文,
- 它为所有已声明的变量和函数分配内存。
- 默认情况下,它会
undefined为该变量分配内存。当执行变量赋值语句时,它会将相应的值赋给该变量。
例如undefined
var a;
console.log(a === undefined); //true
未定义
当 JS 尝试查找初始扫描中未找到的变量时,它会给出错误信息。这意味着没有为该变量分配内存。
例如Not Defined
var a = 10;
console.log(x); //here x is not defined in the scope
ReferenceError: x is not defined
时间死区 -
让我们来看这个例子
console.log(a); // Error
console.log(b); // undefined
let a = 10;
var b = 10;
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. }
上面的例子表明,在变量cora被赋予任何值之前,它将一直停留在一个名为Temporal Dead Zone💀的特殊区域中。
let v/s const v/s var
- 如果出现这种情况
let,则const不允许进行任何重新声明。 - 连游戏机都用不了😅
console.log("This will not print");
let a = 10;
var a = 10; // Redeclaration of identifier 'a'
导致SyntaxError: Identifier 'a' has already been declared.
var a = 10;
var a = "Please like this article";
没有错误,允许进行 re 声明。var
如何避免时间盲区?
- 始终将变量声明放在文件顶部,这样文件一启动就能立即获取所有已声明的变量。-
通过这种方式,我们可以将所有变量声明移到文件顶部,从而将死区窗口缩小到接近于零。
JavaScript 代码块
代码块是一组用代码覆盖的语句,{}目的是将其作为一个单独的语句提供。
例子
if (true) console.log("Single Statement");
这就是为什么我们不需要花括号{}的原因,if condition因为它是一个单独的语句。
我们通常用{}花括号来提供一个代码块,以便包含多个语句。
例子
if(condition){
line1;
line2;
...
} else {...}
function hello(){
line1;
line2;
...
}
块级作用域与全局作用域
let&const是块级作用域,而var是全局作用域。
如何?
再举个例子!假设我们执行这段代码
{
var a = 10; //global
let b = 20; //block
const c = 30; //block
}
证明
影子
这是 JavaScript 中的一个概念,其中使用 `using` 声明的变量var会隐藏全局作用域变量。
var a = 10;
{
var a = 100; // this 'a' shadows the global scoped 'a'
}
console.log(a); // results 100
但是let,它们const的作用方式不同,因为它们并不存在于当前范围之外。
let b = 10;
{
let b = 100;
}
console.log(b); // results 10
let c = 1;
{
let c = 10;
}
console.log(c); // results 1
非法跟踪😵💫
当我们尝试let使用var. 来限定已声明变量的作用域时,就会出现问题。
let a = 100;
{
var a = 10; // Error! Illegal Shadowing
let a = 2; // works just fine!
}
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;
理论上这不应该奏效,因为标识符a必须位于作用域之外。但是,当second()函数返回时,它也包含了词法作用域。这正是闭包的本质。
关于 setTimeout 和闭包的棘手面试题
问题陈述 - 以 1 秒的间隔打印 1 到 5 的数字。
你可能会觉得这个问题很简单,然后写出类似这样的代码👇
for (var i = 0; i <= 5; i++) {
setTimeout(() => {
console.log(i);
}, i * 1000);
}
上面的代码会出错(为什么?),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);
}
}
找出问题所在
-
之前的代码存在一个问题,
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");
}
函数表达式
const callAPI = async function () {
const data = fetch("https://somesite.io/get/data/1232");
return data;
};
参数与实参
function greet(name) {
// identifier name is a parameter
console.log(`Hello ${name}`);
}
greet("Gautam"); // "Gautam" is an Argument
一等函数
-
函数本身包含函数
arguments。 -
函数能够作为值使用,并能够返回和传递给
arguments另一个函数function。
function first(doesSomething) {
doesSomething();
}
first(() => {
console.log("hello World");
});
JavaScript 中的回调函数
这些函数作为参数传递给其他函数,并在需要时分别使用。
setTimeout(function () {
console.log("Timer");
}, 5000);
function x(y) {
console.log("x");
}
x(function y() {
console.log("y");
});
箭头函数
- 这些函数是在 ES6 或 EcmaScript 6 (2015) 中引入的。
- 它们只是让我们能够编写更简洁的语法。
前
function addOne(addNumber) {
return 1 + addNumber;
}
后
const addOne = (addNumber) => 1 + addNumber;
上述方法允许我们在不使用关键字的情况下编写函数function。
如果你喜欢这篇文章,请点赞这篇博客,并前往GitHub获取代码,也请给代码仓库点个星标。
文章来源:https://dev.to/localhostd3veloper/javascript-essentials-40he
