JavaScript看这一篇就够了,简单全面一发入魂-程序员宅基地

技术标签: JavaScript与Vue基础教程系列  javascript  

一、什么是JavaScript

1、DOM

文档对象模型(DOM,Document Object Model)是一个应用编程接口(API),用于在HTML中使用扩展的HTML。DOM将整个页面抽象为一组分层节点。
DOM通过创建表示文档的树,让开发者可以随心所欲的控制网页的内容和结构。使用DOM API可以轻松地删除、添加、替换、修改节点。
对浏览器而言,DOM就是使用ECMAScript实现的,如今已经成为JavaScript语言的一大组成部分。
言而言之,DOM提供与网页内容交互的方法和接口。

2、BOM

IE3和Netscape Navigator3提供了浏览器对象模型(BOM)API,用于支持访问和操作浏览器的窗口。使用BOM,开发者可以操控浏览器显示页面之外的部分。
BOM的能力展示:

  1. 弹出新浏览器窗口的能力;
  2. 移动、缩放和关闭浏览器窗口的能力;
  3. navigator对象,提供关于浏览器的详尽信息;
  4. location对象,提供浏览器加载页面的详尽信息;
  5. screen对象,提供关于用户屏幕分辨率的详尽信息;
  6. performance对象,提供浏览器内存占用、导航行为和时间统计的详尽信息;
  7. 对cookie的支持;
  8. 其它自定义对象,如XMLHttpRequest和IE的ActiveXObject。
    简而言之,BOM提供与浏览器交互的方法和接口。

二、HTML中的JavaScript

1、script标签

<script>标签有8大属性,可以包含来自外部域的JavaScript文件,<script>的src属性可以是一个完整的URL,并且这个URL指向的资源可以跟包含它的HTML页面不在同一个域中,浏览器解析这个资源时,会想src属性指定的路径发送一个GET请求,以取得相应资源,这个初始的请求不受浏览器同源策略限制,但返回并被执行的JavaScript则受限制。当然,这个请求仍然受父页面HTTP/HTTPS协议的限制。

2、标签位置

过去,所有的<script>标签都放在head标签中,这就意味着所有JavaScript代码都要下载、解析和解释完成后,才能开始渲染页面(页面在浏览器解析到<body>标签的起始标签时开始渲染)。对于需要很多JavaScript的页面,会导致页面渲染的明显延迟,在此期间浏览器窗口完全空白。
为了解决这个问题,现代Web应用程序通常将所有JavaScript引用放在<body>元素中的页面内容后面。

3、延迟执行脚本

正常情况下,JavaScript的代码是书序执行的。
defer脚本会延迟到整个页面都解析完毕后再运行,只适用于外部脚步。
async脚本与defer脚本类似,都是只适用于外部脚本,但async脚本并不能保证按照它们出现的次序执行。

4、动态加载脚本

JavaScript可以通过向DOM中动态添加script元素同样可以加载指定的脚本,只要创建一个script元素并将其添加到DOM即可。

let script = document.createElement('script');
script.src = 'nezha.js';
document.head.appendChild(script);

默认情况下,以这种方式创建的<script>标签都以异步方式加载,相当于加了async标签。

5、将JavaScript代码独立于HTML的好处

  1. 可维护性
  2. 缓存。浏览器会根据特定的设置缓存所有外部链接的JavaScript文件,这意味着如果两个页面都用到同一个JavaScript文件,则该文件只需加载一次,这最终意味着页面加载更快。

三、语言基础

1、严格区分大小写

2、ECMAScript中的语句推荐以分号结尾

  1. 加分号有助于防止省略造成的问题
  2. 避免输入内容不完整
  3. 便于开发者通过删除空行来压缩代码(如果没有结尾的分号,只删除空行,则会导致语法错误)
  4. 加分号有助于提升性性能,因为解析器会尝试在合适的位置补上分号以纠正语法错误。

四、对比var与let、const

  1. let不具备声明提升,var具备声明提升
  2. let声明的范围是块作用域,而var声明的范围是函数作用域。
  3. let是ES6才引入的声明关键字
  4. for循环中的let声明
  5. const与let很相似,最大的区别是const必须初始化,且不能再次赋值。

结语:

  1. 不使用var,有了let和const,大多数开发者会发现自己不再需要var了,限制自己只使用let和const,有助于提升代码质量,因为变量有了明确的作用域、声明位置、以及不变的值。
  2. const优先,let次之。使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。

