在这个星期,忙完了睿哥的一些任务之后,我有一两天的时间是有空的,这一两天的时间里,我大概看了一下JavaScript的核心语法,特地写一篇文章来总结一下。
我为什么要先开始学JavaScript而不是HTML和css呢?因为其实在React的框架中,这两个都用的不多,而JavaScript用的还算多,所以要学这个。一般情况下,如果你想展示一个静态的,写死的页面,那根本用不到JavaScript,就HTML和CSS就已经可以了,我直接前端把这个页面给写死,数据也写死在前端,那一个静态页面就产生了。不过现在静态页面已经太low了,根本用不上,一般都用的是动态页面。动态页面其实就是基于后端给的数据进行一些数据的呈现和渲染到页面上,只要我后端传回来的数据一直在改变,那我前端的页面也一直在改变。形成动态的效果。而想要达成这种效果,那就需要使用JavaScript了。
1.变量
在进行页面内容呈现的时候,最常用的是数据,而变量是数据存储的容器。
是否需要显式声明变量?
在JavaScript中,不需要显式声明变量的类型。
var myNum = 10; // myNum 是一个数字
myNum = "Hello"; // 现在 myNum 是一个字符串
通过什么关键字声明变量?
在JavaScript中,变量可以通过 var
、let
或 const
关键字声明。
2.数据类型
JavaScript 中有很多种类型,但是一般使用比较多的就7种。
-
Number:表示数字。
let num = 42;
-
String:表示文本数据。
let greeting = "Hello, World!";
-
Boolean:表示逻辑值,只有两个可能的值:
true
和false
。let isTrue = true; let isFalse = false;
-
Undefined:表示变量已声明但未赋值。
let x; console.log(x); // 输出: undefined,容器的默认值,如果输出undefined,那就代表这个容器没有装上任何值
一般可以通过打印的方式去查看变量存储的数值。
这四种数据类型是最简单的,还有另外比较复杂的类型,像:数组,对象,函数。接下来一一讲解。
3.函数
函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。
函数的声明
JavaScript 有2种声明函数的方法。
(1)function 命令
function命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面。
function print(s) {
console.log(s);
}
(2)函数表达式赋值给变量
除了用function命令声明函数,还可以采用函数表达式变量赋值的写法。
var print = function(s) {
console.log(s);
};
这种写法将一个匿名函数赋值给变量。这时,这个匿名函数又称函数表达式(Function Expression),因为赋值语句的等号右侧只能放表达式。
采用函数表达式声明函数时,function命令后面不带有函数名。
圆括号,return 语句
调用函数时,要使用圆括号。圆括号之中,可以加入函数的参数。
function add(x, y) {
return x + y;
}
add(1, 1) // 2
之前我们讲了声明一个函数,我们声明完了,肯定要使用啊,那怎么使用这个函数呢?
函数名后面紧跟一对圆括号,就会调用这个函数,就是使用了这个函数。
函数体内部的return
语句,表示返回。JavaScript 引擎遇到return
语句,就直接返回return
后面的那个表达式的值,后面即使还有语句,也不会得到执行。也就是说,return
语句所带的那个表达式,就是函数的返回值。return
语句不是必需的,如果没有的话,该函数就不返回任何值,或者说返回undefined
。
第一等公民
JavaScript 语言将函数看作一种值,与其它值(数值、字符串、布尔值等等)地位相同。凡是可以使用值的地方,就能使用函数。比如,可以把函数赋值给变量和对象的属性,也可以当作参数传入其他函数,或者作为函数的结果返回。函数只是一个可以执行的值,此外并无特殊之处。
由于函数与其他数据类型地位平等,所以在 JavaScript 语言中又称函数为第一等公民。
function add(x, y) {
return x + y;
}
// 将函数赋值给一个变量
var operator = add;
// 将函数作为参数和返回值
function a(op){
return op;
}
函数名的提升
f();
function f() {}
表面上,上面代码好像在声明之前就调用了函数f
。但是实际上,由于“变量提升”,函数f
被提升到了代码头部,也就是在调用之前已经声明了。
我个人的理解就是,你的函数无论在哪里定义,都会默认你在开头定义。如果你在区块内定义,就默认你是在区块的开头定义。
函数本身的作用域
函数的作用域就是其声明时所在的作用域,与其运行时所在的作用域无关。
var a = 1;
var x = function () {
console.log(a);
};
function f() {
var a = 2;
x();
}
f() // 1
上面代码中,函数x
是在函数f
的外部声明的,所以它的作用域绑定外层,内部变量a
不会到函数f
体内取值,所以输出1
,而不是2
。
总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。
参数
函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数。
function square(x) {
return x * x;
}
square(2) // 4
square(3) // 9
上式的x
就是square
函数的参数。每次运行的时候,需要提供这个值,否则得不到结果。
4.数组
const numbers = [1, 2, 3, 4, 5];
数组中能讲的就是 forEach
方法和 map
方法了,这两个方法经常会用到。
forEach 方法
forEach
是 JavaScript 数组对象的一个方法,用于遍历数组中的每一个元素,并对每个元素执行指定的函数。它是一个简洁且常用的迭代方法,适合在需要对数组中的每个元素进行操作但不需要返回新数组的情况下使用。
语法
array.forEach(function(currentValue, index, array) {
// 执行的代码
}, thisArg);
currentValue
:当前正在处理的元素。index
(可选):当前正在处理的元素的索引。array
(可选):正在遍历的数组对象。thisArg
(可选):执行回调时用作this
的值(可选)。
示例
以下是一些使用 forEach
的示例:
基本用法
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(number) {
console.log(number);
});
输出:
1
2
3
4
5
使用索引
const fruits = ['apple', 'banana', 'cherry'];
fruits.forEach(function(fruit, index) {
console.log(index + ': ' + fruit);
});
输出:
0: apple
1: banana
2: cherry
使用箭头函数
const animals = ['cat', 'dog', 'elephant'];
animals.forEach((animal, index) => {
console.log(`${index}: ${animal}`);
});
输出:
0: cat
1: dog
2: elephant
结论
forEach
方法适用于需要对数组的每个元素执行操作但不需要返回新数组的场景。
map 方法
map
方法是 JavaScript 中数组对象的一个内置方法,用于创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。map
方法不会改变原始数组。
语法
array.map(function(currentValue, index, array) {
// 返回新的元素值
}, thisArg);
- currentValue:当前正在处理的数组元素。
- index(可选):当前正在处理的数组元素的索引。
- array(可选):正在遍历的数组对象。
- thisArg(可选):执行回调函数时用作
this
值。
示例
基本用法
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(function(number) {
return number * 2;
});
console.log(doubled); // 输出 [2, 4, 6, 8, 10]
在这个例子中,map
方法对数组 numbers
的每个元素调用一次提供的函数,并将返回值组成一个新数组 doubled
。
使用箭头函数
你也可以使用箭头函数来简化代码:
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number * 2);
console.log(doubled); // 输出 [2, 4, 6, 8, 10]
处理对象数组
map
方法也可以用于处理对象数组。例如,假设你有一个包含用户对象的数组,你想要创建一个包含用户名的数组:
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 }
];
const usernames = users.map(user => user.name);
console.log(usernames); // 输出 ['Alice', 'Bob', 'Charlie']
使用 thisArg
你可以使用 thisArg
参数来指定回调函数执行时的 this
值:
const numbers = [1, 2, 3, 4, 5];
const multiplier = {
factor: 2
};
const doubled = numbers.map(function(number) {
return number * this.factor;
}, multiplier);
console.log(doubled); // 输出 [2, 4, 6, 8, 10]
在这个例子中,this
在回调函数中被设置为 multiplier
对象,因此 this.factor
的值为 2。
总结
map
方法用于创建一个新数组,其结果是对原数组中的每个元素调用一次提供的函数后的返回值。
5.对象
在 JavaScript 中,对象(Object)是一种数据结构,用于存储键值对(key-value pairs)。对象是 JavaScript 中最重要的数据类型之一,几乎所有的 JavaScript 程序都离不开对象。
本质
对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型。
什么是对象?简单说,对象就是一组“键值对”(key-value)的集合。
var obj = {
foo: 'Hello',
bar: 'World'
};
上面代码中,大括号就定义了一个对象,它被赋值给变量obj
,所以变量obj
就指向一个对象。该对象内部包含两个键值对(又称为两个“成员”),第一个键值对是foo: 'Hello'
,其中foo
是“键名”(成员的名称),字符串Hello
是“键值”(成员的值)。键名与键值之间用冒号分隔。第二个键值对是bar: 'World'
,bar
是键名,World
是键值。两个键值对之间用逗号分隔。
键名
对象的所有键名都是字符串,所以加不加引号都可以。上面的代码也可以写成下面这样。
var obj = {
'foo': 'Hello',
'bar': 'World'
};
对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。
var obj = {
p: function (x) {
return 2 * x;
}
};
obj.p(1) // 2
上面代码中,对象obj
的属性p
,就指向一个函数。
属性可以动态创建,不必在对象声明时就指定。
创建对象
使用对象字面量
对象字面量是创建对象的最常用方式:
const person = {
name: 'Alice',
age: 25,
greet: function() {
console.log('Hello, my name is ' + this.name);
}
};
这里用到了this关键字,this关键字的个人理解看这篇:JavaScript核心语法(2)-优快云博客
对象的方法
对象的方法是作为对象属性的函数。你可以在对象字面量中定义方法,或者动态地添加方法:
const person = {
name: 'Alice',
age: 25,
greet: function() {
console.log('Hello, my name is ' + this.name);
}
};
person.greet(); // 输出 'Hello, my name is Alice'
访问对象属性
你可以使用点符号(dot notation)来访问对象的属性:
console.log(person.name); // 输出 'Alice'
总结
- 对象 是一种用于存储键值对的数据结构。
- 对象可以通过 对象字面量 创建。
- 对象的属性可以通过 点符号 访问。
- 对象的方法是作为对象属性的函数。
后记
其实JavaScript的语法肯定不止这么多,但是其实用的最多的也就这些。我个人感觉这些只要搞懂了,一般情况就足以应对了。
其实JavaScript中有很多是真的用不到的,还难理解。因为你想想,我们大部分人肯定是挑着简单的来用,所以就导致了大部分JavaScript语法都是简单的,不会太复杂,你如果花很多时间去研究那些复杂的语法,是真的浪费时间,而且确实没什么必要。