JavaScript 入门指南(一)简介及基础语法

JavaScript 简介

JavaScript,简称 js,是一种基于对象(object-based)和事件驱动(Event Driven)的简单的并具有安全性能的脚本语言。

JavaScript 特性

  • JavaScript 是解释性语言,而不是编译性语言;

    在支持 JavaScript 的浏览器中运行的过程中没有编译过程,而是逐行解释执行。

  • JavaScript 是一种轻量级的脚本语言(script language)。

    不具备开发操作系统的能力,只能用来编写控制其他大型应用程序(比如浏览器)的脚本。

  • Javascript 是一种嵌入式语言,本身不提供任何 I/O 相关的 API,主要通过调用宿主环境(host)的 API 来工作。

  • JavaScript 是可插入 HTML 页面的编程代码。插入 HTML 页面后,可由所有的现代浏览器执行。

JavaScript 组成

  • ECMAScript:JavaScript 的核心,语法格式,使用方法

  • 文档对象模型(DOM,document object model):DOM(文档对象模型)是 HTML 和 XML 的应用程序接口(API)。

    DOM 将把整个页面规划成由节点层级构成的文档 document 对象 有 一个一个的元素(element)

  • 浏览器对象模型(BOM,browser object model):对浏览器窗口进行访问和操作

JavaScript 特点:

  • 脚本语言:脚本语言是一种简单的程序,是由一些 ASCII 字符构成,可以使用任何一种文本编辑器编写。

    一些程序语言(如 C、C++、Java 等)都必须经过编译,将源代码编译成二进制的可执行文件之后才能运行,而脚本语言不需要事先编译,只要有一个与其相适应的解释器就可以执行。

    脚本语言是指在 web 浏览器内有解释器解释执行的编程语言,每次运行程序的时候,解释器会把程序代码翻译成可执行的格式。

  • 基于对象的语言:非面向对象

    面向对象有三大特点(封装,继承,多态)缺一不可。

    通常”基于对象”是使用对象,但无法利用现有对象模板产生新的对象类型,也就是说”基于对象”没有继承的特点。

    注意:目前的 js 脚本已经支持创建自定义类,继承等

  • 事件驱动:在网页中执行了某种操作的动作,被称为”事件”(Event)

    比如按下鼠标、移动窗口、选择菜单等都可以视为事件。

    当事件发生后,可能会引起相应的事件响应。

  • 简单性 :变量类型是采用弱类型,并未使用严格的数据类型。

  • 安全性:JavaScript 不能访问本地的硬盘,不能将数据存入到服务器上,不能对网络文档进行修改和删除,只能通过浏览器实现信息浏览或动态交互

  • 跨平台(系统)性:JavaScript 依赖于浏览器本身,与操作平台无关。

    只要计算机安装了支持 JavaScript 的浏览器(装有JavaScript 解释器),JavaScript 程序就可以正确执行。

缺点

  • 部分浏览器兼容性不好!

    各种浏览器支持 JavaScript 的程度是不一样的,支持和不完全支持 JavaScript 的浏览器在浏览同一个带有 JavaScript 脚本的网页时,效果会有一定的差距,有时甚至会显示不出来。

JavaScript 的版本

  • ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版。

    ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并没有类的概念,但是目前浏览器的 JavaScript 是 ES5 版本,大多数高版本的浏览器也支持 ES6,不过只实现了 ES6 的部分特性和功能。

    ES6 的语法:传送门

JavaScript 基础语法

js 在 html 中的引入方式

JS 在 html 中两种引入方式:

  • 方式1:内嵌式(内部脚本):在 html 中创建一个 script 标签,在标签中写 js 代码

    格式:

    <script type="text/javascript">
        js代码;
    </script>
    
  • 方式2:外联式(外部脚本):在 html 页面中使用 script 标签引入外部的 js 文件

    一个 js 文件可以被多个 html 页面同时引入

    <script type="text/javascript" src="外部js文件的路径"></script>
    

