JavaScript学习笔记分享 (1)

admin 2024年10月31日13:01:46评论12 views字数 10362阅读34分32秒阅读模式

0x01 JavaScript是什么?JavaScript简介

JavaScript 与 HTML 和 CSS 共同构成了我们所看到的网页,其中:

  • JavaScript 用来实时更新网页中的内容,例如从服务器获取数据并更新到网页中,修改某些标签的样式或其中的内容等,可以让网页更加生动。

    JavaScript 的特点

    JavaScript 具有以下特点:

    1) 解释型脚本语言

    JavaScript 是一种解释型脚本语言,与 C、C++ 等语言需要先编译再运行不同,使用 JavaScript 编写的代码不需要编译,可以直接运行。

    2) 面向对象

    JavaScript 是一种面向对象语言,使用 JavaScript 不仅可以创建对象,也能操作使用已有的对象。

    3) 弱类型

    JavaScript 是一种弱类型的编程语言,对使用的数据类型没有严格的要求,例如您可以将一个变量初始化为任意类型,也可以随时改变这个变量的类型。

    4) 动态性

    JavaScript 是一种采用事件驱动的脚本语言,它不需要借助 Web 服务器就可以对用户的输入做出响应,例如我们在访问一个网页时,通过鼠标在网页中进行点击或滚动窗口时,通过 JavaScript 可以直接对这些事件做出响应。

    5) 跨平台

    JavaScript 不依赖操作系统,在浏览器中就可以运行。因此一个 JavaScript 脚本在编写完成后可以在任意系统上运行,只需要系统上的浏览器支持 JavaScript 即可。

0x02 Node.js是什么?Node.js简介

对于 JavaScript 来说,它在运行期间需要依赖以下组件:

1) 解释器

JavaScript 是一种脚本语言,需要一边解释一边运行,用到哪些源代码就编译哪些源代码,整个过程由解释器完成。没有解释器的话,JavaScript 只是一堆纯文本文件,不能被计算机识别。

2) 标准库

我们在 JavaScript 代码中会调用一些内置函数,这些函数不是我们自己编写的,而是标准库自带的。

3) 本地模块

所谓本地模块,就是已经被提前编译好的模块,它们是二进制文件,和可执行文件在内部结构上没有什么区别,只是不能单独运行而已。这些本地模块其实就是动态链接库(在 Windows 下是 .dll 文件),如果你使用过C语言、C++ 等编译型语言,那你应该能够更好地理解它。

Node.js 的组成

Node.js 运行时主要由 V8 引擎、标准库和本地模块组成,尤其是本地模块的多少,从底层决定了 Node.js 功能的强弱。

1) V8 引擎

V8 引擎就是 JavaScript 解释器,它负责解析和执行 JavaScript 代码。

V8 引擎借鉴了 Java 虚拟机和 C++ 编译器的众多技术,它将 JavaScript 代码直接编译成原生机器码,并且使用了缓存机制来提高性能,这使得 JavaScript 的运行速度可以媲美二进制程序。

2) 本地模块

Node.js 集成了众多高性能的开源库,它们使用 C/C++ 语言实现,比如:

模块 说明
libuv 一个跨平台的、基于事件驱动的异步 I/O 库。但是 libuv 不仅限于 I/O,它还提供了进程管理、线程池、信号处理、定时器等其它功能。Linux 中一切皆文件,这里的 I/O 不仅仅包括文件读写,还包括数据库读写、网络通信(socket)等。
nmp Node.js 包管理器,可以下载包、安装包、卸载包、更新包、上传包等。
http_parser 一款由C语言编写的轻量级 HTTP 解析器,用以支持 Web 应用开发。
zlib 工业级的数据压缩/解压模块,Nodejs 借助 zlib 来创建同步、异步或者流式的压缩/解压接口。
OpenSSL 该模块提供了经过严密测试的许多加密/解密功能,现代 Web 依赖这些功能来实现安全性,比如 SSL 协议和 https 协议。
c-ares 异步 DNS 查询和解析库。

Node.js 直接在计算机上运行 JavaScript 代码,并且要赋予 JavaScript 强大的能力,所以它的本地模块和浏览器中的运行时有很多大区别,甚至说几乎没有什么关联。Node.js 几乎完全抛弃了浏览器,自己从头构建了一套全新的 JavaScript 运行时。

3) 标准库

