Javascript基础语法

感谢现代Javascript教程提供的学习资源,详细教程请移步现代Javascript教程官网进行学习。

简介

什么是JavaScript

JavaScript 最初被创建的目的是“使网页更生动”。
这种编程语言写出来的程序被称为脚本。它们可以被直接写在网页的 HTML 中,在页面加载的时
候自动执行。
脚本被以纯文本的形式提供和执行。它们不需要特殊的准备或编译即可运行。
JavaScript与Java不是一回事

基础知识

编写JavaScript代码

script标签

JavaScript程序可以在 <script>标签的帮助下插入到HTML文档的任何地方。
比如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>position</title>
      <script>
          alert("这是一个script标签")
      </script>
</head>
<body>
    <script>
        alert("这是一个script标签")
    </script>
</body>
    <script>
        alert("这是一个script标签")
    </script>
</html>

<script>标签中包裹了 JavaScript 代码,当浏览器遇到<script>标签,代码会自动运行。

外部脚本

如果你有大量的 JavaScript 代码,我们可以将它放入一个单独的文件。脚本文件可以通过src属性(attribute)添加到 HTML 文件中。

<script src="/path/script.js"></script>

src的路径既可以是绝对路径,也可以是相对路径,甚至可以是url地址。
要附加多个脚本,请使用多个标签:

<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>

注意

  1. 一般来说,只有最简单的脚本才嵌入到 HTML 中。更复杂的脚本存放在单独的文件中。
    使用独立文件的好处是浏览器会下载它,然后将它保存到浏览器的缓存中。之后,其他页面想要相同的脚本就会从缓存中获取,而不是下载它。所以文件实际上只会下载
    一次。这可以节省流量,并使得页面(加载)更快。
  2. 如果设置了 src 特性, script 标签内容将会被忽略。
<script src="file.js">
  alert(1); // 此内容会被忽略,因为设定了src
</script>

代码结构

分号

JavaScript代码语句之间可以使用分号进行分割。然而,大多数情况下,换行意味着一个分号。
存在 JavaScript 无法确定是否真的需要自动插入分号的情况。

<script>
  alert("这样写会报错")
  [1, 2].forEach(alert)
</script>

因为 JavaScript 并不会在方括号 […] 前添加一个隐式的分号。

注释

单行注释以两个正斜杠字符 // 开始。
多行注释以一个正斜杠和星号开始 “/*” 并以一个星号和正斜杠结束 “*/” 。

现代模式,“use strict”

“use strict” 或者 ‘use strict’ 。当它处于脚本文件的顶部时,则整个脚本文件都将以“现代”模式进行工作。
没有办法取消 use strict

数据类型

在 JavaScript 中有 8 种基本的数据类型(译注:7 种原始类型和 1 种引用类型)。

Number类型

    <script>
    let n = 123;
    </script>

number 类型代表整数和浮点数。除了常规的数字,还包括所谓的“特殊数值(“special numeric values”)”也属于这种类型:Infinity 、 -Infinity 和 NaN 。

  • Infinity 代表数学概念中的 无穷大 ∞。是一个比任何数字都大的特殊值,可以通过除以 0 来得到。
  • NaN 代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果。
    NaN 是粘性的。任何对 NaN 的进一步操作都会返回 NaN

在 JavaScript 中做数学运算是安全的。

BigInt 类型

在 JavaScript 中,“number” 类型无法表示大于 (253-1) (即 9007199254740991 ),或小于
-(253-1) 的整数。
BigInt 类型是最近被添加到 JavaScript 语言中的,用于表示任意长度的整数。

String类型

JavaScript 中,有三种包含字符串的方式。

  1. 双引号: “Hello” .
  2. 单引号: ‘Hello’ .
  3. 反引号: `Hello` .
    双引号和单引号都是“简单”引用,在 JavaScript 中两者几乎没有什么差别。
    反引号是 功能扩展 引号。它们允许我们通过将变量和表达式包装在 ${…} 中,来将它们嵌入到字
    符串中。
    let name = "John";
    // 嵌入一个变量
    alert( `Hello, ${name}!` ); // Hello, John!
    // 嵌入一个表达式
    alert( `the result is ${1 + 2}` ); // the result is 3

${…} 内的表达式会被计算,计算结果会成为字符串的一部分。可以在 ${…} 内放置任何东西:
诸如名为 name 的变量,或者诸如 1 + 2 的算数表达式,或者其他一些更复杂的。
这仅仅在反引号内有效,其他引号不允许这种嵌入。

Boolean类型

boolean 类型仅包含两个值:true 和 false。

null

它构成了一个独立的类型,只包含 null 值,JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值.

    let time = null;

undefined

