重学前端 30 # JavaScript语法的基本规则

简介: 重学前端 30 # JavaScript语法的基本规则

一、脚本和模块


JavaScript 有两种源文件,一种叫做脚本,一种叫做模块。在 ES5 和之前的版本中,就只有一种源文件类型(就只有脚本),ES6 引入了模块机制。


1.1、区别


1、脚本:是可以由浏览器或者 node 环境引入执行的;模块:只能由 JavaScript 代码用 import 引入执行。


2、从概念上,脚本:具有主动性的 JavaScript 代码段,是控制宿主完成一定任务的代码;模块:是被动性的 JavaScript 代码段,是等待被调用的库。


3、如果要引入模块,必须给 script 标签添加 type="module"。如果引入脚本,则不需要 type。

<script type="module" src="xxx.js"></script>


f8d989b07301e485332419c253c8f36a.jpg


1.2、import 声明


import 声明有两种用法,一个是直接 import 一个模块,另一个是带 from 的 import,它能引入模块里的一些信息。

import "mod"; // 引入一个模块
import v from "mod";  // 把模块默认的导出值放入变量 v



1、带 from 的 import 细分有三种用法

   import x from "./a.js" 引入模块中导出的默认值。

   import {a as x, modify} from "./a.js"; 引入模块中的变量。

   import * as x from "./a.js" 把模块中所有的变量以类似对象属性的方式引入。


第一种方式可以跟后两种组合使用。


   import d, {a as x, modify} from "./a.js"

   import d, * as x from "./a.js"



2、例子


假设有两个模块 a 和 b。我们在模块 a 中声明了变量和一个修改变量的函数,并且把它们导出。用 b 模块导入了变量和修改变量的函数。



模块 a

export var a = 1;
export function modify(){
    a = 2;
}


模块 b

import {a, modify} from "./a.js";
console.log(a); // 1
modify();
console.log(a); // 2



1.3、export 声明


与 import 相对,export 声明承担的是导出的任务。模块中导出变量的方式有两种,一种是独立使用 export 声明,另一种是直接在声明型语句前添加 export 关键字。



1、独立使用 export 声明

一个 export 关键字加上变量名列表.

export {a, b, c};



2、export 可以加在任何声明性质的语句之前

   var

   function (含 async 和 generator)

   class

   let

   const



3、export default 表示导出一个默认变量值,它可以用于 function 和 class。这里导出的变量是没有名称的,可以使用 import x from "./a.js" 这样的语法,在模块中引入。


4、export default 还支持一种语法,后面跟一个表达式

// 注意:a 的变化与导出的值就无关,修改变量 a,不会使得其他模块中引入的 default 值发生改变。
var a = {};
export default a;


5、在 import 语句前无法加入 export,但是可以直接使用 export from 语法。

export a from "a.js"





二、函数体


执行函数的行为通常是:在 JavaScript 代码执行时,注册宿主环境的某些事件触发的,执行的过程:就是执行函数体(函数的花括号中间的部分)。函数体:其实也是一个语句的列表。跟脚本和模块比起来,函数体中的语句列表中多了 return 语句可以用。


2.1、普通函数体

function foo(){
    //Function body
}


2.2、异步函数体

async function foo(){
    //Function body
}


2.3、生成器函数体

function *foo(){
    //Function body
}


2.4、异步生成器函数体

async function *foo(){
    //Function body
}


2.5、上面四种函数体的区别

区别在于:能否使用 await 或者 yield 语句。


d2c49de4146cd5f05b21e16469f0e815.jpg



三、预处理


JavaScript 执行前,会对脚本、模块和函数体中的语句进行预处理。预处理过程将会提前处理 var、函数声明、class、const 和 let 这些语句,以确定其中变量的意义。


3.1、var 声明

var 声明永远作用于脚本、模块和函数体这个级别,在预处理阶段,不关心赋值的部分,只管在当前作用域声明这个变量。


3.1.1、例子一

var a = 1;
function foo() {
    console.log(a);
    var a = 2;
}
foo(); // undefined


预处理过程在执行之前,所以有函数体级的变量 a,就不会去访问外层作用域中的变量 a 了,而函数体级的变量 a 此时还没有赋值,所以是 undefined。



3.1.2、例子二

var a = 1;
function foo() {
    console.log(a);
    if(false) {
        var a = 2;
    }
}
foo(); // undefined

