今天我们聊聊JavaScript的组成

468 阅读13分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

开篇介绍

主要由三部分组成,ECMAScriptDOMBOM。那这三者到底是什么东西呢?今天咋们就来说道说道啊!

ECMAScript

在JavsScript中啊,ECMAScript算得上是核心了。

注意

  1. 定义的仅仅是语言基础

    • 语法
    • 类型
    • 语句
    • 关键字
    • 保留字
    • 操作符
    • 对象
    • ...
  2. 宿主环境提供了该语言的基本实现和扩展

    • 比如DOM
  3. 与Web浏览器没有依赖关系

    • 浏览器只是ECMAScript实现的宿主环境之一
  4. 其他宿主环境

    • Node --- 服务器端的JavaScript平台
    • Adobe Flash

DOM

文档对象模型

功能

  1. 把整个页面映射成为一个多层节点结构

  2. 然后提供了一套对这些节点(内容)增删改查的方法

DOM级别

1. DOM1

  • DOM Core ---- 如何映射基于XML的文档结构

  • DOM HTML ---- 添加了针对HTML的对象和方法

2. DOM2

  1. 扩充了鼠标和用户界面事件, 范围,遍历等细分模块

  2. 通过对象接口增加了对CSS的支持

  3. 具体

    • DOM视图 ---- 定义了跟踪不同文档视图的接口
    • DOM事件 ---- 定义了事件和事件处理的接口
    • DOM样式 ---- 定义了基于CSS, 操作元素样式的接口
    • DOM遍历和范围 ---- 定义了遍历和操作文档树的接口,新增了验证文档的方法

3. DOM3

引入了以统一方式加载和保存文档的方法

注意

  1. 针对于XML但经过扩展,用于HTML的应用程序编程接口(API)

  2. 不只是针对于JavaScript的, 很多其他语言也实现了DOM

BOM

  • 浏览器对象模型

  • 作用

    处理浏览器窗口和框架

    习惯于把针对于浏览器操作的JS扩展也归为BOM

  • 具体功能

    1. 弹出新浏览器窗口的功能
    2. 移动,缩放和关闭浏览器窗口的功能
    3. 提供浏览器详细信息的navigator对象
    4. 提供浏览器所加载页面的详细信息的location对象
    5. 提供用户显示器分辨率详细信息的screen对象
    6. 对cookie的支持
    7. XMLHttpRequest -- ActiveXObject

大概的基础知识描述我们已经聊完了,接下来就是分类别的进一步说明。

01-ECMAScript-基本类型和复杂类型

基本(简单)数据类型

1. string 字符串类型

var str = 'This is an apple';

2. number 数值(小数和整数)

  1. 666 ---- 整数(10进制)
  2. 1.1 ---- 浮点数(十进制)
  3. 010 ---- 八进制 0-7
  4. 0x10 ---- 十六进制 0-9 A-F
  5. NaN ---- 非数值(一个特殊的数值)涉及NaN的操作,都会返回NaN,NaN与任何值都不相等, 包括自身
  6. isNaN() ---- 判断是否是数值,会尝试把参数转换为数值

3. boolean 布尔类型(true |false)

var flag = true;
var isOpen = false;

4. null 空

var timer = null;

5. undefined 未定义

用于存放 JavaScript 中未定义的值

<script>
var t1="";
var t2;

if (t1===undefined){
    alert("t1 is undefined");
}
if (t2===undefined){
    alert("t2 is undefined");
}
</script>

以上实例输出结果: t2 is undefined

复杂(复合)数据类型

Object 对象类型

对象也是一个变量,但对象可以包含多个值(多个变量),每个值以 name:value 对呈现。

var car = {name:"五菱", model:500, color:"white"};

Array 数组类型 ==>object

Array 对象用于在变量中存储多个值

var cars = ["大众""奔驰""BMW"];

Date 日期类型 ==>object

Date 对象用于处理日期与时间。

创建 Date 对象: new Date()

以下四种方法同样可以创建 Date 对象:

var d = new Date();
var d = new Date(milliseconds);
var d = new Date(dateString);
var d = new Date(year, month, day, hours, minutes, seconds, milliseconds);

Math 类型 ==>object

Math 对象用于执行数学任务。

Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math()。

var x = Math.PI; // 返回PI
var y = Math.sqrt(16); // 返回16的平方根
var num = Math.random(); // 返回介于 0(包含)~ 1(不包含) 之间的一个随机数

Function 函数 ==>function(并非是object)

function 语句用于声明一个函数。

function myFunction() { // 声明一个函数
   console.log('函数被执行了');
}

myFunction(); // 调用函数

RegExp 正则表达式

1. RegExp

对象用于存储检索规则

2. test()

test() 方法检索字符串中的指定值。返回值是 true 或 false。

3. exec()

exec() 方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null。

4. compile()

既可以改变检索规则,也可以添加或删除第二个参数

5. 创建方式

1、字面量语法 ---- /pattern/attributes

2、创建 RegExp 对象的语法