本地模块使用 C/C++ 编写,而 Node.js 面向 JavaScript 开发人员,所以必须要封装本地模块的 C/C++ 接口,提供一套优雅的 JavaScript 接口给开发人员,并且要保持接口在不同平台(操作系统)上的一致性。

这套 JavaScript 接口,就是 Node.js 标准库。标准库是否优雅和强大,决定了 Node.js 的易用性,直接影响 Node.js 的市场表现。

最后我们来汇总一下 JavaScript 和 Node.js 的历史:

  • Netscape 浏览器衍生出了 JavaScript 脚本,赋予网页编程能力;

  • Chrome 浏览器衍生了 V8 引擎,提高了 JavaScript 性能;

  • V8 引擎构建了 Node.js,拓展了 JavaScript 的编程能力;

  • Node.js 衍生了 Libuv 库,给网络开发增加了一款优秀的工具。

3、第一个JavaScript程序

在 HTML 文档中嵌入 JavaScript 代码

<script> 标签内输入 JavaScript 代码document.write("船山院士网络安全团队");

type="text/javascript"是将<script>标签的脚本类型设置为javascript

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>第一个JavaScript程序</title>
   <script type="text/javascript">
       document.write("<h1>船山院士网络安全团队</h1>");
   </script>
</head>
<body></body>
</html>

在 JavaScript 脚本中,document 表示网页文档对象;document.write() 表示调用 Document 对象的 write() 方法,在当前网页源代码中写入 HTML 字符串"船山院士网络安全团队"

在脚本文件中编写 JavaScript 代码

打开 test.js 文件,在其中编写如下 JavaScript 代码。

alert("船山院士网络安全团队");

在上面代码中,alert() 表示 Window 对象的方法,调用该方法将弹出一个提示对话框,显示参数字符串 "Hi, JavaScript!"。

js不能独立运行需要导入到网页中通过浏览器来运行所以通过<script>来实现

<script type="text/javascript" src="test.js"></script>

src来指向外部属性

JavaScript 代码执行顺序

浏览器在解析 HTML 文档时,将根据文档流从上到下逐行解析和显示。JavaScript 代码也是 HTML 文档的组成部分,因此 JavaScript 脚本的执行顺序也是根据 <script> 标签的位置来确定的。

如果想改变 JavaScript 文件的执行顺序,可以给 <script> 标签增加 defer 或者 async 属性

<script async src="example.js"></script>

script添加async属性,表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行。执行会阻塞HTML解析。ps:和js脚本的执行是并行进行,我不太理解。

<script defer src="example.js"></script>

script添加defer属性,加载后续文档的过程和js脚本的加载是并行进行的,此时的js脚本仅加载不执行,js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前。

4、JavaScript中的几个重要概念

1. 标识符

所谓标识符(Identifier),就是名字。JavaScript 中的标识符包括变量名、函数名、参数名、属性名、类名等。

合法的标识符应该注意以下强制规则:

  • 第一个字符必须是字母、下划线(_)或美元符号($)。

  • 除了第一个字符外,其他位置可以使用 Unicode 字符。一般建议仅使用 ASCII 编码的字母,不建议使用双字节的字符。

  • 不能与 JavaScript 关键字、保留字重名。

  • 可以使用 Unicode 转义序列。例如,字符 a 可以使用“u0061”表示。

示例

在下面示例中,str 就是变量的名字:。

var str = "船山院士网络安全团队";
document.write(str);

第1行代码定义了一个变量,名字为 str,第2行通过 str 这个名字使用了变量。

2. 关键字

关键字(Keyword)就是 JavaScript 语言内部使用的一组名字(或称为命令)。这些名字具有特定的用途,用户不能自定义同名的标识符,具体说明如表所示。

break delete if this while
case do in throw with
catch else instanceof try
continue finally new typeof
debugger(ECMAScript 5 新增) for return var
default function switch void

3. 保留字

保留字就是 JavaScript 语言内部预备使用的一组名字(或称为命令)。这些名字目前还没有具体的用途,是为 JavaScript 升级版本预留备用的,建议用户不要使用。具体说明如表所示。

abstract double goto native static
boolean enum implements package super
byte export import private synchronized
char extends int protected throws
class final interface public transient
const float long short volatile

ECMAScript 3 将 Java 所有关键字都列为保留字,而 ECMAScript 5 规定较为灵活,例如:

  • 在非严格模式下,仅规定 class、const、enums、export、extends、import、super 为保留字,其他 ECMAScript 3 保留字可以自由使用;

  • 在严格模式下,ECMAScript 5 变得更加谨慎,严格限制 implements、interface、let、package、private、protected、public、static、yield、eval(非保留字)、arguments(非保留字)的使用。