注意:

  • JavaScript 代码必须位于 <script></script> 标签之间

  • 一个 HTML 文档中可以出现多个 <script> 标签

  • JavaScript 代码的出现次序就是 JavaScript 的执行顺序

  • 如果一个 script 标签引入了外部 js 文件,那么这个标签中就不能写 js 代码了,会失去作用

    如果想要再写 js 代码,需要重新创建一个 script 标签

  • 理论上 script 标签可以写在 html 页面中的任意位置,在不影响功能的前提下,尽量把 script 标签写在页面的下边,让浏览器先解析出页面,给用户展示,再执行 js 的代码(页面显示速度快)

示例:

  • 主 js 文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>JS两种引入方式</title>
        <!--1.内嵌式(内部脚本)-->
        <script type="text/javascript">
            //全局函数alert(数据);可以在页面中弹出一个对话框,输出指定的数据
            alert(1);
        </script>
        <!--2.外联式(外部脚本)-->
        <script src="js/1.js"></script>
    </head>
    <body>
    </body>
    </html>
    

    1.js文件

    alert("你好");
    

js 在 js 中的导出导入方式

  • JavaScript 中,模块是一种可重用的代码块,它将一些代码打包成一个单独的单元,并且可以在其他代码中进行导入和使用。

    在导入模块时,JavaScript中有两种常用的方式::import 和 require

    • import :是 ES6 引入的新特性,它允许以声明式的方式导入其他模块中的内容
    • require :是 Node.js 中的特性,它允许使用一个函数来加载和导入其他模块
  • import 和 require 的区别

    • 导入方式

      • import 导入的方式是使用关键字 import 加上大括号(如果需要导入的内容是命名导出的话),再加上模块名的方式进行导入。例如:

        import {func1, func2 } from './myModule';
        
      • require 导入的方式是使用 require 函数,将需要导入的模块路径作为参数传递给该函数。例如:

        const myModule = require('./myModule');
        
    • 文件类型

      • import 只能导入 ES6 模块或者使用 Babel 等工具转化为 ES6 模块的代码。
      • require 则可以导入 CommonJS 模块、AMD 模块、UMD 模块以及 Node.js 内置模块等多种类型的模块。
    • 变量提升

      • 在 ES6 中,import 语句是静态执行的,意味着它们在模块内部的顶层执行,并且在模块内部创建一个局部作用域。这意味着导入的变量只在模块内部可见,并且不会影响模块外部的变量。因此,使用 import 导入的变量是不会被提升的。
      • require 函数是动态执行的,这意味着它在运行时执行,并且不会在模块内部创建一个局部作用域。因此,使用 require 导入的变量是可以被提升的。

      注:如何理解 import 语句是静态执行的和 require 函数是动态执行的?

      • 理解 import 语句是静态执行的和require函数是动态执行的,需要先了解这两个概念的含义。

        • 静态执行是指在编译阶段就能够确定其执行结果的代码执行方式。

          在 JavaScript 中,import 语句属于静态执行的代码,也就是说,当 JavaScript 引擎执行代码时,会在编译阶段对 import 语句进行静态分析,确定所导入的模块,并在运行时加载这些模块。

        • 动态执行是指在运行时才能确定其执行结果的代码执行方式。

          在 JavaScript 中,require 函数属于动态执行的代码,也就是说,当 JavaScript 引擎执行代码时,会在运行时动态地确定所需的模块,并加载这些模块。

      • 因此,可以理解为:

        • import 语句是静态执行的,因为在编译阶段就能够确定所导入的模块,从而在运行时快速加载这些模块。
        • require 函数是动态执行的,因为在运行时才能够确定所需的模块,需要动态地加载这些模块。

      注意:由于 import 语句是静态执行的,因此在代码中不能使用变量或表达式作为模块路径,只能使用字符串字面量。而 require 函数则可以接受变量或表达式作为模块路径,从而动态地确定所需的模块。

    • 导出方式

      • import 使用ES6的导出方式,可以使用命名导出和默认导出两种方式进行导出。例如:

        // 命名导出
        export function func1() {}
        // 默认导出
        export default {}
        
      • require 使用 CommonJS 的导出方式,只能使用默认导出方式进行导出。例如:

        module.exports = {};
        

        require 除了可以使用 module.exports 导出模块,还可以使用 exports 对象。

        实际上,exports 对象是 module.exports 的一个引用。

        当使用 exports 导出时,实际上是向 module.exports 对象添加属性和方法。

    • 模块作用域

      在 JavaScript 中,每个模块都有自己的作用域,模块之间的变量是互相隔离的,不会相互干扰。这也是模块化编程的一个主要特点。

      • 在使用 import 导入模块时,实际上是在模块内部创建了一个指向被导入模块的引用,而不是直接复制模块中的变量。因此,当不同的文件中使用 import 导入相同的模块时,它们实际上是共享了同一个模块实例,所以可以访问和修改同一个模块中的变量。
      • 在使用 require 导入模块时,实际上是将导入模块中的变量直接复制到(可以理解为浅拷贝)当前模块的作用域中。因此,当不同的文件中使用 require 导入相同的模块时,它们实际上是拥有各自独立的模块实例,彼此之间不会共享模块中的变量。

      需要注意的是,如果使用 require 导入的模块中含有可变状态的对象,那么在不同文件中修改该对象的变量会相互影响。这也是 require 在某些情况下会产生一些难以预测的副作用的原因之一。而使用 import 导入的模块,由于是共享同一个模块实例,相对来说更容易管理和控制。

      • 如果使用 require 导入的模块中含有可变状态的对象,比如一个对象的属性值可以被修改,那么当在不同的文件中修改这个对象中变量时,由于 require 会将导入的模块中的变量直接复制到当前模块的作用域中(类似于浅拷贝,模块中的普通变量(例如字符串、数字等)是非共享的,而对象的变量则是能被修改共用的),因此会导致这个对象的变量在不同文件中的值相互影响。

      • 需要注意的是,这种影响是由于模块之间共享同一个对象的引用造成的,而不是模块本身的问题。因此,在编写模块时,需要谨慎地处理可变状态的对象,尽量避免在不同模块之间共享同一个对象的引用,以避免出现不可预测的副作用。

      • 举个例子,假设有一个 config.js 模块,其中定义了一个可变的对象 config,并且在 main.jsapp.js 两个文件中使用了 require 导入该模块:

        config.js:

        let config = {
          env: 'dev',
          port: 3000
        }
        module.exports = config;
        

        main.js:

        const config = require('./config.js');
        // 修改config对象的属性值
        config.port = 4000;
        console.log(`config.port in main.js: ${config.port}`);
        

        app.js:

        const config = require('./config.js');
        console.log(`config.port in app.js: ${config.port}`);
        
        • 当执行 main.jsapp.js 时,它们都会通过 require 导入 config.js 模块,并且 main.js 中修改了 config 对象的 port 属性值。
        • 那么当 app.js 输出 config.port 时,它实际上输出的是被 main.js 修改后的 port 属性值,而不是 config.js 模块原本定义的值。
        • 这就是因为 require 导入的模块中含有可变状态的对象或变量,在不同文件中修改该对象或变量会相互影响的原因。