new RegExp(pattern, attributes);
  • 参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
  • 参数 attributes 是一个可选的字符串,包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。
  • 如果 pattern 是正则表达式,而不是字符串,则必须省略该参数

5. 实战

1、把一个字符串中所有的英文,都给删除

制定英文匹配规则:一个或者多个英文字母

[A-Za-z]+  或者 [A-z]+
var reg1 = 'abc123';
var res = reg1.replace(/[A-Za-z]+/g, ''); // 匹配成功替换成空
console.log(res); // 123 

2、验证一个字符串是否是电话号码

指定电话号码匹配规则

首位1, 次位358, 其余9位纯数字
reg = /^[1][358][0-9]{9}$/;

3、检索出一个字符串中的电话号码

var reg = /[1][358][0-9]{9}/g;

调用方法

do {
    var result = reg.exec(str);
    console.log(result);
}while (result != null);

String 字符串对象类型

String 对象用于处理文本(字符串)。

String 对象创建方法: new String()

var txt = new String("*string*");

或者更简单方式:

var txt = "*string*";

Number

Number 对象是原始数值的包装对象。

Number 创建方式 new Number()

var num = new Number(1); // Number {1}

Boolean

Boolean 对象用于转换一个不是 Boolean 类型的值转换为 Boolean 类型值 (true 或者false)

var b1=new Boolean(0); // false
var b2=new Boolean(1); // true
var b3=new Boolean(""); // false
var b4=new Boolean(null); // false
var b5=new Boolean(NaN); // false
var b6=new Boolean("false"); // true

区别

存储方式不同

堆区和栈区

1、栈区特点

  • 操作性能高, 速度快
  • 存储量小
  • 所以: 一般存储操作频率较高, 生命周期较短, 占用空间较小的数据; 又或者基本数据类型。

2、堆区特点

  • 操作性能低, 速度慢
  • 存储量大
  • 所以: 一般存储操作频率较低, 生命周期比较长, 占用空间比较大的数据; 又或者复杂数据类型(对象)。

操作方式不同

1、划分

值类型

  • string
  • number
  • boolean
  • undefined
  • null(*) 引用类型
  • Object类型,以下类型其本质都是object类型
  • Function
  • Array
  • Date
  • String
  • Number
  • Boolean

2、值&引用

赋值

  • 值类型赋值
  • 引用类型赋值 传递
  • 函数中的参数传递

02-ECMAScript-类型获取和判断

获取数据类型

使用关键字typeof,其返回值是string类型

typeof 字符串   // string
typeof 10      // number
typeof null    // object
typeof undefined // undefined

判断数据类型

方法1

适用于基本数据类型

语法:typeof value == 'type'

function test(){} 
console.log(typeof 1); // number 
console.log(typeof test); // function 
console.log(typeof "apple"); // string 
console.log(typeof undefined); // undefined

方法2

简单理解:判断一个实例是否是某一个类型,只适用于复杂数据类型,该检测会返回一个布尔型(boolean),

语法: value instanceof type

// 复杂数据类型
console.log([] instanceof Array); // true
// 基本数据类型
console.log(123 instanceof number); // 报错 Uncaught ReferenceError: number is not defined

补充

1、null和undefined的区别

  • null表示"没有对象",即该处不应该有值。

    (1)表达是一个对象,但是没有存放任何引用

    (2)可以手动赋值, 一般在准备将一个变量赋值为一个对象之前, 先赋值为null 或者想要释放一个对象的时候

  • undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。

    (1)不需要手动的赋值此值

2、可以使用typeof 判断一个变量是否未定义或者未声明

typeof name  // undefined

if (name) { } // 这种判断是否可行?

03-ECMAScript-=和==和===说明

=

  • 赋值操作
  • 表达式的返回值就是赋值的数值
  • 对条件表达式写法的影响,比如 if (值 == 变量) { }

==

  • 基本数据类型之间

    判断两个变量 是否相等

  • 对象之间

    判断内存地址是否相等

  • 基本类型和对象之间

    则会将对象转换为基本数据类型数值进行比对

===

  • 基本数据类型之间

    判断两个变量 是否相等 且比对类型

  • 对象之间

    判断内存地址是否相等

  • 基本类型和对象之间

    则会将对象转换为基本数据类型数值进行比对 且比对类型

04-ECMAScript-关系运算符

m1.png

05-ECMAScript-逻辑运算符

m2.png

06-ECMAScript-分支和循环

m3.png

07-ECMAScript-函数

函数的几种创建方式

1、声明函数

function 函数名称 (形参1,形参2)
{
    //函数体
}

2、函数表达式

// 匿名函数
var func01 = function (){

};

// 命名的函数表达式
var func02 = function func(){

};

3、使用构造函数创建函数对象

var func02 = new Function("console.log('demo');");
func02();

/*
可以传递N个参数
	会把最后一个参数, 当做函数体;
	其他参数当做函数形参
*/

函数的使用技巧

1、形参和arguments

该参数是一个类似于数组的结构(可以像数组一样遍历 + 还可以使用下标来访问数据),但是并不是数组。

  1. 函数调用的时候,会把实参的值赋值给形参,而且会使用arguments来接收实参
  2. 如果实参的个数超过形参的个数,那么可以通过arguments来获取超出的数据
  3. 如果实参的格式小于形参的个数,那么不足的全部设置为undefined 两者之间是关联的关系