undefined 的含义是 未被赋值 。如果一个变量已被声明,但未被赋值,那么它的值就是 undefined 。

object 类型

symbol 类型

补充

  1. typeof null 的结果是 “object” 。这是官方承认的 typeof 的行为上的错误。
  2. typeof alert 的结果是 “function”,因为 alert 在 JavaScript 语言中是一个函数。

总结

JavaScript 中有八种基本的数据类型(前七种为基本数据类型,也称为原始类型,而
object 为复杂数据类型)。

  • number 用于任何类型的数字:整数或浮点数,在 ±(253-1) 范围内的整数。
  • bigint 用于任意长度的整数。
  • string 用于字符串:一个字符串可以包含 0 个或多个字符,所以没有单独的单字符类型。
  • boolean 用于 true 和 false 。
  • null 用于未知的值 —— 只有一个 null 值的独立类型。
  • undefined 用于未定义的值 —— 只有一个 undefined 值的独立类型。
  • symbol 用于唯一的标识符。
  • object 用于更复杂的数据结构。

可以通过 typeof 运算符查看存储在变量中的数据类型。
两种形式: typeof x 或者 typeof(x) 。

交互:alert、prompt、confirm

  1. alert
    显示信息。alert的返回值是undefined
  2. prompt
    显示信息要求用户输入文本。点击确定返回文本,点击取消或按下 Esc 键返回 null 。
  3. confirm
    显示信息等待用户点击确定或取消。点击确定返回 true ,点击取消或按下 Esc 键返回
    false 。

类型转换

有三种常用的类型转换:转换为 string 类型、转换为 number 类型和转换为 boolean 类型。
字符串转换 —— 转换发生在输出内容的时候,也可以通过 String(value) 进行显式转换。原
始类型值的 string 类型转换通常是很明显的。
数字型转换 —— 转换发生在进行算术操作时,也可以通过 Number(value) 进行显式转换。

数字型转换规则

转换值
undefinedNaN
null0
true/false1/0
string“按原样读取”字符串,两端的空白会被忽略。空字符串变成 0 。转换出错则输出 NaN 。

布尔型转换 —— 转换发生在进行逻辑操作时,也可以通过 Boolean(value) 进行显式转换。

布尔型转换规则

转换值
0 , null , undefined , NaN , “”false
其他值true

基础运算符,数学

二元运算符 + 连接字符串

只要任意一个运算元是字符串,那么另一个运算元也将被转化为字符串。

   alert( '1' + 2 ); // "12"
   alert( 2 + '1' ); // "21"

二元 + 是唯一一个以这种方式支持字符串的运算符。其他算术运算符只对数字起作用,并且总是
将其运算元转换为数字。

如减法和除法运算的示例:

alert( 6 - '2' ); // 4,将 '2' 转换为数字
alert( '6' / '2' ); // 3,将两个运算元都转换为数字

数字转化,一元运算符 +

一元运算符加号,应用于单个值,对数字没有任何作用。但是如果运算元不是数字,加号 + 则会将其转化为数字。
效果和 Number(…) 相同,但是更加简短。

// 对数字无效
let x = 1;
alert( +x ); // 1
let y = -2;
alert( +y ); // -2
// 转化非数字
alert( +true ); // 1
alert( +"" );   // 0

let apples = "2";
let oranges = "3";
// 在二元运算符加号起作用之前,所有的值都被转化为了数字
alert( +apples + +oranges ); // 5
// 更长的写法
// alert( Number(apples) + Number(oranges) ); // 5

常用运算符优先级

优先级名称符号
17一元加号+
17一元负号-
16求幂**
15乘号*
15除号/
13加号+
13减号-
3赋值符=

自增/自减运算符

运算符 ++ 和 – 可以置于变量前,也可以置于变量后。

  • 当运算符置于变量后,被称为“后置形式”: counter++ 。
  • 当运算符置于变量前,被称为“前置形式”: ++counter 。
    所有的运算符都有返回值,自增/自减也不例外。前置形式返回一个新的值,但后置返回原来的值(做加法/减法之前的值)。
let a=1;
let b=1;
let c=0;
let d=0;
c=a++;
d=++b;
alert(a);//返回2
alert(b);//返回2
alert(c);//返回1
alert(d);//返回2

位运算符

位运算符把运算元当做 32 位整数,并在它们的二进制表现形式上操作。

  • 按位与 ( & )
  • 按位或 ( | )
  • 按位异或 ( ^ )
  • 按位非 ( ~ )
  • 左移 ( << )
  • 右移 ( >> )
  • 无符号右移 ( >>> )

值的比较

不同类型间的比较

当对不同类型的值进行比较时,JavaScript 会首先将其转化为数字(number)再判定大小。