五、对象池管理

通过创建对象池管理一组可回收的对象,应用程序可以向这个对象池请求一个对象、设置其属性,使用他,然后
在操作完成后再把它交还给对象池,因为没有对象初始化,垃圾回收探测刽发现兑现更替,因此垃圾回收程序就不会频繁调用了。

let v1 = vectorPool.allocate();
let v2 = vectorPool.allocate();
let v3 = vectorPool.allocate();

v1.x = 10;
v1.y = 5;
v2.x = 11;
v2.y = 12;

addVector(v1,v2,v3);

vectorPool.free(v1);
vectorPool.free(v2);
vectorPool.free(v3);

由于数组是动态可变的,当创建一个大小为100的数组,使用时发现不够大,引擎会删除这个数组,然后创建一个新的,
垃圾回收程序会看到这个删除操作,然后很快的就来收一次垃圾,要避免这种动态分配操作。

六、变量、作用域、内存

JavaScript变量可以保存两种类型的值:原始值和引用值。

1、原始值6种数据类型

  1. Undefined
  2. Null
  3. Boolean
  4. Number
  5. String
  6. Symbol

2、原始值和引用值特点

  1. 原始值大小固定,保存在栈内存中
  2. 从一个变量到另一个变量复制原始值,会创建该值得第二个副本
  3. 引用值是对象,存储在堆内存中
  4. 包含引用值的变量实际上只包含指向相应对象的一个指针,而不是对象本身
  5. 从一个变量到另一个变量复制引用值,只会复制指针,因此结果是两个变量都指向同一个对象
  6. typeof操作费可以确定值的原始类型,instanceof操作符用于确保值得引用类型

3、执行上下文

任何变量都存在于某个执行上下文中(也称为作用域)。这个上下文(作用域)决定了变量的生命周期,以及它们可以访问代码的哪些部分。
执行上下文可以总结如下:

  1. 执行上下文分为 ① 全局上下文、② 函数上下文、③ 块级上下文
  2. 代码执行流每进入一个新上下文,都会创建一个作用域链,用于搜索变量和函数
  3. 函数或块的局部上下文不仅可以访问自己作用域内的变量,也可以访问任何包含上下文乃至全局上下文的变量
  4. 全局上下文只能访问全局上下文中的变量和函数,不能直接访问局部上下文中的任何数据
  5. 变量的执行上下文用于确定什么时候释放内存

4、JavaScript垃圾回收

JavaScript是使用垃圾回收的编程语言,开发者不需要操心内存分配和回收。

  1. 离开作用域的值会被自动标记为可回收,然后在垃圾回收期间被删除
  2. 主流的垃圾回收算法是标记算法,即先给当前不使用的值加上标记,再回来回收它们的内存
  3. 引用计数是另一种垃圾回收策略,需要记录值被引用了多少次。JavaScript引擎不再使用这种算法,但某些旧版本的IE仍然会受这种算法的影响,原因是JavaScript会访问非原生JavaScript对象(如DOM对象)。
  4. 引用计数在代码中循环引用时会出现问题
  5. 解除变量的引用不仅可以消除循环引用,而且对垃圾回收也有帮助。为促进内存回收,全局对象、全局对象的属性和循环引用都应该在不需要时解除引用。

七、map基础API

1、set()方法添加键值对

2、get()和has()进行查询

3、delete()和clear()进行删除

4、size获取map获取键值对数量

八、顺序与迭代

与Object的主要差异是,map实例会维护键值对的插入顺序,可以根据插入顺序执行迭代操作。
映射实例可以通过迭代器Iterator,能以插入顺序生成[key,value]形式的数组,可以通过entries()方法,或者Symbol.iterator属性,它引用entries()取得这个迭代器。

const map = new Map([
	["id","1"],
	["name","哪吒"],
	["age","18"]
]);

for(let x of map.entries()){
    
	alert(x);
}
//[id,1]
//[name,哪吒]
//[age,18]

for(let x of map[Symbol.iterator]()){
    
	alert(x);
}
//[id,1]
//[name,哪吒]
//[age,18]

map.foreach((val,key) => alert(`${
      key} -> ${
      val}`));
//id -> 1
//name -> 哪吒
//age -> 18

for(let key of map.keys()){
    

}

for(let v of map.values()){
    

}