js 的三种输出方式

  • 方式1:把数据输出到浏览器的控制台:console.log(“hello”);

    注:按 F12 调出控制台

  • 方式2:输出到 html 页面的 body 中:document.writeln(“200”);

  • 方式3:浏览器弹出对话框输出:alert(“你好”);

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JS三种输出方式</title>
</head>
<body>
    <script>
        //JS三种输出方式
        //1.把数据输出到浏览器的控制台
        console.log("hello");
        //2.输出到html页面的body中
        document.writeln("200");
        //3.浏览器弹出对话框输出
        alert("你好");
    </script>
</body>
</html>

js 的变量

  • js 语言:弱类型语言。给变量赋什么类型的值,那么这个变量就是什么类型

  • 定义变量

    在使用每种数据的时候,都可以使用关键字 var(es5 特性)或 let(es6 特性)来定义变量

    • var:定义全局变量

      • 作用域在这个 script 标签中都有效(作用域大)
      • 可以先使用变量,再定义变量
      var 变量名; 		 	  // 变量没有赋值,有默认值undefined
      var 变量名a, 变量名b;		// 同时声明多个变量
      var 变量名 = 数据值;		// 定义变量的同时,给变量进行初始化赋值
      
    • let:定义局部变量

      • 只在局部的位置(自己所在的块级)有效

        任何一对花括号 { } 中的语句都属于一个块,在花括号里面用 let 定义的所有变量在花括号外都是不可见的,称之为块级作用域

      • 必须先定义后使用

      let 变量名; 	// 变量没有赋值,有默认值undefined
      let 变量名a, 变量名b;		// 同时声明多个变量
      let 变量名 = 数据值;
      
  • 定义常量

    在 js 中可以使用关键字 const 定义常量(常量的值是不能改变的)

    const 常量名 = 数据值;
    
  • 常量和变量的命名

    • 以字母,下划线或者 $ 开头,并且以字母,下划线,$,数字组成

    • 不能使用 关键字 和 保留字

      <!-- 关键字 -->
      break/case/catch/continue/debugger/default/in/do/else/finally/for/function/if/try
      /instanceof/new/return/switch/this/throw/typeof/var/void/while/with/delete
      
      <!-- 保留字 -->
      abstract/enum/int/short/boolean/export/interface/static/byte/extends/long/super/Char
      /final/native/synchronized/Class/float/package/throws/Const/goto/private/transient
      /debugger/implements/protected/volatile/double/import/public
      
    • 字母的大小写敏感