function func1(a, b, c) {
  console.log(arguments[0]);
  // expected output: 1

  console.log(arguments[1]);
  // expected output: 2

  console.log(arguments[2]);
  // expected output: 3
  
  console.log(arguments);
}

func1(1, 2, 3);

c1.png

2、属性

  • length属性 ---- 函数名.length;形参的长度(个数)
  • name属性 ---- 函数名称 c2.png

函数重载

概念

函数名相同, 但是根据传递的参数不同可以实现不同的功能

例如

  • function sum(a, b)
  • function sum(a, b, c)
  • 可以同时存在 但是:

js没有函数重载! 但是可以通过arguments个数来模拟重载

函数的几种叫法

1、函数

分为命名函数匿名函数

2、闭包

可以访问其他函数内部变量的函数

  • 由函数内部返回给外界的函数
    
  • 由外界传递到函数内部的函数
    

3、方法

  • 有宿主

      静态方法
      实例方法
    
  • 需要通过宿主来调用

08-ECMAScript-作用域问题

概念: 某个变量有(起)作用的范围

1. js中的作用域

  • script标签构成的全局作用域

  • 块级作用域

      在其他语言中, 由{}包含的代码块都有自己的作用域
      在其他语言中,有块级作用域,但是在js中没有块级作用域(这里不涉及到ES6)
    
  • 在js中函数是唯一一个可以创建作用域的对象

      注意: 如果没有通过var关键字声明变量, 则为全局变量
    

2. 作用域链

  • js中函数可以创建作用域

  • js中的函数中可以声明函数

  • 函数内部的函数中又可以声明函数

  • 以上,会形成一个链式的结构,这个是作用域链 3. 变量查找原则

  • 就近原则

  • 从内到外

09-ECMAScript-变量和函数提升

js的执行

  1. 预解析阶段 变量和函数的提升(声明)
  2. 具体的执行阶段

规则

0-会把变量的声明提升到当前作用域的最前面

赋值放在原位置不动

1-会把函数声明提升到当前作用域前面

紧接着被提升过的其他声明

注意

1、函数的声明包含了函数体;

2、如果是函数的表达式,只会把var变量的名称(函数)提升到当前作用域的最顶端

特例写法

不要这样写!!! 使用函数表达式的形式修正

if (condition) {
    function a() {alert('1')};
}else {
    function a() {alert('2')};
}

测试

function foo() {
    var num = 123;
    console.log(num); // 123
}

foo(); 
console.log(num); // num is not defined

2-变量和变量同名的情况

后面的变量会把前面的变量覆盖

测试

var scope = "global";
foo();

function foo() {
    console.log(scope); // undefined
    var scope = "local"; // local
    console.log(scope);
}

console.log(scope); // global

3-函数和函数同名的情况

后面的会把前面的覆盖

测试

结合前面第一点第二点就会发现foo函数输出的是第二点中foo函数的内容(undefinedlocal)

4-函数和变量同名的情况

变量的声明不会覆盖函数的声明

5-变量提升无法脱离所在作用域

测试

var foo = 1;
function bar() {

    if(!foo){
        var foo = 10;
    }
    alert(foo);  // 10  而不是弹出1
}

bar();

10-ECMAScript-异常处理

场景

正常情况下,如果程序出现了错误或者是异常,那么该行代码后面的所有代码都无法得到执行

但是,有些时候我们需要保证即便程序出现了问题,后面的代码也能够正常执行,这种情况就可以使用异常捕获结构

使用

抛出异常

throw 字符串/对象

捕捉异常

try{
    //可能出错的代码
}catch (e){
    //出错了就执行这个代码块
}
finally
{
    //不管是否出错,都会执行这里的代码块
    //一般在前端开发中不会使用,多多用于后端开发Node.js 主要用于在最后释放资源
}

11-DOM-操作(增删改查)

n3.png

12-BOM-操作

浏览器对象模型

作用

  • 处理浏览器窗口和框架
  • 习惯于把针对于浏览器操作的JS扩展也归为BOM

具体功能

  • 弹出新浏览器窗口的功能
  • 移动,缩放和关闭浏览器窗口的功能
  • 提供浏览器详细信息的navigator对象
  • 提供浏览器所加载页面的详细信息的location对象
  • 提供用户显示器分辨率详细信息的screen对象
  • 对cookie的支持
  • XMLHttpRequest -- ActiveXObject

重要对象

window

m4.png

m5.png

location

m6.png

navigator,screen,history

m7.png

结语

本篇文章的话总结的也不是很全,因为知识点真的太多太多了,所以有些部分是采取了贴图的方式。比如DOM操作那一部分,当然还有其他部分的,更多的还是需要自己去鼓捣鼓捣。

码字不易,如果觉得对你有帮助,觉得还不错的话,欢迎点赞收藏~

当然由于是个人整理,难免会出现纰漏,欢迎留言反馈。