九、Object和Map到底有什么区别?

1、内存占用

给定固定大小内存的情况下,Map一般会比Object多存储50%的键值对。

2、插入性能

插入Map一般会稍微快一点。

3、查找速度

相差无几。

4、删除性能

Map的删除性能完胜Object。
综上四点,选择Map显然是更好地选择。

十、Set

1、基础API

  1. 添加add()
  2. 查询has()
  3. 获取数量size
  4. 删除delete()
  5. 清空clear()

2、顺序与迭代

Set会维护值插入时的顺序,因此支持按顺序迭代。
集合实例可以提供一个迭代器Iterator,能以插入顺序生成集合内容。可以通过values()方法及其别名方法keys(),或者Symbol.iterator属性,他引用values(),取得这个迭代器。

const s = new Set("哪吒","云韵","比比东");

alert(s.keys === s[Symbol.iterator]);//true
alert(s.values === s[Symbol.iterator]);//true

for(let value of s.values()){
    

}

for(let value of s[Symbol.iterator]){
    

}

因为values()是默认迭代器,所以可以直接对集合实例使用扩展操作,把集合转为数组:

const s = new Set("哪吒","云韵","比比东");
console.log([...s]);//["哪吒","云韵","比比东"]

十一、什么是生成器

1、生成器简介

生成器是ECMAScript6新增的一个极为灵活的结构,拥有在一个函数块内暂停和恢复代码执行的能力。这种新能力具有较深远的影响,比如,使用生成器可以自定义迭代器和实现协程。
生成器的形式是一个函数,函数名称前面加一个星号*,表示它是一个生成器。只要是可以定义函数的地方,就可以定义生成器。
调用生成器函数会产生一个生成器对象,生成器对象一开始处于暂停执行(suspended)状态。与迭代器相似,生成器对象也实现了Iterator接口,因此具有next()方法。调用这个方法会让生成器开始或恢复执行。
next()方法的返回值类似于迭代器,有一个done属性和一个value属性。函数体为空的生成器函数中间不会停留,调用一次next()就会让生成器到达done:true状态。
value属性是生成器函数的返回值,默认值为undefined,可以通过生成器函数的返回值指定:

function * generatorFn(){
    
	return '哪吒编程'
}

生成器函数只会在初次调用next()方法之后开始执行。

2、通过yield中断执行

yield关键字可以让生成器停止和开始执行,也是生成器最有用的地方,生成器函数在遇到yield关键字之前会正常执行。遇到这个关键字之后,执行器会停止,函数作用域的状态会被保留。停止执行的生成器函数只能通过在生成器对象上调用next()方法来恢复执行。

  1. 生成器对象作为可迭代对象
  2. 使用yield实现输入和输出
  3. 产生可迭代对象
  4. 使用yield*实现递归算法

3、生成器作为默认迭代器

因为生成器对象实现了Iterable接口,而且生成器函数和默认迭代器被调用之后都产生迭代器,所以生成器格外适合作为默认迭代器。

4、提前终止生成器

1、使用return()终止生成器
2、使用throw()
throw()方法会在暂停的时候提供一个错误注入到生成器对象中。如果错误未被处理,生成器就会关闭。不过如果生成器函数内部处理了这个错误,生成器就不会关闭,还可以恢复执行。

5、生成器小结

迭代是一种所有编程语言中都可以看到的模式。ECMASCript正式支持迭代模式并引入两个新的语言特性:迭代器和生成器。
迭代器是一个可以由任意对象实现的接口,支持连续获取对象产出的每一个值。任何实现Iterable接口的对象都有一个Symbol.iterator属性,这个属性引用默认迭代器。默认迭代器就像一个迭代器工厂,也就是一个函数,调用之后会产生一个实现Iterator接口的对象。
迭代器必须通过连续调用next()方法才能连续获取值,这个方法返回一个IteratorObject。这个对象包含一个done属性和一个value属性。前者时刻一个布尔值,表示十分还有更多值可以访问;后者包含迭代器返回的当前值。这个接口可以通过手动反复调用next()方法来消费,也可以通过原生消费者,比如for循环来自动消费。
生成器是一种特殊的函数,调用之后会返回一个生成器对象。生成器对象实现了Iterable接口,因此可用在任何消费可迭代对象的地方。生成器的独特之处在于支持yield关键字,这个关键字能够暂停执行生成器函数。使用yield关键字还可以通过next()方法接收输入和产生输出。在加上星号之后,yield关键字可以将跟在后面的可迭代对象序列化为一连串值。

