重学前端 31 # JavaScript的语句

简介: 重学前端 31 # JavaScript的语句

一、介绍


JavaScript 标准中,把语句分成了两种:普通语句和声明型语句。

1.1、普通语句

dd32078e786596f91c34ab7d42ea0027.png


1.2、声明型语句

cb24e58770dc9713cf692689f0d617b0.jpg



二、语句块


语句块就是一对大括号。

{
    var x, y;
    x = 10;
    y = 20;
}


语句块的意义和好处在于:让我们可以把多行语句视为同一行语句。

// 语句块会产生作用域
{
    let x = 1;
}
console.log(x); // Uncaught ReferenceError: x is not defined



三、空语句


空语句就是一个独立的分号,实际上没什么大用。

;




四、if 语句


if(a < b)
    console.log(a);


if 和 else 连写成多分支条件

if(a < 10) {
   //...
} else if(a < 20) {
   //...
} else if(a < 30) {
   //...
} else {
   //...
}



五、switch 语句


switch(num) {
case 1:
    console.log(1);
case 2:
    console.log(2);
case 3:
    console.log(3);
}
// num等于1,输出:1 2 3
// num等于2,输出:2 3
// num等于3,输出:3
switch(num) {
case 1:
    console.log(1);
    break;
case 2:
    console.log(2);
    break;
case 3:
    console.log(3);
    break;
}
// num等于1,输出:1
// num等于2,输出:2
// num等于3,输出:3


winter 的看法是:“ switch 已经完全没有必要使用了,应该用 if else 结构代替。”。




六、循环语句


6.1、while 循环和 do while 循环

let a = 5;
while(a--) {
    console.log("*");
}
// 输出:* * * * *
let a = 6;
do {
    console.log(a);
} while(a < 6)
// 6


6.2、普通 for 循环

for(i = 0; i < 6; i++)
    console.log(i);
// 0 1 2 3 4 5
for(var i = 0; i < 6; i++)
    console.log(i);
// 0 1 2 3 4 5
for(let i = 0; i < 6; i++)
    console.log(i);
// 0 1 2 3 4 5
for(const i = 0; i < 6; i++)
    console.log(i);
// 0 Uncaught TypeError: Assignment to constant variable.
var j = 0;
for(const i = 0; j < 6; j++)
    console.log(i);
// 0 0 0 0 0 0


6.3、for in 循环

for in 循环枚举对象的属性,体现了属性的 enumerable 特征。

let o = { a: 10, b: 20}
Object.defineProperty(o, "c", {enumerable: false, value: 30})
for(let p in o)
    console.log(p);
// 输出:a b
// enumerable为true,输出:a b c


6.4、for of 循环和 for await of 循环

for of 循环是非常棒的语法特性。背后的机制是 iterator 机制。


1、用于数组

for(let e of [1, 2, 3, 4, 5])
    console.log(e);
// 1 2 3 4 5


2、如何为一个对象添加 iterator

let o = {  
    [Symbol.iterator]:() => ({
        _value: 0,
        next(){
            if(this._value == 10)
                return {
                    done: true
                }
            else return {
                value: this._value++,
                done: false
            };
        }
    })
}
for(let e of o)
    console.log(e);
// 0 1 2 3 4 5 6 7 8 9



3、使用 generator function。

function* foo(){
    yield 0;
    yield 1;
    yield 2;
    yield 3;
}
for(let e of foo())
    console.log(e);
// 0 1 2 3


4、JavaScript 还为异步生成器函数配备了异步的 for of

function sleep(duration) {
    return new Promise(function(resolve, reject) {
        setTimeout(resolve,duration);
    })
}
async function* foo(){
    i = 0;
    while(true) {
        await sleep(1000);
        yield i++;
    }
}
for await(let e of foo())
    console.log(e);
// 从0开始,每隔1s加1,输出:0 1 2 3 4 5....



七、return


return 语句用于函数中,它终止函数的执行,并且指定函数的返回值。

function squre(x){
    return x * x;
}



八、break 语句和 continue 语句


break 语句用于跳出循环语句或者 switch 语句,continue 语句用于结束本次循环并继续循环。

for(let i = 0; i < 2; i++){
    console.log(i)
    if( i == 0){
        break;
    }
}
// 0
for(let i = 0; i < 2; i++){
    console.log(i)
    if( i == 0){
        continue;
    }
}
// 0 1




九、with 语句


with 语句把对象的属性在它内部的作用域内变成变量。

let o = {a:1, b:2}
with(o){
    console.log(a, b);
}
// 1 2




十、try 语句和 throw 语句


