以你从未见过的方式解释现代 JavaScript🔥
JavaScript 到底是什么?
JavaScript 是一种高级编程语言,通常缩写为 JS。JavaScript 与 HTML 和 CSS 并列为万维网的核心技术之一。它支持事件驱动、函数式和命令式编程风格。
那么,事不宜迟,让我们开始吧。
变量
-
变量是存储值的容器。
-
它包含可在整个程序中使用的信息。
-
可以使用 var、let 和 const 运算符声明变量。
-
不太推荐的方法是“var”。因此,强烈建议使用“let”和“const”来声明变量。
// var
var username = "Tommy"
//let
let firstName = "Tom"
//const
const lastName = "Cruise"
console.log(username)
console.log(firstName)
console.log(lastName)
使用变量:
为了声明变量,我们使用“var”、“let”和“const”。
-
不推荐使用变量声明方式“var”,仅在JavaScript之前的版本(ES6之前的版本)使用
-
变量应使用“let”声明。可以重新分配它。
-
该变量也应使用“const”声明。它不能重新定义,并且只能具有固定值。
变量
// var
var name = "Tom Cruise";
console.log(name);
name = "pramit armpit";
console.log(name);
初始化变量
// Initializing the variables
var greetings;
console.log(greetings);
greetings = "yoo there";
console.log(greetings);
JavaScript变量的规则和约定
// Allowed
/*
* letters
* numbers
* _ (uderscores)
* $ (dollar signs)
*/
// Not allowed
// do not start variable names with a numbers
let 1name = "groot" // not valid
let name = "thanos"; // valid
多词变量
// multi word variables
let firstName = "thanos"; // camel casing
let first_name = "promear"; // underscore convention
let FirstName = "yolomeat"; // pascal case
让
// let
let name = "Brad pitt";
console.log(name);
name = "Christain Bale";
console.log(name);
常量
// const => constant
const name = "promeat";
console.log(name);
// cannot reassign
name = "pramit";
// have to assign the value
const greetings;
// but we can change the data inside the object
const person = {
name: "pramit",
age: 230,
};
person.name = "promeat";
person.age = 100;
console.log(person);
// same goes to the array
const numbers = [1, 2, 3, 4, 5, 6, 7];
numbers.push(8);
console.log(numbers);
console.log()
console.log() 方法用于在 Web 控制台中打印消息。消息可以是简单的 JavaScript 字符串、数字、布尔值、对象或数组。
// log to console
console.log("hello there");
console.log(123456789);
console.log(true);
console.log(false);
let hey = "yolo";
console.log(hey);
console.log([1, 2, 3]);
console.table({
a: 1,
b: 2
});
console.error("This is an error");
console.clear();
console.warn("This is an warning");
// -----------------------------------
// console time (check the scripts how long does the code takes)
console.time("Hello");
console.log("YOOO!!!!");
console.log("YOOO!!!!");
console.log("YOOO!!!!");
console.log("YOOO!!!!");
console.log("YOOO!!!!");
console.log("YOOO!!!!");
console.timeEnd("Hello");
数据类型:
原始数据类型:
- 字符串
- 数字
- 布尔值
- 不明确的
- 无效的
字符串:
它是一种原始数据类型,用于表示和操作由字母、空格、数字和字符组成的字符串。字符串通常用双引号或单引号括起来。
let someString = "This is a string";
const stringTwo = "This is also a string"
let stringThree = "123456789011223344";
let stringSingleQuote = 'This is single quote string'
模板字面量(模板字符串):
模板字面量是支持嵌入表达式的字符串字面量。它们支持多行字符串以及字符串插值。
let name = "Aviyel";
let field = "open source"
let purpose = `${name} is a community driven monetization platform for ${field} Projects`
let projectOnboard = `${name} has already onboarded ${4 + 1} ${field} projects`
console.log(purpose);
console.log(projectOnboard);
`This is a template string`
`This
is
a
multi-line
string
`
数字:
它也是一种原始数据类型。它包含所有整数和浮点数的集合。
let firstNumber = 12345;
let secondNumber = 56789;
let floatNumber = 123.456;
const numberOne = 100;
const numberTwo = 3;
let calculate;
calculate = numberOne + numberTwo;
//console.log(calculate);
calculate = numberOne * numberTwo;
//console.log(calculate);
calculate = numberOne - numberTwo;
//console.log(calculate);
calculate = numberOne / numberTwo;
//console.log(calculate);
calculate = numberOne % numberTwo;
// result
console.log(calculate);
- 数学对象:
//Math Object (its an object because it contains both properties as well as function)
let valueCalc;
valueCalc = Math.PI;
//console.log(valueCalc);
valueCalc = Math.E;
//console.log(valueCalc);
valueCalc = Math.round(2.111);
//console.log(valueCalc);
valueCalc = Math.ceil(1.4);
//console.log(valueCalc);
valueCalc = Math.floor(1.4);
//console.log(valueCalc);
valueCalc = Math.sqrt(49);
//console.log(valueCalc);
valueCalc = Math.abs(-11); // converts into positive Numbers
//console.log(valueCalc);
valueCalc = Math.pow(2, 2);
//console.log(valueCalc);
valueCalc = Math.min(1222, 123, 123342, 2829028, 226262, 626, 11, 1726, 10, 13, 62);
//console.log(valueCalc);
valueCalc = Math.max(1222, 123, 123342, 2829028, 226262, 626, 11, 1726, 10, 13, 62);
//console.log(valueCalc);
valueCalc = Math.random();
//console.log(valueCalc);
valueCalc = Math.random() * 10; // if we want random number from max numebr of 20
//console.log(valueCalc);
valueCalc = Math.floor(Math.random() * 10 + 1);
//result
console.log(valueCalc);
空中主题操作员。
const a = 100,
b = 110,
c = 300;
const str = "100",
st2 = "110",
str3 = "300";
// addition
console.group("Addition");
console.log(a + b);
console.log(b + c);
console.groupEnd();
// adding string
console.log(str + str2);
注意: JavaScript 是一种动态类型语言,这意味着类型可以随时改变。
- 将数字添加到字符串:
const numberOne = 100;
const stringOne = "100",
console.log(numberOne + stringOne);
const a = 1000,
b = 110,
c = 40;
// Subtraction
console.group("Substration");
console.log(a - b);
console.log(b - c);
console.groupEnd();
3. 乘法运算符
const a = 1000,
b = 110,
c = 40;
// Multiplication
console.group("Multiplication");
console.log(b * c);
console.log(a * b);
console.groupEnd();
const a = 1000,
b = 100,
c = 3;
// Division
console.group("Modulus");
console.log(b % c);
console.log(a % b);
console.groupEnd();
let a = 1000,
b = 100,
c = 3;
console.group("Increment");
console.log(a + 1);
console.log(a++);
console.log((c = c + a));
console.log((c += a));
console.groupEnd();
let a = 1000,
b = 100,
c = 3;
console.group("Decrement");
console.log(a - 1);
console.log(a--);
console.log((c = c - a));
console.log((c -= a));
console.groupEnd();
布尔值:
let isOpenSource;
isOpenSource = true;
isOpenSource = false;
//result
console.log(isOpenSource);
无效的:
let existence = null;
//result
console.log(existence);
不明确的:
它只是表示没有定义值。如果声明了一个变量,但未赋值/初始化为特定值,则该变量的值将为未定义值。它只是表示没有定义值。如果声明了一个变量,但未赋值/初始化为特定值,则该变量的值将为未定义值。
let name;
console.log(name) // undefined
非原始数据类型:
- 功能
- 对象
- 数组
功能:
函数是 JavaScript 的基本构造块之一。在 JavaScript 中,函数类似于过程(一组执行任务或计算值的语句)。但要使过程符合函数的定义,它必须接受一些输入并返回一个输出,并且输入和输出之间存在明显的关系。
function add(a, b) {
return a + b;
}
console.log(add(1, 2));
// es6 arrow function
const add = (a, b) => a + b;
console.log(add(1, 2))
定义函数:
1. 函数声明(函数定义或函数语句):
- 函数的名称。
- 该函数的参数列表。例如,
function sub(a,b){
return a - b
};
函数“sub”接受两个参数 a 和 b。该函数包含一个返回语句,返回 a - b 的减法结果。
返回。
- 函数使用 return 返回值。
- 它结束函数执行并将指定的值返回到调用它的位置。
- 如果没有声明返回语句,函数将默认抛出“undefined”。
2. 函数表达式:
在表达式中,可以使用 function 关键字来定义函数。这些函数可以匿名执行,无需指定名称。
匿名函数:
- 它没有名称属性。
- 它只能通过使用 function 关键字来定义。例如,
const add = function(a,b){
return a + b;
};
let x = add(2,3)
console.log(x); // 5
立即调用函数表达式 - IFFE
(function(x = 2) {
console.log(`${x * x}`);
console.log(`Immidiately Invocable Functions Expressions - IFFEs`);
})();
(function(y, name) {
console.log(`${y * y}`);
console.log(`${name} yooooooo`);
})(9, "nine");
注意: IFFE 可以同时声明和运行。
调用函数:
定义函数并不执行该函数。调用函数实际上是使用指定的参数执行指定的操作。
add(100,200)
sub(200,100)
注意:函数调用时必须在作用域内,但函数声明可以提升
console.log(add(20,90));
function add(a,b){
return a + b;
}
参数 VS 参数
参数:
- 参数是传递给函数的命名变量。参数变量用于将参数传入函数。
参数:
- 参数是作为输入传递给函数的值(原始值或对象)。
对象:
JavaScript 对象是存储命名值(称为属性或方法)的容器。对象是内置的非原始数据类型,用于存储键值对。
该对象内部的数据不按顺序排列,并且值可以是任何类型。
对象的属性和值:
- 花括号包围对象文字。
- 冒号符号用于将值映射到键。
- 所有键都必须是唯一的,但值可以是任何他们想要的值。
- 对象属性是键值对的另一个名称。
- 逗号用于分隔键值对。
const projectDetails = {
name: "Typesense",
isOpenSource: true,
githubStars: 8200
}
对象可以改变:
- 即使使用 const 声明对象,其内部的内容也可以改变。
- 可以添加、删除和更改新属性。
const projectDetails = {
name: "Typesense",
isOpenSource: true,
githubStars: 8200
}
delete projectDetails.isOpenSource;
projectDetails.githubStars = 9000;
console.log(projectDetails)
// { name: 'Typesense', githubStars: 9000 }
用于访问对象属性的点 (.)
- 可以通过“Object.propertyName”访问对象的属性
const car = {
name: "Lambo",
color: "orange",
licensePlate: 420
}
console.log(car.name) // Lambo
console.log(car.color) // orange
- 如果我们尝试访问未声明(不存在)的属性,JavaScript 将抛出“未定义”。例如,
const car = {
name: "Lambo",
color:"orange",
licensePlate: 420
}
console.log(car.age) // Undefined
对象中的 For-in 循环
- 它迭代对象的键
const car = {
name: "Lambo",
color: "orange",
licensePlate: 420
}
for (let key in car) {
console.log(`${key} : ${cars[key]}`)
}
/*
*name : Lambo
*color : orange
*licensePlate : 420
*/
将对象作为参数传递:
- 当对象作为参数传递给函数时,它是通过引用传递的。
const age = 100;
const details = {
name: "pramit"
};
const chngObjArgs = (ag, obj) => {
age = 7;
obj.name = "Thanos";
};
chngObjArgs(age, details);
console.log(age); // 100
console.log(details.name); // Thanos
对象方法:
- 如果对象的属性值是一个函数,则它们被称为对象方法。
const details = {
name: () => {
console.log("Hello there , Yo!! how are you doing ")
};
}
details.name();
// Hello there , Yo!! how are you doing
对象解构:
const details = {
name: 'Pramit',
profession: 'web developer',
isOnline: true,
isOffline: false,
username: 'promeat',
};
const {
name,
profession,
isOnline,
isOffline,
username
} = details;
console.log(name); // Pramit
console.log(profession); // web developer
console.log(isOnline); // true
console.log(isOffline); // false
console.log(username); // promeat
对象创建的快捷技巧:
const name = "Thanos";
const details = {name};
console.log(details) // { name: 'Thanos' }
JavaScript 对象中的“this”关键字
在 JavaScript 中,“this” 是一个保留关键字。它指向方法的调用对象,并可用于访问该对象的方法。
const details = {
name: "Pramit",
isOnline: true
thisName() {
return this.name;
}
}
console.log(detail.thisName()) // Pramit
// Another Example
const ageCalc = {
oldAge: 100,
newAge: 23,
calculateAge() {
return this.oldAge - this.newAge;
}
}
console.log(ageCalc.calculateAge()); // 77
工厂功能:
- 工厂函数是一个返回对象的函数。
// Factory Function creating car
let Car = function(name, color) {
// creating car object
let car = {};
// parameters as keys to this object
car.name = name;
car.color = color;
// function to start engine
car.vroom = function() {
return 'Vrom vrom!! ' + car.name + ' is ' + car.color + ' color ';
};
return car;
};
let carOne = Car('Lambo', 'orange');
console.log(carOne.vroom()); // Vrom vrom!! Lambo is orange color
let carTwo = Car('Ferarri', 'Red');
console.log(carTwo.vroom()); // Vrom vrom!! Ferarri is Red color
数组:
-
使用 JavaScript 数组可以将多个值存储在单个变量中。
-
许多值可以存储在具有单一名称的数组中,并且可以通过引用索引号来访问这些值。
const stringArray = ["my", "name", "is", "pramit"]
// result
console.log(stringArray)
const numArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]
// result
console.log(numArray)
混合阵列
const mixedArray = [1,"my",2,"name",8,"is",7,"pramit",true,false]
//result
console.log(mixedArray)
指数:
- 数组是类似列表的对象,其原型具有执行遍历和变异操作的方法。
- 数组元素按索引值排列。
- 索引值始终从 0 开始。
创建数组
let comics = ['DC', 'Marvel']
console.log(comics)
**Checking the length of an array.**
console.log(comics.length)
使用索引位置访问数组项
let first = comics[0]
let second = comics[1]
访问数组的最后一项
let last = comics[comics.length - 1]
循环数组
comics.forEach(function(item, index, array) {
console.log(item, index)
})
// DC 0
// Marvel 1
将项目添加到数组末尾。
let newLength = comics.push('Capcom')
// ["DC", "Marvel", "Capcom"]
从数组末尾删除一个元素
let last = comics.pop() // remove Capcom
// ["DC", "Marvel"]
从数组开头删除一个元素
let first = comics.shift() // remove DC from the front
// ["Marvel"]
将一个项目添加到数组的开头
let newLength = comics.unshift('Nintendo') // add to the front
// ["Nintendo", "Marvel"]
查找数组中某个项目的索引
let pos = comics.indexOf('Marvel')
// 1
按索引位置删除项目
let removedItem = comics.splice(1, 1)
// ["Nintendo"]
从索引位置删除项目
let comics = ['Nintendo', 'DC', 'Marvel', 'Capcom']
console.log(comics)
// ['Nintendo', 'DC', 'Marvel', 'Capcom']
let removedItems = comics.splice(1, 2)
console.log(comics)
// [ 'Nintendo', 'Capcom' ]
console.log(removedItems)
// [ 'DC', 'Marvel' ]
复制数组
let shallowCopy = comics.slice() // this is how to make a copy
// or
let copyArray = [...comics]
条件语句
条件语句控制行为并确定代码片段是否可以运行。条件语句用于根据特定条件控制执行流程。如果条件为真,则可以执行某个操作;如果条件为假,则可以执行其他操作。
If 语句
- 如果表达式为真,则仅执行代码
const isOnline = true;
if (isOnline) {
console.log("Thanos is Online")
}
else 语句
- 如果“if”条件不满足,则执行 else 块。
const isOnline = false;
if(isOnline){
console.log("Thanos is Online")
} else{
console.log("Thanos is Not Online")
}
If-else 语句
等于
const age = 100;
// equal to
if (age == "100") {
console.log("true");
} else {
console.log("wrong");
}
不等于
const age = 100;
if (age != 100) {
console.log("true");
} else {
console.log("wrong");
}
等于值和类型
const age = 100;
if (age === 100) {
console.log("true");
} else {
console.log("wrong");
}
不等于值和类型
const age = 100;
if (age === 100) {
console.log("true");
} else {
console.log("wrong");
}
大于或小于
if (age >= 100) {
console.log("true");
} else {
console.log("wrong");
}
if (age < 100) {
console.log("true");
} else {
console.log("wrong");
}
If Else 语句
const color = "purple";
if (color === "red") {
console.log("Color is red");
} else if (color === "green") {
console.log("Color is green");
} else {
console.log("Color is Neither red nor green");
}
逻辑运算符
// Ampersand operator
const name = "pramit";
const hisAge = 23;
if (hisAge > 0 && hisAge < 20) {
console.log(`${name} is a Teenager`);
} else if (hisAge > 20 && hisAge < 30) {
console.log(`${name} is in his Twenties`);
} else {
console.log("He is OLD");
}
OR 运算符
if (hisAge > 16 || hisAge < 25) {
console.log(`${name} he can join the army`);
} else {
console.log(`${name} cannot run in race`);
}
三元运算符
console.log(hisAge === 23 ? "Correct" : "Incorrect");
如果没有括号
if (hisAge > 16 || hisAge < 25) console.log(`${name} he can join the army`);
else console.log(`${name} cannot run in race`);
switch-case语句
switch 语句用于根据不同的条件执行不同的操作。
- Switch 被评估一次。
- 表达式的值与每个案例进行比较。
- 如果匹配,则执行代码块。
- 如果没有任何匹配,则执行默认代码块。
const foobar = "bar";
switch (foobar) {
case "foo": {
let x = 60;
console.log(x + 9);
break;
}
case "bar": {
let y = 400;
console.log(y + 20);
break;
}
default: {
console.log("REEEE!!!!!!!!!");
}
}
比较运算符
- 比较两个值并返回 true 或 false
const name = "pramit";
const name2 = "PRAMIT";
console.group("strings");
console.log(name == "pramit"); // true
console.log(name == name2); //false
console.log(name == name2.toLowerCase());
console.groupEnd();
数字比较
const firstNumber = 69;
const secondNumber = "69";
console.group("numbers");
console.log(firstNumber == secondNumber); // true
console.log(firstNumber === secondNumber); // false
console.log(firstNumber != secondNumber); //false
console.log(firstNumber !== secondNumber); //true
console.groupEnd();
布尔值比较
let yolo;
let nothing = null;
console.group("booleans");
console.log(Boolean("")); //false
console.log(Boolean("this")); //true
console.log(Boolean(yolo)); //false
console.log(Boolean(nothing)); //false
console.log(Boolean({})); //true
console.log(Boolean([])); //true
console.groupEnd();
对象和数组的比较
const array1 = [1, 2, 3, 4, 5, 6];
const array2 = [1, 2, 3, 4, 5, 6];
const obj1 = {
name: "pramit"
};
const obj2 = {
name: "pramit"
};
console.group("objects and arrays");
console.log(array1 == array2); // false
console.log(obj1 == obj2); // false
console.log(array1 === array2); // false
console.log(obj1 === obj2); // false
console.groupEnd();
AND 或 OR 运算符
console.group("And");
console.log(Boolean("true_") && Boolean("true_")); // true
console.log(Boolean("true_") && Boolean("")); // false
console.log(Boolean("") && Boolean("true")); // false
console.log(Boolean("") && Boolean("")); // false
console.groupEnd();
console.group("OR");
console.log(Boolean("true_") || Boolean("true_")); // true
console.log(Boolean("true_") || Boolean("")); // true
console.log(Boolean("") || Boolean("true")); // true
console.log(Boolean("") || Boolean("")); // false
console.groupEnd();
三元运算符
它是一个需要三个操作数的运算符:一个条件,后跟一个问号(?),然后是一个如果条件为真则执行的表达式,后跟一个冒号(:),最后是一个如果条件为假则执行的表达式。
条件?表达式如果为真:表达式如果为假
const age = 230
console.log(age === 230 ? "Correct" : "Incorrect");
逻辑或 (||) 运算符
false || false // false
false || true // true
true || false // true
true || true // true
逻辑与 (&&) 运算符
false && false // false
false && true // false
true && false // false
true && true // true
循环
For 循环
// For Loops
for (let i = 0; i <= 10; i++) {
console.log(i);
}
改变迭代
for (let i = 0; i <= 10; i++) {
if (i === 2) {
console.log("Two");
}
console.log(i);
}
继续循环(Continue 语句)
for (let i = 0; i <= 10; i++) {
if (i === 2) {
console.log("Two");
continue;
}
console.log(i);
}
// Another example
let arr1 = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 13, 21, 11, 333, 556, 66,
];
let str = "";
for (let i = 0; i < arr1.length; i++) {
if (i % 2 === 1) continue;
str += (str == "" ? "" : ";") + arr1[i];
// str = str.split(";").sort((a, b) => a - b);
}
console.log(str);
for (let i = 0; i <= 10; i++) {
if (i === 2) {
console.log("Two");
break;
}
console.log(i);
}
// Another example
let arr1 = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 13, 21, 11, 333, 556, 66,
];
let str = "";
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] > 10) break;
str += (str === "" ? "" : "; ") + arr1[i];
}
console.log(str);
循环遍历数组
const names = ["pramit", "ram", "shyam", "hari", "krishna", "gopal"];
for (let a = 0; a < names.length; a++) {
console.log(names[a]);
}
const namesTwo = ["pramit", "ram", "shyam", "hari", "krishna", "gopal"];
namesTwo.forEach((nam, index, array) => {
console.log(`${index} : ${nam}`);
console.log(array);
});
const users = [
{
id: 1,
name: "pramit"
},
{
id: 2,
name: "marattha"
},
{
id: 3,
name: "ram"
},
{
id: 4,
name: "hari"
},
{
id: 5,
name: "gopal"
},
{
id: 6,
name: "krishna"
},
{
id: 7,
name: "shanker"
},
{
id: 8,
name: "shyam"
},
];
const ids = users.map((user) => {
return user.id;
});
console.log(ids);
对象中使用的 for in 循环
const userBase = {
firstName: "pramit",
lastName: "marattha",
age: 230,
};
for (let x in userBase) {
console.log(`${x} :==> ${userBase[x]}`);
}
While 循环和 do-while
let i = 0;
let j = 0;
while (i < 10) {
console.log("Numbers " + i);
i++;
}
执行 While 循环
do {
console.log("Numbers " + j);
j++;
} while (j < 10);
无限循环
for (;;) {
console.log("Stuck in an endless loop");
}
while (true) {
console.log("Stuck in an endless loop");
}
do {
console.log("Stuck in an endless loop");
} while (true);
For in 循环
let arr1 = [1, 2, 3, 4, 5, 6, 7, 899, 99, 98, 7, 653, 32, 4];
let sum = 0;
for (let i in arr1) {
// console.log(arr1.hasOwnProperty(i));
if (arr1.hasOwnProperty(i)) {
sum += arr1[i];
}
}
console.log(sum);
For of 循环
let arr1 = [1, 2, 3, 4, 5, 6, 7, 899, 99, 98, 7, 653, 32, 4];
let sum = 0;
// for (let i of arr1) {
// sum += i;
// }
for (let i of arr1) {
sum += i;
}
console.log(sum);
标记语句
let firstMatch = -1;
let arr1 = [1, 2, 3, 4, 5, 6];
let arr2 = arr1.filter((i) => i % 2 === 0);
// console.log(arr2);
firstLoop: for (let i in arr1) {
for (let x in arr2) {
if (arr1[i] === arr2[x]) {
firstMatch = arr1[i];
break firstLoop;
}
}
}
console.log("🚀 ~ file: labeledStatement.js ~ line 2 ~ firstMatch", firstMatch);
function containNumber(numbers, number) {
for (let i in numbers) {
if (numbers.hasOwnProperty(i)) {
if (numbers[i] == number) {
return true;
}
}
}
return false;
}
let arr1 = [1, 23, 4, 5, 67, 60];
let conatinsTwo = containNumber(arr1, 23);
console.log(
"🚀 ~ file: returnStatement.js ~ line 15 ~ conatinsTwo",
conatinsTwo
);
无价值返回
function someDataWithValue(value) {
someData();
if (!value) {
return;
}
someOtherData();
}
function someData() {
console.log("Some Data");
}
function someOtherData() {
console.log("Some Other Data");
}
someDataWithValue(false);
错误处理
捕获所有异常
function catchWhenNullEmpty(array) {
if (array.length == null) {
throw "array is null";
}
if (array.length === 0) {
throw new RangeError();
}
return array;
}
try {
catchWhenNullEmpty(["null"]);
console.log(catchWhenNullEmpty(["null"]));
} catch (error) {
console.log(error);
}
捕获特定异常
function throwNewNullOrEmpty(array) {
if (array == null) {
throw "Array is null";
}
if (array.length === 0) {
throw new RangeError();
}
}
try {
throwNewNullOrEmpty([]);
} catch (e) {
if (e.name === "RangeError") {
console.log("Array is Empty");
} else {
console.log("Array is not specified");
}
}
定义异常类型
function simepleExeption() {}
function exception(name, message) {
this.name = name;
this.message = message;
}
throw new exception("exception", "this is a message");
范围
全局范围
// Global Scope
var a = 1;
let b = 22;
const c = 333;
功能范围
function check() {
var a = 4444;
let b = 55555;
const c = 666666;
console.log(`Function Scope: ${a} ${b} ${c}`);
}
check();
如果块范围
if (true) {
var a = 4444;
let b = 55555;
const c = 666666;
console.log(`If block Scope: ${a} ${b} ${c}`);
}
循环块作用域
for (var a = 0; a < 10; a++) {
console.log(`Loop block Scope : ${a}`);
}
课程
-
类是创建对象的模板。
-
类语法有两个组成部分
- 类声明。
- 类表达式。
构造函数:
构造函数方法是类的一个特殊方法,用于创建和初始化该类的对象。构造函数可以使用 super 关键字来调用超类的构造函数。
类声明
class sum {
constructor(numberA, numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
}
类表达式
命名表达式
let Sum = class sumTwo {
constructor(numberA, numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
};
console.log(Sum.name);
// output: "sumTwo"
未命名的表达式
let Sum = class {
constructor(numberA, numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
};
console.log(Sum.name);
// output: "Sum";
原型方法
class Sum {
constructor(numberA, numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
// Getter
get totalSum() {
return this.calculateSum();
}
// Method
calculateSum() {
return this.numberA + this.numberB;
}
}
const tSum = new Sum(10, 10);
console.log(tSum.totalSum); // 20
绑定“this”
当调用静态方法或原型方法时,如果没有为 this 设置值,例如将方法分配给变量然后调用它,则方法内部的“this”值将未定义。
class Animal {
speak() {
return this;
}
static eat() {
return this;
}
}
let obj = new Animal();
obj.speak(); // the Animal object
let speak = obj.speak;
speak(); // undefined
Animal.eat() // class Animal
let eat = Animal.eat;
eat(); // undefined
字段声明:
公共字段声明。
class Sum {
numberA = 0;
numberB;
constructor(numberA, numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
}
私有字段声明。
class Sum {
#numberA = 0;
#numberB;
constructor(numberA, numberB) {
this.#numberA = numberA;
this.#numberB = numberB;
}
}
使用 extends 进行子类化
- extends 用于创建另一个类的类。
class Instrument {
constructor(name) {
this.name = name;
}
play() {
console.log(`${this.name} creates a melodic harmony.`);
}
}
class Guitar extends Instrument {
constructor(name) {
super(name);
}
play() {
console.log(`${this.name} creates a melody.`);
}
}
let strum = new Guitar("Ibanez");
strum.play(); // Ibanez creates a melody.
使用 super 关键字调用超类:
super 关键字用于访问和调用对象父级上的函数。
class Instrument {
constructor(name) {
this.name = name;
}
play() {
console.log(`${this.name} creates a melodic harmony.`);
}
}
class Guitar extends Instrument {
play() {
super.play()
console.log(`${this.name} creates a melody.`);
}
}
let strum = new Guitar("Ibanez");
strum.play();
// Ibanez creates a melodic harmony.
// Ibanez creates a melody.
迭代器:
- 迭代器是一个定义序列并在终止时可能返回值的对象。
- 迭代器允许你迭代一个对象
具体来说,迭代器是通过具有 next() 方法实现 Iterator 协议的任何对象,该方法返回具有两个属性的对象:
完成的价值
一旦创建,迭代器对象就可以通过重复调用 next() 来显式地迭代。
function calcRangeIterator(start = 0, end = Infinity, step = 1) {
let nextIndex = start;
let iterationCount = 0;
const rangeIterator = {
next: function() {
let result;
if (nextIndex < end) {
result = {
value: nextIndex,
done: false
}
nextIndex += step;
iterationCount++;
return result;
}
return {
value: iterationCount,
done: true
}
}
};
return rangeIterator;
}
使用迭代器:
const it = calcRangeIterator(1, 10, 2);
let result = it.next();
while (!result.done) {
console.log(result.value);
result = it.next();
}
console.log("Iterated over sequence of size: ", result.value);
生成器:
-
生成器是一个有用的工具,它允许我们通过定义函数来创建迭代器。
-
要创建生成器,您需要在函数名称前面添加 (*)。
function *thisIsGenerator(){
}
- 要在匿名函数中创建生成器,需要在函数本身的末尾添加 (*)
function* (){
}
- 生成器中的“yield”关键字的行为与承诺中的 await 相同。
function* uniqueIdGenerator() {
let i = 0;
while (true) {
yield i++;
}
}
const uniqueId = uniqueIdGenerator();
console.log(uniqueId.next().value); // 0
console.log(uniqueId.next().value); // 1
console.log(uniqueId.next().value); // 2
console.log(uniqueId.next().value); // 3
console.log(uniqueId.next().value); // 4
console.log(uniqueId.next().value); // 5
console.log(uniqueId.next().value); // 6
console.log(uniqueId.next().value); // 7
console.log(uniqueId.next().value); // 8
console.log(uniqueId.next().value); // 9
回调
回调函数是指在经过一定时间后产生结果的函数。这类异步回调通常用于访问数据库值、下载照片、读取文件等等。我们不能继续执行下一行,因为这可能会引发“不可用”的错误;我们也不能暂停程序,因为这些操作需要时间才能完成。因此,我们必须保存结果并在完成后返回。
- 回调函数
function one(call_two) {
console.log("step one");
call_two();
}
function two() {
console.log("step two");
}
one(two);
关于回调的示例
订购食材 ===> 取料 ====> 开始制作 ====> 上菜
let stocks = {
Fruits: ["grapes", "apple", "orange", "banana"],
Liquid: ["water", "ice"],
Holder: ["cone", "cup"],
Toppings: ["sprinkles", "chocolate"],
};
console.log(stocks.Fruits[3]);
回调地狱
回调地狱是由复杂的嵌套回调引起的一个严重问题。每个回调都接受一个参数,该参数是它之前回调的结果。这种代码结构类似于金字塔,使其难以理解和维护。此外,如果一个函数失败,所有其他函数都会受到影响。
let order = (Fruit_name, call_production) => {
// console.log("order placed");
setTimeout(() => {
console.log(`${stocks.Fruits[Fruit_name]} was selected`);
call_production();
}, 2000);
};
let production = () => {
// console.log("starting production");
setTimeout(() => {
console.log("production has started");
setTimeout(() => {
console.log("Fruit chopped");
setTimeout(() => {
console.log(`${stocks.Liquid[0]} and ${stocks.Liquid[1]} was added`);
setTimeout(() => {
console.log("machine started");
setTimeout(() => {
console.log(`${stocks.Holder[1]} was selected`);
setTimeout(() => {
console.log(`${stocks.Toppings[1]} was added`);
setTimeout(() => {
console.log(`Icecream was served`);
}, 2000);
}, 2000);
}, 2000);
}, 1000);
}, 1000);
}, 2000);
}, 0);
};
order(0, production);
承诺
-
承诺用于处理异步操作。
-
Promises 用于确定异步操作是否成功执行。
Promise 有三种状态:
- 待办的。
- 已实现。
- 被拒。
创建承诺
const isOnline = true;
let prom = new Promise((resolve, reject) => {
if (isOnline) {
resolve("User is online");
} else {
reject("User is not online");
}
});
console.log(prom)
另一个例子,
let stocks = {
Fruits: ["grapes", "apple", "orange", "banana"],
Liquid: ["water", "ice"],
Holder: ["cone", "cup"],
Toppings: ["sprinkles", "chocolate"],
};
let is_shop_open = true;
let order = (time, work) => {
return new Promise((resolve, reject) => {
if (is_shop_open) {
setTimeout(() => {
resolve(work());
}, time);
} else {
reject(console.log("Shop is Closed"));
}
});
};
order(2000, () => console.log(`${stocks.Fruits[0]}`));
Promise 链
someApiCall().then((result) => {
return someAnotherApiCall();
}).then((result2) => {
return someAnotherNextApiCall();
}).then((result3) => {
// do something
}).catch((error) => {
console.error(error)
});
异步等待:
-
async/await 是 Promise 之上的语法糖,提供了一种以同步方式处理异步任务的方法
-
Await 暂停异步函数,直到承诺返回结果(解决或拒绝)值。
-
如果 Promise 成功解析,await 运算符将返回解析后的值:const resolveVal = await promise。否则,你可以在 try/catch 中捕获被拒绝的 Promise。
-
异步函数总是返回一个承诺,这使得嵌套异步函数的能力成为可能。
async function fetchMovies() {
const response = await fetch('http://www.omdbapi.com/?t=a&y=2000&plot=full');
if (!response.ok) {
throw new Error('Failed to fetch movies');
}
const movies = await response.json();
return movies;
}
另一个例子,
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise is resolved");
}, 1000);
});
const asynchronousFunction = async () => {
let result = await promise;
console.log(result);
};
asynchronousFunction();
完整文章(第 1 部分)可在此处查看 => https://aviyel.com/post/1187
完整文章(第 2 部分)可在此处查看 => https://aviyel.com/post/1264
编码愉快!!
如果您是项目维护者、贡献者或只是开源爱好者,请关注@aviyelHQ或在 Aviyel 上注册以获得早期访问权限。
加入 Aviyel 的 Discord => Aviyel 的世界
推特 =>[ https://twitter.com/AviyelHq ]
文章来源:https://dev.to/aviyel/modern-javascript-explained-in-a-way-youve-never-seen-before-2020