十二、原型链

ECMA-262把原型链定义为ECMAScript的主要继承方式。其基本思想就是通过原型继承多个引用类型的属性和方法。

1、构造函数、原型、实例三者的关系?

每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数,这样就在实例和原型之间构造了一条原型链。

2、盗用构造函数

为了解决原型链包含引用值导致的继承问题,引入了盗用构造函数的概念。基本思路很简单,在子类构造函数中调用父类构造函数,因为毕竟函数就是在特定上下文中执行代码的简单对象,所以可以使用apply()或call()方法,重新创建上下文执行构造函数。
相比于使用原型链,盗用构造函数的一个优点就是可以在子类构造函数中向父类构造函数传参。

3、组合继承

组合继承综合了原型链和盗用构造函数,将两者的优点集中了起来,基本的思路是使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性。这样既可以把方法定义在原型上以实现重用,又可以让每个实例都有自己的属性。
组合继承也保留了instanceof操作符和isPrototypeOf()方法识别合成对象的能力。

作者简介:哪吒,CSDN2021博客之星亚军、新星计划导师、博客专家

哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师

关注公众号【哪吒编程】,回复1024,获取Java学习路线思维导图、大厂面试真题、加入万粉计划交流群、一起学习进步


下一篇:JavaScript数组你都掰扯不明白,简历上你敢写精通JavaScript?

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/guorui_java/article/details/123263006

智能推荐

应用服务器安装手册_应用级服务器安装-程序员宅基地

文章浏览阅读431次。环境准备fdisk -l mkfs.ext4 /dev/vdb mount -t ext4 /dev/vdb /data yum update yum -y install gcc gcc-c++ autoconf automake libtool make openssl openssl-devel pcre-devel libxml2-devel libcurl-devel lib..._应用级服务器安装

利用xgboost进行多元时间序列预测_best_adab=space_eval(space,best)-程序员宅基地

文章浏览阅读9.3k次,点赞7次,收藏76次。利用2019年ccf的数据集进行测试(乘用车销量预测)主要思路进行划分出很多窗口,这里以1320*4条数据为一个窗口因为每个省都有60个车型,一共22个省,就是1320,预测未来4个月,所以用的4import pandas as pdtrain_sales = pd.read_csv('C:\\Train\\train_sales_data.csv',header=0)trai..._best_adab=space_eval(space,best)

thrift windows vs2015编译_windows下vs2015搭建thrift(c++)-程序员宅基地

文章浏览阅读3.6k次。1、首先从官网下载安装包https://thrift.apache.org/download 或者从Git地址中获取:https://github.com/apache/thrift 目前的最新版为thrift-0.9.3 2、解压后用vs2015打开里面的cpp lib 用vs2015打开此路径下的sln文件: thrift-master\lib\cpp 升级一下: ..._windows下vs2015搭建thrift(c++)

SwiftUI实现网格视图(GridView)_swiftui gridview-程序员宅基地

文章浏览阅读1.7k次。目录SwiftUI实现网格视图(GridView)HStack和VStack组合1. 准备工作2. 实现RowView3. 组合成网格4.效果图利用格子位置1. GridLayout2. GridView3. ContentView.swift4. 效果图参考资料SwiftUI实现网格视图(GridView)使用两种方法来实现网格视图,一种是利用HStack和VStack组合来实现,另一种利用格子位置来实现。HStack和VStack组合使用这种方法的步骤:首先实现行视图也就是RowView利_swiftui gridview

SDH、MSTP、OTN和PTN的关系-程序员宅基地

文章浏览阅读318次,点赞7次,收藏9次。SDH系统的电路调度均以TDM为基础,所以看到很多人说SDH业务就是TDM业务,就是传统的电路调度,是有理论依据的。但在SDH大红大紫的时候,另一场战争在以太网和ATM(不是取款机哟,是“异步传输模式”,一种以信元为基础的分组交换和复用技术)之间开打。在这场大战中,以太网取得全面胜利,从而大行其道。TDM,就是时分复用,就是将一个标准时长(1秒)分成若干段小的时间段(8000),每一个小时间段(1/8000=125us)传输一路信号。这样的话,SDH是一个大红人,以太网是另一个大红人,能否合作一下?