首先 if(false) 中的代码永远不会被执行,但是预处理阶段并不管这个,var 的作用能够穿透一切语句结构,它只认脚本、模块和函数体三种语法结构。



3.1.3、例子三

var a = 1;
function foo() {
    var o= {a:3}
    with(o) {
        var a = 2;
    }
    console.log(o.a);
    console.log(a);
}
foo(); // 2  undefine


3.1.4、例子四

早年 JavaScript 没有 let 和 const,只能用 var,而 var 除了脚本和函数体都会穿透,可用立即执行的函数表达式(IIFE)来产生作用域。

for(var i = 0; i < 20; i ++) {
    void function(i){
        var div = document.createElement("div");
        div.innerHTML = i;
        div.onclick = function(){
            console.log(i);
        }
        document.body.appendChild(div);
    }(i);
}
// 点击div对应的序号
for(var i = 0; i < 20; i ++) {
    var div = document.createElement("div");
    div.innerHTML = i;
    div.onclick = function(){
        console.log(i);
    }
    document.body.appendChild(div);
}
// 点击div全是20


3.2、function 声明

在全局(脚本、模块和函数体),function 声明表现跟 var 相似,不同之处在于,function 声明不但在作用域中加入变量,还会给它赋值。



3.2.1、例子一

console.log(foo);
function foo(){
}
// ƒ foo(){}


3.2.2、例子二

console.log(foo);
if(true) {
    function foo(){
    }
}
// undefined


3.3、class 声明

class 声明在全局的行为跟 function 和 var 都不一样。


3.3.1、例子一

console.log(c);
class c{
}
// 报错


3.3.2、例子二

var c = 1;
function foo(){
    console.log(c);
    class c {}
}
foo();
// 还是报错,这说明,class 声明也是会被预处理的,它会在作用域中创建变量,并且要求访问它时抛出错误。





四、指令序言机制


脚本和模块都支持一种特别的语法,叫做指令序言(Directive Prologs)。最早是为了 use strict 设计的,它规定了一种给 JavaScript 代码添加元信息的方式。


"use strict"; // 单引号也不影响它是指令序言。
function f(){
    console.log(this);
};
"use strict"; // 没有出现在最前,所以不是指令序言。
f.call(null);
// null
目录
相关文章
|
7天前
|
资源调度 前端开发 JavaScript
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第10天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤,包括安装依赖、创建混淆脚本、修改 `package.json` 脚本命令、构建项目并执行混淆,以及在 HTML 文件中引用混淆后的文件。通过这些步骤,可以有效提高代码的安全性。
|
15天前
|
设计模式 前端开发 JavaScript
揭秘!前端大牛们如何巧妙利用JavaScript,打造智能交互体验!
【10月更文挑战第30天】前端开发领域充满了无限可能与创意,JavaScript作为核心语言,凭借强大的功能和灵活性,成为打造智能交互体验的重要工具。本文介绍前端大牛如何利用JavaScript实现平滑滚动、复杂动画、实时数据更新和智能表单验证等效果,展示了JavaScript的多样性和强大能力。
31 4
|
13天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
13天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
20 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
18天前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
25 1
|
19天前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
16 1
|
22天前
|
前端开发 JavaScript UED
"前端小技巧大揭秘:JS如何将后台时间戳秒变亲切小时前、分钟前,让用户秒懂,提升互动体验!"
【10月更文挑战第23天】在Web开发中,将后台返回的时间戳转换为“小时前”、“分钟前”、“刚刚”等友好的时间描述是常见需求。本文介绍如何用JavaScript实现这一功能,通过计算当前时间和时间戳的差值,返回相应的描述,提升用户体验。
25 1
|
28天前
|
前端开发 JavaScript 安全
JavaScript前端开发技术
JavaScript(简称JS)是一种广泛使用的脚本语言,特别在前端开发领域,它几乎成为了网页开发的标配。从简单的表单验证到复杂的单页应用(SPA),JavaScript都扮演着不可或缺的角色。
20 3
|
27天前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
10天前
|
前端开发 JavaScript 安全
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第7天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤。包括项目准备、安装 `javascript-obfuscator`、配置 Vite 构建以应用混淆,以及最终构建项目进行混淆。通过这些步骤,可以有效提升前端代码的安全性,防止被他人轻易分析和盗用。