alert( '2' > 1 ); // true,字符串 '2' 会被转化为数字 2
alert( '01' == 1 ); // true,字符串 '01' 会被转化为数字 1

null 和 undefined 在相等性(==)中的比较结果确是不同的

JavaScript 存在一个特殊的规则,会判定它们相等。他们两个仅仅等于对方而不等于其他任何的值(只在非严格相等下成立)。

alert( null == undefined ); // true
alert( null == 0 ); // false

相等性检查 == 和普通比较符 > < >= <= 的代码逻辑是相互独立的。

  1. 进行值的比较时, null 会被转化为数字,因此它被转化为了 0 。
  2. undefined 和 null 在相等性检查 == 中不会进行任何的类型转换,它们有自己独
    立的比较规则,所以除了它们之间互等外,不会等于任何其他的值。
alert( null > 0 );  // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true

严格相等

普通的相等性检查 == 存在一个问题,它不能区分出 0 和 false :
比如

alert( 0 == false ); // true
alert( '' == false ); // true
alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)

严格相等运算符 === 在进行比较时不会做任何的类型转换。

逻辑运算符

JavaScript 中有三个逻辑运算符: || (或), && (与), !(非)。

||(或)

result = a || b;

如果参与运算的任意一个参数为 true ,返回的结果就为 true ,否则返回 false 。
JavaScript 的“附加”特性。
或运算寻找第一个真值

result = value1 || value2 || value3;

或运算符 || 做了如下的事情:

  • 从左到右依次计算操作数。
  • 处理每一个操作数时,都将其转化为布尔值。如果结果是 true ,就停止计算,返回这个操作
    数的初始值。
  • 如果所有的操作数都被计算过(也就是,转换结果都是 false ),则返回最后一个操作数。
    返回的值是操作数的初始形式,不会做布尔转换。
    也就是说,一个或运算 || 的链,将返回第一个真值,如果不存在真值,就返回该链的最后一个
    值。

比如:

alert( 1 || 0 ); // 1(1 是真值)
alert( null || 1 ); // 1(1 是第一个真值)
alert( null || 0 || 1 ); // 1(第一个真值)
alert( undefined || null || 0 ); // 0(都是假值,返回最后一个值)

&&(与)

result = a && b;

在传统的编程中,当两个操作数都是真值时,与运算返回 true ,否则返回 false 。
JavaScript 的“附加”特性。
或运算寻找第一个假值

result = value1 && value2 && value3;

与运算 && 做了如下的事:

  • 从左到右依次计算操作数。
  • 在处理每一个操作数时,都将其转化为布尔值。如果结果是 false ,就停止计算,并返回这个
    操作数的初始值。
  • 如果所有的操作数都被计算过(例如都是真值),则返回最后一个操作数。

换句话说,与运算返回第一个假值,如果没有假值就返回最后一个值。

// 如果第一个操作数是真值,
// 与运算返回第二个操作数:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5
// 如果第一个操作数是假值,
// 与运算将直接返回它。第二个操作数会被忽略
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0

与运算 && 的优先级比或运算 || 要高。

!(非)

感叹符号 ! 表示布尔非运算符。

result = !value;

逻辑非运算符接受一个参数,并按如下运作:

  1. 将操作数转化为布尔类型: true/false 。
  2. 返回相反的值。

两个非运算 !! 可以将某个值转化为布尔类型

空值合并运算符’??’

将值既不是 null 也不是 undefined 的表达式称为“已定义的(defined)”。
空值合并运算符(nullish coalescing operator)的写法为两个问号 ?? 。
a ?? b 的结果是:

  • 如果 a 是已定义的,则结果为 a ,
  • 如果 a 不是已定义的,则结果为 b 。

||与??的区别

  • || 返回第一个 真 值。
  • ?? 返回第一个 已定义的 值。**|| 无法区分 false 、 0 、空字符串 “” 和 null/undefined 。**比如:
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
alert("0"||100);// 0

break/continue标签

有时候我们需要从一次从多层嵌套的循环中跳出来。标签 是在循环之前带有冒号的标识符:

labelName: for (...) {
  ...
}

break <labelName>语句跳出循环至标签处:

outer: for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    if (!input) break outer; // 跳出到最外层循环
  }
}
alert('Done!');

continue 指令也可以与标签一起使用。在这种情况下,执行跳转到标记循环的下一次迭代。

switch语句

case分支下如果没有 break ,程序将不经过任何检查就会继续执行下一个 case 。

let a = 2 + 2;
switch (a) {
  case 3:
    alert( 'Too small' );
  case 4:
    alert( 'Exactly!' );
  case 5:
    alert( 'Too big' );
  default:
    alert( "I don't know such values" );
}