try 语句和 throw 语句用于处理异常。try 语句用于捕获异常,用 throw 抛出的异常。


  • try 部分用于标识捕获异常的代码段
  • catch 部分则用于捕获异常后做一些处理(catch结构会创建一个局部的作用域,不能再声明变量 e ,否则会出错。)
  • finally 语句一般用于释放资源,它一定会被执行
try {
    throw new Error("error");
} catch(e) {
    console.log(e);
} finally {
    console.log("finally");
}
// Error: error at <anonymous>:2:1  
// finally



十一、debugger 语句


debugger 语句的作用是:通知调试器在此断点。在没有调试器挂载时,它不产生任何效果。




十二、var


1、var 声明语句是古典的 JavaScript 中声明变量的方式。而现在,基本使用 let 和 const 。

2、如果仍然想要使用 var,winter建议:把它当做一种保障变量是局部的逻辑,遵循以下三条规则:


  • 声明同时必定初始化
  • 尽可能在离使用的位置近处声明
  • 不要在意重复声明



// 下面这里x声明了两次
function add(x,y) {
    console.log(x + y);
}
function multiply(x,y) {
    console.log(x * y);
}
var x = 1, y = 2;
add(x, y);
for(var x = 0; x < 2; x++)
    multiply(x,y);
// 3
// 0
// 2
// 使用let改造,用代码块限制了第一个 x 的作用域,这样就更难发生变量命名冲突引起的错误。
{
    let x = 1, y = 2;
    add(x, y);
}
for(let x = 0; x < 2; x++)
    multiply(x);



十三、let 和 const


const a = 2;
if(true){
    const a = 1;
    console.log(a);
}
console.log(a);
// 1 2


1、const 和 let 语句在重复声明时会抛错,这能够有效地避免变量名无意中冲突。

let a = 2
const a = 1;
// Uncaught SyntaxError: Identifier 'a' has already been declared



2、let 和 const 声明还是会被预处理。如果当前作用域内有声明,就无法访问到外部的变量。

const a = 2;
if(true){
    console.log(a); // 抛错
    const a = 1;
}
// Uncaught ReferenceError: Cannot access 'a' before initialization
if(true){
    console.log(a);
   var a = 1;
}
// undefined
// 上面的对比就说明 const 声明仍然是有预处理机制的。



十四、class 声明


class 最基本的用法只需要 class 关键字、名称和一对大括号。

1、class 的声明特征跟 constlet 类似,都是作用于块级作用域,预处理阶段则会屏蔽外部变量。


const a = 2;
if(true){
    console.log(a); // 抛错
    class a {
    }
}
// Uncaught ReferenceError: Cannot access 'a' before initialization


2、class 内部,可以使用 constructor 关键字来定义构造函数。

// 这个例子来自 MDN,它展示了构造函数、getter 和方法的定义。
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  // Getter
  get area() {
    return this.calcArea();
  }
  // Method
  calcArea() {
    return this.height * this.width;
  }
}



十五、函数声明


函数声明使用 function 关键字。


1、带 * 的函数是 generator。生成器函数可以理解为返回一个序列的函数,它的底层是 iterator 机制。

2、async 函数是可以暂停执行,等待异步操作的函数,它的底层是 Promise 机制。


function foo(){
}
function* foo(){
    yield 1;
    yield 2;
    yield 3;
}
async function foo(){
    await sleep(3000);
}
async function* foo(){
    await sleep(3000);
    yield 1;
}


3、函数的参数,可以只写形参名,还可以写默认参数和指定多个参数

function foo(a = 1, ...other) {
    console.log(a, other)
}
foo();
// 1 []
foo(3,4);
// 3 [4]


目录
相关文章
|
2月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
2月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
55 5
|
2月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
84 1
|
2月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
57 4
|
2月前
|
资源调度 前端开发 JavaScript
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第10天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤,包括安装依赖、创建混淆脚本、修改 `package.json` 脚本命令、构建项目并执行混淆,以及在 HTML 文件中引用混淆后的文件。通过这些步骤,可以有效提高代码的安全性。
121 2
|
2月前
|
设计模式 前端开发 JavaScript
揭秘!前端大牛们如何巧妙利用JavaScript,打造智能交互体验!
【10月更文挑战第30天】前端开发领域充满了无限可能与创意,JavaScript作为核心语言,凭借强大的功能和灵活性,成为打造智能交互体验的重要工具。本文介绍前端大牛如何利用JavaScript实现平滑滚动、复杂动画、实时数据更新和智能表单验证等效果,展示了JavaScript的多样性和强大能力。
62 4
|
2月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
183 1
|
2月前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
63 1
|
2月前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
51 1