JavaScript 预定义了很多全局变量和函数,用户也应该避免使用它们,具体说明如表所示。

arguments encodeURL Infinity Number RegExp
Array encodeURLComponent isFinite Object String
Boolean Error isNaN parseFloat SyntaxError
Date eval JSON parseInt TypeError
decodeURL EvalError Math RangeError undefined
decodeURLComponent Function NaN ReferenceError URLError

不同的 JavaScript 运行环境都会预定义一些全局变量和函数,上表列出的仅针对 Web 浏览器运行环境。

无论是在严格模式下还是在非严格模式下,都不要在定义变量名、函数名或者属性名时使用上面列举出的保留字,以免大家入坑。

4. 区分大小写

JavaScript 严格区分大小写,所以 Hello 和 hello 是两个不同的标识符。

为了避免输入混乱和语法错误,建议采用小写字符编写代码,在以下特殊情况下可以使用大写形式:

1) 构造函数的首字母建议大写。构造函数不同于普通函数。

示例

下面示例调用预定义的构造函数 Date(),创建一个时间对象,然后把时间对象转换为字符串显示出来。

  d = new Date();  //获取当前日期和时间
document.write(d.toString()); // 显示日期

2) 如果标识符由多个单词组成,可以考虑使用骆驼命名法——除首个单词外,后面单词的首字母大写。例如:

typeOf();
printEmployeePaychecks();

提示:

上述都是约定俗成的一般习惯,不构成强制性要求,用户可以根据个人习惯进行命名。

5. 直接量

字面量(Literal)也叫直接量,就是具体的值,即能够直接参与运算或显示的值,如字符串、数值、布尔值、正则表达式、对象直接量、数组直接量、函数直接量等。

示例

下面示例分别定义不同类型的直接量:字符串、数值、布尔值、正则表达式、特殊值、对象、数组和函数。

//空字符串直接量
1 //数值直接量
true //布尔值直接量
/a/g //正则表达式直接量
null //特殊值直接量
{} //空对象直接量
[] //空数组直接量
function(){} //空函数直接量,也就是函数表达式

5、JS注释(多行注释+单行注释)

单行注释://

多行注释:/*  */

HTML注释:<!--   -->

6、JS变量定义和赋值

1、定义变量

在 JavaScript 中,定义变量需要使用var关键字,语法格式如下:

var 变量名;

举几个例子:

var str;  //用来存储字符串
var age; //用来存储年龄
var prePage; //用来存储上一页

定义变量时,可以一次定义一个或多个变量,若定义多个变量,则需要在变量名之间使用逗号,分隔开,如下例所示:

var a, b, c;  // 同时声明多个变量

变量定义后,如果没有为变量赋值,那么这些变量会被赋予一个初始值——undefined(未定义)。

2、 为变量赋值

变量定义后,可以使用等于号=来为变量赋值,等号左边的为变量的名称,等号右边为要赋予变量的值,如下例所示:

var num;    // 定义一个变量 num
num = 1;   // 将变量 num 赋值为 1

此外,也可以在定义变量的同时为变量赋值,如下例所示:

var num = 1;                // 定义一个变量 num 并将其赋值为 1
var a = 2, b = 3, c = 4;   // 同时定义 a、b、c 三个变量并分别赋值为 2、3、4
// var a = 2,               // 为了让代码看起来更工整,上一行代码也可以写成这样
//     b = 3,
//     c = 4;      

3、 变量提升

JavaScript 在预编译期会先预处理声明的变量,但是变量的赋值操作发生在 JavaScript 执行期,而不是预编译期。

document.write(str); //显示undefined
str = http://c.biancheng.net/js/;
document.write(str); //显示 http://c.biancheng.net/js/
var str;

在上面示例中,声明变量放在最后,赋值操作放在前面。由于 JavaScript 在预编译期已经对变量声明语句进行了预解析,所以第1行代码读取变量值时不会抛出异常,而是返回未初始化的值 undefined。第3行代码是在赋值操作之后读取,故显示为数字 1。

JavaScript 引擎的解析方式是:先解析代码,获取所有被声明的变量,然后再一行一行地运行。这样,所有声明的变量都会被提升到代码的头部,这就叫作变量提升(Hoisting)。