在没有break的情况下,上面的代码会连续执行三个alert

任何表达式都可以成为 switch/case 的参数
共享同一段代码的几个 case 分支可以被分为一组

let a = 3;
switch (a) {
  case 4:
    alert('Right!');
    break;
  case 3: // (*) 下面这两个 case 被分在一组
  case 5:
    alert('Wrong!');
    alert("Why don't you take a math class?");
    break;
  default:
    alert('The result is strange. Really.');
}

用switch/case进行比较,被比较的值必须是相同的类型才能进行匹配。

函数

函数声明

function showMessage() {
  alert( 'Hello everyone!' );
}

function 关键字首先出现,然后是 函数名,然后是括号之间的 参数 列表(用逗号分隔,在上
述示例中为空),最后是花括号之间的代码(即“函数体”)。

function name(parameters) {
  ...body...
}

关于函数参数变量与全局变量同名

我们有一个变量 from ,并将它传递给函数。请注意:函数会修改 from ,但在函数外部看不到更改,因为函数修改的是复制的变量值副本:

function showMessage(from, text) {
  from = '*' + from + '*'; // 让 "from" 看起来更优雅
  alert( from + ': ' + text );
}
let from = "Ann";
showMessage(from, "Hello"); // *Ann*: Hello
// "from" 值相同,函数修改了一个局部的副本。
alert( from ); // Ann

这里的from是一个形参,类似于java、c语言中函数的形参:

public static void showMessage( String from,String text ){

}

在函数内部对,相当于新建了一个变量用于接收原来的参数,这个新建的变量只在函数中生效,所以并不会影响外部的数值。

空值的 return 或没有 return 的函数返回值为 undefined

function doNothing() { /* 没有代码 */ }
alert( doNothing() === undefined ); // true

不要在 return 与返回值之间添加新行,因为 JavaScript 默认会在 return 之后加上分号。

总结

函数声明方式如下所示:

function name(parameters, delimited, by, comma) {
  /* code */
}
  • 作为参数传递给函数的值,会被复制到函数的局部变量。
  • 函数可以访问外部变量。但它只能从内到外起作用。函数外部的代码看不到函数内的局部变量。
  • 函数可以返回值。如果没有返回值,则其返回的结果是 undefined 。

为了使代码简洁易懂,建议在函数中主要使用局部变量和参数,而不是外部变量。
与不获取参数但将修改外部变量作为副作用的函数相比,获取参数、使用参数并返回结果的函数更容易理解。
函数命名:

  • 函数名应该清楚地描述函数的功能。当我们在代码中看到一个函数调用时,一个好的函数名能够让我们马上知道这个函数的功能是什么,会返回什么。
  • 一个函数是一个行为,所以函数名通常是动词。
  • 目前有许多优秀的函数名前缀,如 create… 、 show… 、 get… 、 check… 等等。使用它们来提示函数的作用

函数表达式

函数表达式定义格式:

let sayHi = function() {
  alert( "Hello" );
};

函数表达式与函数声明对比

  1. 语法
    函数声明:在主代码流中声明为单独的语句的函数。
    function sum(a, b) {
    return a + b;
    }
    
    函数表达式:在一个表达式中或另一个语法结构中创建的函数。
    // 函数表达式
    let sum = function(a, b) {
    return a + b;
    };
    
  2. JavaScript 引擎创建函数的时机。
    • 在执行代码块之前,内部算法会先处理函数声明。所以函数声明在其被声明的代码块内的任何位置都是可见的。
    • 函数表达式在执行流程到达时创建。

箭头函数基础

箭头函数的格式:

  1. 不带花括号: (…args) => expression — 右侧是一个表达式:函数计算表达式并返回
    其结果。如:
    let sum = (a, b) => a + b;
    /* 这个箭头函数是下面这个函数的更短的版本:
    let sum = function(a, b) {
    return a + b;
    };
    */
    alert( sum(1, 2) ); // 3
    
    • 如果我们只有一个参数,还可以省略掉参数外的圆括号
      let double = n => n * 2;
      // 差不多等同于:let double = function(n) { return n * 2 }
      alert( double(3) ); // 6
      
    • 如果没有参数,括号将是空的(但括号应该保留)
      let sayHi = () => alert("Hello!");
      sayHi();
      
  2. 带花括号: (…args) => { body } — 花括号允许我们在函数中编写多个语句,但是我们
    需要显式地 return 来返回一些内容
    let sum = (a, b) => {  // 花括号表示开始一个多行函数
    let result = a + b;
    return result; // 如果我们使用了花括号,那么我们需要一个显式的 “return”
    };
    alert( sum(1, 2) ); // 3
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值