js 的运算符

  • 类型运算符

    • typeof:返回变量的类型
    • instanceof:返回对象是否对象类型的实例
  • 算数运算符

    • + :加法。注意:字符串+数字 表现为拼接,而不是将字符串类型转换成数字相加
    • - :减法
    • * :乘法
    • / :除法
    • % :取模(余数)
    • ++ :递加
    • -- :递减
  • 赋值运算符

    • = :将等号左侧的值或变量值赋值给等号右侧的变量,示例:x = y
    • += :先加再赋值左侧,示例:x += y 等价于 x = x + y
    • -= :先减再赋值左侧,示例:x -= y 等价于 x = x - y
    • *= :先乘再赋值左侧,示例:x *= y 等价于 x = x * y
    • /= :先除再赋值左侧,示例:x /= y 等价于 x = x / y
    • %= :先取模再赋值左侧,示例:x %= y 等价于 x = x % y
  • 比较运算符

    • == :等于
    • === :等值等型
    • != :不相等
    • !== :不等值或不等型
    • > :大于
    • < :小于
    • >= :大于或等于
    • <= :小于或等于
    • ? :三元运算符

    注意:

    • == 和 === 的区别

      等于判断(==):先判断类型,类型一致则直接比较内容,如果类型不一致,转换为数字类型后再比较内容

      等值判断(===):先判断类型,类型不一致则直接 false,类型一致则继续比较内容,内容一致则 true,不一致则 false

    • boolean 类型

      参与计算或比较时,true 转换为 1,false 转换为 0

  • 逻辑运算符

    • && :逻辑与
    • || :逻辑或
    • ! :逻辑非
  • 条件运算符(三目运算符、双元运算符)

    // 语法:
    变量名 = (condition) ? value1 : value2
    // 示例:
    var a = (11 == 5) ? "b" : "c"
    

js 的布尔运算规则

可以使用一些非布尔类型的值,作为布尔值来使用

  • boolean 类型: true:真;false:假
  • undefined 类型: 作为 false
  • null 类型:作为 false
  • string 类型: “”(空字符串)作为 false,非空的字符串作为 true
  • number 类型: 0 或 0.0 作为 false 使用,非 0 的数字作为 true
  • object 类型: 所有的对象都可以作为 true

js 的流程控制语句