4、 let 和 const 关键字

2015 年以前,JavaScript 只能通过 var 关键字来声明变量,在 ECMAScript6(ES6)发布之后,新增了 let 和 const 两个关键字来声明变量,其中:

  • 使用 let 关键字声明的变量只在其所在的代码块中有效(类似于局部变量),并且在这个代码块中,同名的变量不能重复声明;

  • const 关键字的功能和 let 相同,但使用 const 关键字声明的变量还具备另外一个特点,那就是 const 关键字定义的变量,一旦定义,就不能修改(即使用 const 关键字定义的为常量)。

注意:IE10 及以下的版本不支持 let 和 const 关键字。

示例代码如下:

let name = "小明";      // 声明一个变量 name 并赋值为“小明”
let age = 11;         // 声明一个变量 age
let age = 13;         // 报错:变量 age 不能重复定义
const PI = 3.1415       // 声明一个常量 PI,并赋值为 3.1415
console.log(PI)         // 在控制台打印 PI

7、JS数据类型(基本数据类型+引用类型)

JavaScript 中的数据类型可以分为两种类型:

  • 基本数据类型(值类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol;

  • 引用数据类型:对象(Object)、数组(Array)、函数(Function)。

提示:Symbol 是 ECMAScript6 中引入的一种新的数据类型,表示独一无二的值。

typeof 操作符

在开始介绍各种数据类型之前,先来了解一下 typeof 操作符,使用 typeof 操作符可以返回变量的数据类型。

typeof 操作符有带括号和不带括号两种用法,如下例所示:

typeof x;       // 获取变量 x 的数据类型typeof(x);      // 获取变量 x 的数据类型

1. JS 基本数据类型

1) String 类型

字符串(String)类型是一段以单引号''或双引号""包裹起来的文本,例如 '123'、"abc"。需要注意的是,单引号和双引号是定义字符串的不同方式,并不是字符串的一部分。

定义字符串时,如果字符串中包含引号,可以使用反斜杠来转义字符串中的引号,或者选择与字符串中不同的引号来定义字符串,如下例所示:

var str = "Let's have a cup of coffee.";  // 双引号中包含单引号
var str = 'He said "Hello" and left.';   // 单引号中包含双引号
var str = 'We'll never give up.';       // 使用反斜杠转义字符串中的单引号

2) Number 类型

数值(Number)类型用来定义数值,JavaScript 中不区分整数和小数(浮点数),统一使用 Number 类型表示,如下例所示:

var num1 = 123;     // 整数var
num2 = 3.14;   // 浮点数

注意:Number 类型所能定义的数值并不是无限的,JavaScript 中的 Number 类型只能表示 -(253 - 1) 到 (253 -1) 之间的数值。

对于一些极大或者极小的数,也可以通过科学(指数)计数法来表示,如下例所示:

var y=123e5;      // 123 乘以 10 的 5 次方,即 12300000
var z=123e-5;     // 123 乘以 10 的 -5 次方,即 0.00123

另外,Number 类型中还有一些比较特殊的值,分别为 Infinity、-Infinity 和 NaN,其中

  • Infinity:用来表示正无穷大的数值,一般指大于 1.7976931348623157e+308 的数;

  • -Infinity:用来表示负无穷大的数值,一般指小于 5e-324 的数;

  • NaN:即非数值(Not a Number 的缩写),用来表示无效或未定义的数学运算结构,例如 0 除以 0。

提示:如果某次计算的结果超出了 JavaScript 中 Number 类型的取值范围,那么这个数就会自动转化为无穷大,正数为 Infinity,负数为 -Infinity。

3) Boolean 类型

布尔(Boolean)类型只有两个值,true(真)或者 false(假),在做条件判断时使用的比较多,您除了可以直接使用 true 或 false 来定义布尔类型的变量外,还可以通过一些表达式来得到布尔类型的值,例如:

var a = true;   // 定义一个布尔值 true
var b = false; // 定义一个布尔值 false
var c = 2 > 1; // 表达式 2 > 1 成立,其结果为“真(true)”,所以 c 的值为布尔类型的 true
var d = 2 < 1; // 表达式 2 < 1 不成立,其结果为“假(false)”,所以 c 的值为布尔类型的 false

4) Null 类型

Null 是一个只有一个值的特殊数据类型,表示一个“空”值,即不存在任何值,什么都没有,用来定义空对象指针。