使用STM32和AD5420输出4-20mA的电路和程序_stm32输出4-20ma电流-程序员宅基地

文章浏览阅读6.8k次,点赞6次,收藏65次。最近在做一个4-20mA输出的项目,遇到一些问题,但是还好顺利解决,使用STM32F103C8T6和AD5420,下面是电路图:AD5420电路参考datasheet和CN0270,www.analog.com/CN0270.通讯使用的是官方示例程序移植,官方为4-20mA,我这项目为了有其他模式所以改为0-24mA输出。程序如下:头文件如下:#ifndef __..._stm32输出4-20ma电流

随便推点

linux下bin安装包制作教程_linux系统bin文件打包方法-程序员宅基地

文章浏览阅读9.2k次,点赞4次,收藏22次。基本思想: 制作简单的安装包的时候可以简单的用cat命令连接两个文件,然后头部是脚本文件,执行的时候把下面的文件分解出来就行了。一般这个后部分的文件是个压缩包,那样,就能够打包很多文件了,在脚本中解压出来即可。这就是Linux那些bin啊run啊等安装脚本的简单制作了。制作步骤:编写shell脚本#!/bin/bash#安装前先卸载旧版本软件if [ -f "/u_linux系统bin文件打包方法

线性链表的删除-----数据结构与算法笔记_有一个含有n个元素的线性表,可以采用单链表或双链表存储,其主要的操作是插入和删-程序员宅基地

文章浏览阅读2.5k次,点赞3次,收藏9次。一、线性链表的元素删除参考书:《数据结构(C语言)》–严蔚敏等编著,清华大学出版社。1、删除思想如图:若线性链表初始化为:1,2,3,4,5删除第3个位置的元素步骤:(1)查找到第i的位置的前驱,使用p指向i-1处;(2)建立q节点,使其在p的next,将q的next 给 p的next,使2的位置与4的位置相连(3)这时将q的位置的值赋给e返回,然后free(q)或delete q;这个节点,完成删除相关代码:#include "stdio.h"#include "stdlib.h_有一个含有n个元素的线性表,可以采用单链表或双链表存储,其主要的操作是插入和删

【语义分割】1、语义分割超详细介绍_语义分割方法分类-程序员宅基地

文章浏览阅读2.8w次,点赞135次,收藏1k次。图像分割是机器视觉任务的一个重要基础任务,在图像分析、自动驾驶、视频监控等方面都有很重要的作用。图像分割可以被看出一个分类任务,需要给每个像素进行分类,所以就比图像分类任务更加复杂。此处主要介绍 DL-based 方法。encoder:输入图像→resize到特定大小→输入 backbone→得到特征图可选:decode_head[0]:特征图→FCN→类别特征图→求带权重的 loss(权重0.4)_语义分割方法分类

使用python将mat文件转换为csv文件_python批量转化mat为csv-程序员宅基地

文章浏览阅读1.2k次。import pandas as pdimport scipyfrom scipy import iomatfile = scipy.io.loadmat('你的mat文件路径,直到.mat结束')features = list(matfile .values())[-1]data = pd.DataFrame(features)csvdatapath = '你的csv目标文件路径,直到.csv结束'data.to_csv(csvdatapath, index=False)..._python批量转化mat为csv

网站链接跳转安全警告提示l单页源码_网站安全监测单页源码-程序员宅基地

文章浏览阅读1k次。介绍:本次给大家分享一个网页广告链接跳转提示html模板。做网站的,很多都是以接广告,但是游客没法一一去判别一些广告是否违规,是否安全,所以我们尽可能的提示网站用户,让用户去判别,谨慎交易。所以,鹏仔花了点时间,写了这个单页面,点击跳转时候的一个小提示,如上图所示。网盘下载地址:http://kekewangLuo.cc/XUMaxxsaeDR0图片:..._网站安全监测单页源码

CSS选择器权重计算规则_请描述css选择器的权重(specificity)计算规则。-程序员宅基地

文章浏览阅读185次。一、CSS选择器类型包括:1.ID  #id2. class .class3. 标签 p4. 通用 *5. 属性 [type="text"]6. 伪类 :link7. 伪元素 ::after8. 子选择器 相临选择器二、权重计算规则1.第一等,代表内联样式规则 如:style="",权值为:1000;2.第二等,代表ID选择器 如:#box,权..._请描述css选择器的权重(specificity)计算规则。