分支语句:if、switch

  • if 语句:

    • if 语句 – 只有当指定条件为 true 时,使用该语句来执行代码
    • if…else 语句 – 当条件为 true 时执行代码,当条件为 false 时执行其他代码
    • if…else if…else 语句- 使用该语句来选择多个代码块之一来执行
  • switch 语句:使用该语句来选择多个代码块之一来执行

    格式:

    var 变量n = 变量值;
    switch(变量n):
        case 值1:
        	逻辑代码
            break;
        case 值2:
            逻辑代码
            break;
        ...
        default:
            逻辑代码
            break;
    

    代码解释:

    • 计算一次 switch 表达式
    • 把表达式的值与每个 case 的值进行对比
    • 如果存在匹配,则执行关联代码

    工作原理:

    1. 首先设置表达式 n(通常是一个变量)
    2. 随后表达式的值会与结构中的每个 case 的值做比较
    3. 如果存在匹配,则与该 case 关联的代码块会被执行
    4. 请使用 break 来阻止代码自动地向下一个 case 运行

    break 关键字的作用

    • 如果 js 遇到 break 关键词,它会跳出 switch 代码块。即停止 switch 代码块中更多代码的执行以及 case 测试。
    • 如果找到匹配,并完成任务,则随即中断执行(break),无需更多测试。
    • break 能够节省大量执行时间,因为它会“忽略” switch 代码块中的其他代码的执行。
    • switch 代码块中的最后一个 case 可以省略 break ,因为代码块在此处会自然结束,不必 break 来中断

    default 关键字的使用:使用 default 关键词来规定匹配不存在时做的事情

循环语句:while、do-while、for、for-each

  • while 循环

    如果条件为真的话,就会重复循环执行大括号包裹的代码块

    语法:

    while (条件){
    	代码块
    };
    
  • do-while 循环

    do-while 循环是 while 循环的变体。

    该循环会在检查条件是否为真之前执行一次代码块,然后如果条件为真的话,就会重复这个循环

    语法:

    do {
    	需要执行的代码
    } while (条件);
    
  • for 循环

    语法:

    for (进入循环前执行的语句; 进入循环的条件; 每次循环后执行的语句){        
    	被执行的代码块        
    }
    
    // 示例
    var arr = [1,2,3,"a","b","c",true,false,1.1,2.2,3.3];
    for(var i=0; i<arr.length; i++){
        console.log(arr[i]);
    }
    
  • 增强 for 循环

    • for-in 格式:获取的是数组的索引

      for(let i in 数组){		  // 使用变量i接收数组的索引值。i是变量名,可自定义
      	let 变量名 = 数组[i]);	// 获取数组元素并赋值给变量
      }
      
      // 示例:
      var arr = [1, 2, 3];
      for(let i in arr){
      	console.log(arr[i]);	// 打印数组元素
      }
      
    • for-of 格式:获取的是数组中的元素

      for(let 变量名 of 数组){
      	console.log(变量名);
      }
      
      // 示例:
      var arr = [1, 2, 3];
      for(let v in arr){
      	console.log(v);
      }
      

    注:也可以用 var 定义变量,但是推荐使用 let,因为 var 定义的是全局变量,let 定义的是局部变量

终止循环:break、continue、return

  • break 语句:立即跳出整个循环(即终止循环)

  • continue 语句:立即跳出本次循环,然后开始循环的一次新迭代

  • return 语句:用于终止函数的执行并指定函数返回的值。return 语句只能出现在函数体内

    在函数体内的循环中使用 return 语句,终止了整个函数的执行,当然也就终止了函数体内的循环

js 的函数

  • JavaScript 使用关键字 function 定义函数。

    函数可以通过声明定义,也可以是一个表达式(匿名函数)

  • 声明定义函数

    定义格式:

    function 函数名(参数列表){
        函数体;
        return 返回值;
    }
    

    注意:

    • 函数是没有返回值类型的,在函数中写 return 就有返回值,不写 return 没有返回值

    • 只写 return ,不写具体的返回值,则 return 的作用就是结束函数

    • 函数的参数列表,不能写数据类型,直接写变量名即可

      (var a, var b) 	// 错误  
      (a,b)			// 正确
      

    使用格式:

    // 有返回值的函数:
    var 变量 = 函数名(参数);
    // 没有返回值的函数:
    函数名(参数);
    
  • 匿名函数:没有名字的函数

    定义格式

    function (参数列表){
        函数体;
        return 返回值;
    }
    

    使用格式

    • 可以把匿名函数赋值给一个变量,变量名就相当于是函数的名字,通过变量名就可以调用函数
    • 在 js 中有一些函数的参数需要传递其他的函数,就可以使用匿名函数传递(例如:定时器)