使用 typeof 操作符来查看 Null 的类型,会发现 Null 的类型为 Object,说明 Null 其实使用属于 Object(对象)的一个特殊值。因此通过将变量赋值为 Null 我们可以创建一个空的对象。

5) Undefined 类型

Undefined 也是一个只有一个值的特殊数据类型,表示未定义。当我们声明一个变量但未给变量赋值时,这个变量的默认值就是 Undefined。例如:

var num;
console.log(num); // 输出 undefined

在使用 typeof 操作符查看未赋值的变量类型时,会发现它们的类型也是 undefined。对于未声明的变量,使用 typeof 操作符查看其类型会发现,未声明的变量也是 undefined,示例代码如下:

var message;
console.log(typeof message); // 输出 undefined
console.log(typeof name);     // 输出 undefined

6) Symbol 类型

Symbol 是 ECMAScript6 中引入的一种新的数据类型,表示独一无二的值,Symbol 类型的值需要使用 Symbol() 函数来生成,如下例所示:

var str = "123";
var sym1 = Symbol(str);
var sym2 = Symbol(str);
console.log(sym1);         // 输出 Symbol(123)
console.log(sym2);         // 输出 Symbol(123)
console.log(sym1 == sym2); // 输出 false :虽然 sym1 与 sym2 看起来是相同的,但实际上它们并不一样,根据 Symbol 类型的特点,sym1 和 sym2 都是独一无二的

2. JS 引用数据类型

1) Object 类型

JavaScript 中的对象(Object)类型是一组由键、值组成的无序集合,定义对象类型需要使用花括号{ },语法格式如下:

{name1: value1, name2: value2, name3: value3, ..., nameN: valueN}

其中 name1、name2、name3、...、nameN 为对象中的键,value1、value2、value3、...、valueN 为对应的值。

在 JavaScript 中,对象类型的键都是字符串类型的,值则可以是任意数据类型。要获取对象中的某个值,可以使用对象名.键的形式,如下例所示:

var person = {
  name: 'Bob',
  age: 20,
  tags: ['js', 'web', 'mobile'],
  city: 'Beijing',
  hasCar: true,
  zipcode: null
};
console.log(person.name);       // 输出 Bob
console.log(person.age);       // 输出 20

2) Array 类型

数组(Array)是一组按顺序排列的数据的集合,数组中的每个值都称为元素,而且数组中可以包含任意类型的数据。在 JavaScript 中定义数组需要使用方括号[ ],数组中的每个元素使用逗号进行分隔,例如:

[1, 2, 3, 'hello', true, null]

另外,也可以使用 Array() 函数来创建数组,如下例所示:

var arr = new Array(1, 2, 3, 4);
console.log(arr);       // 输出 [1, 2, 3, 4]

数组中的元素可以通过索引来访问。数组中的索引从 0 开始,并依次递增,也就是说数组第一个元素的索引为 0,第二个元素的索引为 1,第三个元素的索引为 2,以此类推。如下例所示:

var arr = [1, 2, 3.14, 'Hello', null, true];
console.log(arr[0]); // 输出索引为 0 的元素,即 1
console.log(arr[6]); // 输出索引为 5 的元素,即 true
console.log(arr[7]); // 索引超出了范围,返回 undefined

3) Function 类型

函数(Function)是一段具有特定功能的代码块,函数并不会自动运行,需要通过函数名调用才能运行,如下例所示:

function sayHello(name){
  return "Hello, " + name;
}
var res = sayHello("Peter");
console.log(res); // 输出 Hello, Peter

此外,函数还可以存储在变量、对象、数组中,而且函数还可以作为参数传递给其它函数,或则从其它函数返回,如下例所示:

var fun = function(){
  console.log("http://c.biancheng.net/js/");
}
function createGreeting(name){
  return "Hello, " + name;
}
function displayGreeting(greetingFunction, userName){
  return greetingFunction(userName);
}
var result = displayGreeting(createGreeting, "Peter");
console.log(result); // 输出 Hello, Peter

小结

在学习JavaScript过程中记录的一些小笔记,不足之处还望指正。在之后的日子里大家一起进步吧!

web渗透师徒班:昕之所嚮学习分享!

JavaScript学习笔记分享 (1)

原文始发于微信公众号(衡阳信安):JavaScript学习笔记分享 (1)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月31日13:01:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JavaScript学习笔记分享 (1)https://cn-sec.com/archives/1833443.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息