js 的事件

事件概述

js 的事件是 js 不可或缺的组成部分。

几个概念:

  • 事件源:被监听的 html 元素
  • 事件:某类动作,例如点击事件,移入移出事件,敲击键盘事件等
  • 事件与事件源的绑定:在事件源上注册上某事件
  • 事件触发后的响应行为:事件触发后需要执行的代码,一般使用函数进行封装

常用的事件

事件名 描述
onload 某个页面或图像被完成加载
onreset 重置按钮被点击
onsubmit 提交按钮被点击(注意:事件源是表单 form)
onchange 用户改变域中内容
onclick 鼠标点击某个对象
ondblclick 鼠标双击某个对象
onblur 元素失去焦点
onfocus 元素获得焦点
onchange 用户改变域的内容
onmouseover 鼠标移入(鼠标被移到某元素之上)
onmouseout 鼠标移出(鼠标从某元素移开)
onmousemove 鼠标移动
onmousedown 某个鼠标按键被按下
onmouseup 某个鼠标按键被松开
onkeydown 某个键盘的键被按下
onkeypress 某个键盘的键被按下或按住
onkeyup 某个键盘的键被松开
onselect 文本被选定
onerror 当加载图像时发生错误

事件的基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js中的事件</title>
    <script>
        //定义按钮发生鼠标点击事件的响应函数
        function butOnclick() {
            //事件的处理逻辑
            alert("就点你咋地!");
        }

        //定义图片鼠标移入事件的响应函数
        function imgOnmouseover() {
            alert("鬼子又来抢花姑娘了!");
        }

        //定义文本框修改域内容事件的响应函数
        function textOnchange() {
            alert("haha");
        }
    </script>
</head>
<body>
    <!--
        按钮发生了点击事件
        事件源: <input type="button"/> 按钮
        事件: 鼠标点击事件 onclick
        把事件和事件源绑定到一起: 在按钮标签上,添加一个onclick属性,属性值调用一个函数
        事件触发之后的响应行为: 定义一个函数,在函数中处理按钮的鼠标点击事件
    -->
    <input type="button" value="没事别点我" onclick="butOnclick()"/>

    <!--
        鼠标移入事件
        事件源: dev标签
        事件: 鼠标移入事件 onmouseover
        把事件和事件源绑定到一起: 在标签上,添加一个onmouseover属性,属性值调用一个函数
        事件触发之后的响应行为: 定义一个函数,在函数中处理图片鼠标移入事件
    -->
    <dev width="150px" height="200px" style="border-style:solid" onmouseover="imgOnmouseover()">
	鼠标移入就弹窗
	</dev>

    <!--
        文本框改变域内容事件
        事件源: 文本框 <input type="text"/>
        事件: 改变域内容事件 onchange
        把事件和事件源绑定到一起: 在文本框上,添加一个onfocus属性,属性值调用一个函数
        事件触发之后的响应行为: 定义一个函数,在函数中处理文本框获取焦点事件
    -->
    <input typeof="text" placeholder="请输入你想输入的内容" onchange="textOnchange()"/>
</body>
</html>

页面加载事件(onload)

onload 事件会在页面或图像加载完成后立即发生。

onload 通常用于 <body> 元素,在页面完全载入后(包括图片、css文件等等。)执行脚本代码。

语法(实际使用中,以下两种方式二选一):

  • 在 HTML 中:在 body 标签绑定事件 onload ,并指定响应函数

    <body onload="SomeJavaScriptCode()">
    
  • 在 JavaScript 中

    window.onload=function(){*SomeJavaScriptCode*};
    

版权声明:本文为博主作者:墨鸦_Cormorant原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/footless_bird/article/details/136800119

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2024年4月1日
下一篇 2024年4月1日

相关推荐