【前端】前端三要素之JavsScript基础

写在前面:本文仅包含JavaScript内容,DOM知识传送门在这里,BOM传送门在这里。

本文内容是假期中刷的黑马Pink老师视频(十分感谢Pink老师),原文保存在个人的GitLab中,如果需要写的网页内容信息等可以评论联系我,若是编辑博文中出现了忘记上传的图片或者错位的图片欢迎评论区指正。写作不易,欢迎点赞、收藏+关注。

最近正在阅读JavaScript高级,后续会陆续发出来。

文章目录

  • JavaScript学习笔记
  • 简介
    • 浏览器组成部分
    • JS的组成
        • ECMAScript
        • DOM —— 文档对象模型
        • BOM——浏览器对象模型
    • JS 书写方式
    • JS 的注释
    • JS 的输入输出
  • 变量
    • 变量的使用
    • 变量使用的注意事项
    • 变量的命名规则
  • Q&A
  • 数据类型简介
    • 1. 简单数据类型 | 简介
    • 1.1 Number
    • 1.2 String 字符串类型
    • 1.3 Boolean 类型
    • 1.4 undefined
    • 1.5 Null
    • 1.6 变量类型检测
  • 数据类型的转换
    • 1. > String
    • 2. > Number
    • 3. > Boolean
  • 运算符
    • 表达式
    • 关系运算符(比较运算符)
    • 逻辑运算符
    • 逻辑中断逻辑与 | 逻辑中断逻辑或
        • 逻辑与终端
        • 逻辑或终端
    • 赋值运算符
  • 流程控制
    • 三元表达式
    • switch
    • 循环
        • for 循环
        • while 循环
        • do...while... 循环
    • continue | break
  • 数组
        • 创建数组的方式
        • 访问数组元素
        • 数组新增元素
    • 复习笔记
        • 检测是不是数组
        • 添加数组元素
        • `sort` 数组排序
        • `sort` 方法存在的问题
        • `sort` 的完美解决方案
        • 获取数组索引号
        • 数组转换为字符串
  • 函数
        • 函数的使用
        • 函数的参数
  • 使用`arguments`
        • 伪数组
  • 函数的两种声明方式
  • 作用域
        • 变量作用域
  • JavaScript 没有块级作用域
  • 作用域链
    • LHS 与 RHS 简介
  • 预解析
  • 对象
    • 创建对象
    • 遍历对象
  • 内置对象
        • 格式化日期
        • 格式化时分秒
        • 时间戳
        • 倒计时
  • 基本包装类型
        • 基本数据类型
        • 字符串的内容不可改变
        • 获取字符的位置
        • 根据位置返回字符
        • 拼接与截取字符串
        • 替换字符串
        • 字符串转换为数组
  • 数据类型
        • 简单数据类型
        • 简单数据类型传参
        • 复杂类型传参
  • JS 执行队列
    • 任务执行机制
    • 带点击事件的任务执行机制
  • 立即执行函数 | IFEE

自从搭建了自己的GitLab,每一天都在想着喂饱它!最近趁年假补了一下JS基础与CSS。

以下内容均是本人亲自写的,并且经过验证,请放心食用。

JavaScript学习笔记

简介

本内容来源于黑马程序员[JavaScript全套教程]

  1. JavaScript是运行在客户端上的编程语言
  2. 是一门脚本语言
  3. 也可以基于Node.js进行服务器端编程

浏览器组成部分

渲染引擎/JS引擎

  1. 渲染引擎:用来解析HTML和CSS,俗称内核,比如chrome浏览器的blink,老版本的webkit
  2. JS引擎:也称为JS解释器。用来读取网页中的JavaScript代码,对其处理后运行,比如chrome浏览器的V8.

JS的组成

ECMAScript/DOM/BOM

ECMAScript

ECMAScript是由ECMA国际(原欧洲计算机制造商协会)进行标准化的一门编程语言,这种语言在万维网上应用广泛,它往往被称为JavaScript或者JScript,但实际上后两者是ECMAScript语言的实现和拓展。

DOM —— 文档对象模型

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口

通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)

BOM——浏览器对象模型

BOM(Browser Object Model,简称BOM)是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。

通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。

JS 书写方式

  1. 行内式
<body>
    <!-- 行内式JS -->
    <input type="button" value="唐伯虎" onclick="alert('点秋香咯')">
</body>
  1. 内嵌式
<!-- 内嵌式JS -->
<script>
    alert('Hello World')
</script>
  1. 外联式
// 01.my.js文件
alert('如果我是DJ你还爱我吗?')
<!-- 外联式JS -->
<script src="01.my.js"></script>

JS 的注释

  1. 单行注释
// 这是一个单行注释
  1. 多行注释
/*
 这是多行注释
*/
/**
 * 这也是多行注释,不过是绿色的
 */

JS 的输入输出

  1. prompt输入框
  2. alert弹出框
  3. console.log()控制台打印
var age = prompt('请输入你的年龄');
alert(age)
console.log(age)

变量

变量是在内存中用来存放数据的空间。

变量的使用

  1. 声明变量
  2. 赋值变量
var age; // 生命一个变量
age = 18; // 赋值变量
// 也可以合为一步
var age = 18;
console.log(age);
// 结合第二步的输入输出
var age = prompt('请输入你的年龄');
alert(age)
console.log(age)

变量使用的注意事项

  1. 可以一次声明多个变量
  2. 只声明不赋值是undefined
  3. 不声明直接使用会报错ReferenceError:tel is not defined
  4. 不声明直接赋值会给你创建一个新的变量(LHS找不到会为你创建一个新的全局变量,严格模式下不行)
var age,name,address;
var age = 18,
    name = '张三',
    address = '上海市松江区泗泾镇';

变量的命名规则

  1. 可以包含字母(区分大小写)、数字、下划线、美元符号
  2. 不能以数字开头
  3. 不能是保留字或者关键字
  4. 变量名必须要有艺艺
  5. 遵守驼峰命名法
  6. 不要使用name作为变量名

Q&A

为什么使用变量 | 因为需要鵆一些数据
变量是什么 | 变量就是一个容器,用来存放数据的。方便后面使用数据
变量的本质是什么 | 变量是内存里的一块空间,用来存储数据

数据类型简介

使用不同的数据类型可以节约内存空间

JavaScript是一种弱语言类型,只有在程序运行的时候才会被确认数据类型。

JavaScript是动态语言,运行过程中数据类型是可以变化的(有点像ts的any类型)

1. 简单数据类型 | 简介

数据类型默认值
Number0
Booleanfalse
String“”
Undefinedundefined
Nullnull

1.1 Number

// 十进制整数与小数
var num1 = 10;
var num2 = 10.01;

// 八进制(前面加0表示八进制 | 八进制不能表示小数)
var e1 = 010; // 8

// 16进制(前面加0x表示16进制 | 0~9A~F)
var s1 = 0xA;
// 最大值 & 最小值
var max = Number.MAX_VALUE;
var min = Number.MIN_VALUE;
Infinity;  // 无穷大
-Infinity; // 无穷小
NaN; // 非数字
'Hello' - 100; // NaN 

Number 相关方法

isNaN(2); // false 是数字返回false

1.2 String 字符串类型

使用单引号或双引号引起来的内容都是字符串,但是更推荐是用单引号

嵌套关系:使用外双内单(也可以外单内双)

var str1 = '我是Jim.kk';
var str2 = "'我是'Jim'.kk'"
var str3 = '我是:\nJim.kk'; // 换行

字符串的转义字符等与其他语言无异,这里不多做解释。

字符串具有一些特点,比如:具有长度、可以拼接或者裁切等:

var str1 = '我是Jim.kk';
console.log(str1.length); // 8

使用+可以拼接字符串,字符串类型与任意类型相加都会拼接。

var str1 = '我是' + 'Jim.kk'; // 我是Jim.kk
var str2 = '我' + 18 + '岁';  // 我18岁
var str3 = '结果是:'+true; // 结果是:true

1.3 Boolean 类型

var x1 = true;
var x2 = false;

1.4 undefined

var v1;
var v2 = undefined;
console.log('hello'+v1); // helloundefined
console.log('hello'+v2); // helloundefined
console.log(v2+1); // NaN

1.5 Null

var n1 = null;

1.6 变量类型检测

var v1 = 'Hello';
var v2 = 12;
var v3;
var v4 = v3 + 12;
console.log(typeof v1) // string
console.log(typeof v2) // number
console.log(typeof v3) // undefined
console.log(typeof v4) // number

prompt输入的一定是字符串类型

数据类型的转换

1. > String

  1. xx.toString()
  2. String()
  3. 加号拼接空字符串
var v1 = 1;
var v2 = true;
var str1 = v1.toString();
var str2 = v2.toString();
var str3 = String(v1);
var str4 = String(v2);
var str5 = v1+'';
var str6 = v2+'';

var str7 = 1+'';
var str8 = true+'';

2. > Number

  1. parseInt(string)
  2. parseFloat(string)
  3. Number(string) // 强制转换函数
  4. js隐式转换(- * /) '12'-0
parseInt('12') // 12
parseInt('12.21') // 12
parseInt('12xxx') // 12
parseInt('zx12xxx') // NaN
parseFloat('120') // 120
parseFloat('12.21') // 12.21
parseFloat('12.21xxx') // 12.21
parseFloat('zx12.21xxx') // NaN
Number('12') // 12
Number('12.21') // 12.21
'12'-0; // 隐式转换 12
'120' - '110'; // 隐式转换 10
'12' * 3; // 隐式转换 36

3. > Boolean

代表空、否定的值会被转换为false,如:‘’、0、NaN、null、undefined

其余全不会被转换为true

Boolean('')         // false
Boolean(0)          // false
Boolean(NaN)        // false
Boolean(null)       // false
Boolean(undefined)  // false
Boolean('Jim.kk')   // true
Boolean(12)         // true

运算符

感觉可以省略了

+ - * / %:加减乘除取余

小数在算数运算中会存在问题

console.log(0.1 + 0.2) // 0.300...004

表达式

表达式是有数字、运算符、变量组成的式子,表达式一定有返回值

1+1
var age = 1;
age + 1;
var v1 = 1;
++v1;
v1++;
--v1;
v1--;

关系运算符(比较运算符)

> < >= <= == === != !==

18 == '18'   // true
18 === '18'  // false
18 != '18';  // false
18 !== '18'; // true

双等号是只看值,此时有隐式转换,===不仅要求值一样,数据类型也要一致。

逻辑运算符

&& || ! 逻辑与、逻辑或、逻辑非

逻辑中断逻辑与 | 逻辑中断逻辑或

逻辑与终端

如果第一个表达式为真,则返回表达式2

如果第一个表达式为假,则返回表达式1

123 && 456 // 456
0 && 456   // 0
0 && 1 + 2 && 456 * 789 // 0
逻辑或终端

如果表达式1为真,则返回表达式1

如果表达式1为假,则返回表达式2

123 || 456 // 123
123 || 456 || 456 + 123 // 123
0 || 456 || 456 + 123 // 456
var num = 0;
console.log(123 || num++); // 123
console.log(num); // 0

赋值运算符

= += -=

var v1 = 1; // 1
v1 += 2;    // 3
v1 -= 1;    // 2

流程控制

顺序结构/分支结构/循环结构

顺序流程控制

var v1 = 1;
v1 = 2;
console.log(v1);

分支结构

if( 条件表达式 ) {
    执行语句;
}
if( 条件表达式 ) {
    执行语句;
    return;
}
执行语句;
if( 条件表达式 ) {
    执行语句;
} else {
    执行语句;
}
if( 条件表达式 ) {
    执行语句;
} else if ( 条件表达式 ) {
    执行语句;
} else {
    执行语句;
}

三元表达式

若是条件表达式为真,则执行语句1,否则执行语句2

条件表达式 ? 执行语句1 : 执行语句2;

switch

利用表达式的值与case的值相匹配,若是一致则执行该case,都不一致执行default;

如果不写break则会继续向下执行,直到遇到一个break或者执行结束。

var v1 = 3;
switch ( v1 ) {
    case 1:
        // 执行语句1;
        break;
    case 2:
        // 执行语句2;
        break;
    case 3:
        // 执行语句3;
        break;
    default:
        // 最后的执行语句;
}

循环

for 循环
for(var i = 1; i<=100; i++) {
    console.log(i);
}

// 执行顺序

// for( 1 ; 2 ; 4){
//    3;
// }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

while 循环
// while(条件表达式) {
//     循环体;
// }

var v1 = 1;
while( v1 <= 100) {
    console.log(v1++);
}
do…while… 循环

dowhile会先执行一次,然后再去判断条件,while则是先判断条件

// do {
//     循环体;
// } while( 条件表达式 );

continue | break

continue:跳出当前循环

break:跳出循环

数组

数组是一种有长度的、存储内容没有限制的链(Array)

创建数组的方式
// 1. new Array()
var arr1 = new Array();

// 2. 数组字面量
var arr2 = [];
var arr3 = ['1',2,'3','4',5];
访问数组元素
// 获取数组元素
var arr = [1,2,3,4,5]
console.log(arr[0]) // 1

// 修改数组元素
arr[0] = 3;
console.log(arr[0]) // 3

超过数组长度-1下标的元素是undefined

数组新增元素
  1. 修改length长度
  2. 修改索引号

修改长度

var arr = ['红','黄','蓝'];
arr.length = 5;
console.log(arr); // '红','黄','蓝',empty*2(两个空)
arr[3] = '绿';
arr[4] = '青';

追加数组元素

var arr = ['红','黄','蓝'];
arr[length] = '绿'; // arr[3] = '绿'
arr[length] = '青'; // arr[4] = '青'
var arr = ['红','黄','蓝'];
arr = '12345';
console.log(arr); // 12345

复习笔记

var arr1 = [];
var arr2 = new Array();

var arr3 = new Array(2);   // 创建一个长度为2的空白数组
var arr3 = new Array(2,3); // 数组中有两个元素,分别是2和3

console.log(reverse(arr3)) // [3,2]

通过字面量或者内置对象创建一个空数组。

检测是不是数组
var arr = new Array();
console.log(arr instanceof Array); // true
console.log(Array.isArray(arr));   // true
添加数组元素
  1. push 在末尾添加一个或多个元素 | 返回新数组的长度
arr = [1,2,3];
arr.push(4,5,6);  // 返回新数组的长度
console.log(arr); // [1,2,3,4,5,6]
  1. unshift 在数组前面添加一个或者多个元素 | 返回新数组的长度
arr = [1,2,3];
arr.unshift('blue','red'); // 返回新数组长度
console.log(arr); // ['blue','red',1,2,3]
  1. pop 在数组末尾删除一个元素 | 返回删除的那个元素
arr = [1,2,3];
arr.pop(); // [1,2]
  1. shift 删除第一个元素 | 返回删除的那个元素
arr = [1,2,3];
arr.shift(); // [2,3]
sort 数组排序
var arr = [3,4,7,1];
arr.sort();
console.log(arr);  // [1,3,4,7]
sort 方法存在的问题

sort对两位数是先对比第一个

var arr = [13,4,77,1,7];
arr.sort();
console.log(arr); // [1,13,4,7,77] 排序失败
sort 的完美解决方案
var arr = [13,4,77,1,7];
arr.sort(function (a,b) {
   return a - b; 
});
console.log(arr); // [1,13,4,7,77] 排序失败
获取数组索引号
var arr = ['red','blue','green'];
console.log(arr.indexOf('green')); // 2
var arr = ['red','blue','green','green'];
console.log(arr.indexOf('green')); // 2 只找第一个
var arr = ['red','blue'];
console.log(arr.indexOf('green')); // -1
var arr = ['red','blue','green','green'];
console.log(arr.lastIndexOf('green')); // 3 返回最后一个 不存在返回-1
数组转换为字符串
  1. toString()
var arr = [1,2,3];
console.log(arr.toString()); // 1,2,3
  1. join()

join() 可以修改分隔符

var arr = [1,2,3];
console.log(arr.join()); // 1,2,3
console.log(arr.join('-')); // 1-2-3
console.log(arr.join('&')); // 1&2&3

函数

在一些语言中是方法,出现的目的是为了代码复用。

function getSum(num1,num2) {
    return num1 + num2;
}

console.log(getSum(1,2)); // 3
console.log(getSum('我是','Jim.kk')) // 我是Jim.kk
函数的使用
  1. 声明函数
  2. 调用函数
// 声明函数
function sayHi(){
    console.log('Hi~');
}
// 调用函数
sayHi()
函数的参数

声明函数的时候括号里的参数是形参

调用函数的时候括号里的参数是实参

函数的形参与实参不需要意义匹配

function getSum(num1,num2) {
    console.log(num1 + num2);
}

getSum(1,2);    // 3
getSum(1,2,3);  // 3 | 第三个参数没人接,就扔掉了
getSum(1);      // NaN | 第二个数字没有值,是undefined,一个数字加上undefined是NaN

JS中不存在函数的重载,若是多次声明一个同名参数(即使参数不同),也仅以最后一次声明为准。

return除了返回以外,还可以终止函数。

如果函数没有return,则返回的是undefined

使用arguments

当我们不确定有多少个参数传递进来的时候,可以使用garguments来获取。在JavaScript中,arguments实际上他是当前函数的一个内置对象。所有的函数都内置了一个arguments对象,arrguments对象中存储了传递的所有实参

function fn(){
    console.log(arguments);
}

fn(1,2,3); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

arguments其实是一个伪数组

伪数组
  1. 要有长度
  2. 按照索引方式进行存储的
  3. 没有pop、push方法

函数的两种声明方式

  1. 命名方法
  2. 函数表达式
// 1. 命名方式
function fun1() {
    // ...
} 

// 2. 函数表达式(匿名函数,fun2是变量名)
var fun2 = function (){
    // ...
}

作用域

  1. 提高程序的可靠性
  2. 减少命名冲突

全局作用域:整个Script标签中的作用域

局部作用域:代码的名字只在函数内部起作用

var num = 1;
var fun1 = function (){
    var num = 2;
    console.log(num);
}

console.log(num); // 1
fun1(); // 2
变量作用域
  1. 全局变量:<script>标签内的变量
  2. 局部变量:函数内部的变量

需要注意的是:如果LHS在局部作用域内找不到该变量,则会定义一个全局变量

function fun(){
    var num1 = 1;
    num2 = 2;
}

// console.log(num1) // Uncaught ReferenceError: num1 is not defined
fun(); // 调用一次fun,发现fun中进行LHS查询找不到num2,因此定义了一个全局的num2
console.log(num2) // 由于function中没有var num2,而是直接赋值,所以num2被定义为全局变量。

以上示例中如果不调用一次fun()函数,则console.log(num2)的结果也是ReferenceError,原因请自己思考

  1. 全局变量只有浏览器关闭的时候才会销毁,比较占用内存资源
  2. 局部变量程序执行完毕就会销毁,比较节约内存资源

JavaScript 没有块级作用域

ES6的时候加了块级作用域

if ( 3 < 5){
    var num1 = 5;
}
console.log(num1); // 5
if ( 3 > 5){
    var num1 = 5;
}
console.log(num1); // undefined

作用域链

内部函数可以访问外部函数

采用就近原则,也就是说可以屏蔽,如果fun2()中也定义了一个num1,那么读取的就是fun2()中的num1

LHS 与 RHS 简介

function fun1(){
    var num1 = 1;
    function fun2() {
        console.log(num1);
    }
    fun2();
}
fun1(); // 1
var num1;
var num2 = 1; // 一次LHS查询,找到num2,给它赋值为1
num1 = num2;  // 先进行一次RHS查询,找到num2的值为1,然后进行一个LHS查询,找到num1,并且将1赋值给num1
function fun(){
    console.log(1);
}

fun(); // 进行一次RHS查询,找到fun的值,发现是个函数,直接执行,这一行中没有出现等于号,但是依旧是一个RHS查询

预解析

JS引擎会把所有的js里面所有的var、function提升到当前作用域的最前面。

const、let不会提升

  1. 变量提升:把所有的变量声明提升到当前作用域最前面,只提升生命,不提升赋值。
  2. 函数提升:把所有的函数声明提升到当前作用域的最前面。
  1. 变量提升
console.log(num); // 报错:Uncaught ReferenceError: num1 is not defined
console.log(num2); // undefined
var num2 = 10;

// 执行顺序:
// var num2;
// console.log(num2)
// num2 = 10;
console.log(num3); // 报错:Uncaught ReferenceError: Cannot access 'num3' before initialization
const num3 = 10;
  1. 函数提升
fun(); // 我是Jim.kk
function fun(){
    console.log('我是Jim.kk');
}
fun(); // 报错:Uncaught TypeError: fun is not a function
var fun = function(){
    console.log('我是Jim.kk');
}

// 执行顺序:
// var fun;
// fun();
// fun = function(){
//     console.log('我是Jim.kk');
// }
function fun() {
    var a;
    a = b = c = 9;
    console.log(a); // 9
    console.log(b); // 9
    console.log(c); // 9
}
fun();
console.log(a); // undefined
console.log(b); // 9
console.log(c); // 9

对象

  1. 对象简介

在JavaScript中,对象是一组无需的相关属性和方法的集合,所有的事务都是对象,例如字符串、数值、数组、函数等。
对象是属性方法的集合。

  1. 如何创建对象
  1. 对象字面量:就是花括号{}里面包含了对象这个具体事务(对象)的属性和方法。

创建对象

  1. 对象字面量
var obj = {
    uname: 'Jim.kk',
    age: 25,
    sex: '男',
    sayHi: function (){
        console.log('Hi~我是Jim.kk');
    }
}

// 使用.的或[]的方式调用对象属性
console.log(obj.uname); // Jim.kk
console.log(obj['age']) // 25

// 使用.的方式调用对象方法
obj.sayHi(); // Hi~我是Jim.kk
  1. 里面的属性或方法采用键值对的形式 键 属性名:值 属性值
  2. 多个属性或者方法间用逗号隔开
  3. 方法冒号后面跟的是一个匿名函数
  1. 使用new Object的方式创建对象
var obj = new Object();
obj.uname = 'Jim.kk';
obj.age = 25;
obj.sex = '男';
obj.sayHi = function () {
    console.log('Hi~我是Jim.kk');
}

console.log(obj.uname); // Jim.kk
obj.sayHi(); // Hi~我是Jim.kk

以上代码一次只能创建一个对象,要想创建多个对象只能赋值粘贴,所以结合函数的特性,就有了构造函数。

  1. 构造函数

构造函数可以服用创建多个对象,本身是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总是与new运算符一起使用。我们可以把对象中的一些公共的属性和方法抽取出来,然后封装到这个函数里面。

使用构造函数遵循以下规范:

  1. 构造函数首字母大写
// function  构造函数名() {
//     this.属性 = 值;
//     this.方法 = function (){}
// }

// new 构造函数名();

function Star(name,age,sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}

var ldh = new Star('刘德华',18,'男');
console.log(ldh)
  1. 对象是特指
  2. 构造函数是泛类
  3. 使用构造函数构造对象的方式称为对象实例化
  1. new可以在内存中创建一个空对象
  2. this会指向该空对象
  3. 执行构造函数里面的代码给这个空对象添加属性和方法
  4. 返回这个对象

遍历对象

for...in... 循环

function Star(name,age,sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}

var obj = new Star('刘德华',18,'男');

for(var item in obj) {
    console.log(item); // name age sex
    console.log(obj[item]); // 刘德华 18 男
}

内置对象

JavaScript的三种对象:自定义对象、内置对象、浏览器对象

JavaScript内置独享库

通过 MDN / W3C 可以查阅文档

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

var randon = Math.random();
console.log(randon)
 
var date = Date();
console.log(date);
格式化日期
    function getDate() {
    var week = ['星期天','星期一','星期二','星期三','星期四','星期五','星期六']
    var date = new Date();
    var y = date.getFullYear();
    var m = date.getMonth() + 1; // 注意是 0~11
    var d = date.getDate();
    var w = date.getDay();
    return y + '年' + m + '月' + d + '日 ' + week[w + 1];
}

console.log(getDate()); // 2024年2月8日 星期五
格式化时分秒
    function getTime(){
    var date = new Date();
    var h = date.getHours();
    var m = date.getMinutes();
    var s = date.getSeconds();
    return h + ':' + (m < 10 ? '0' + m : m) + ':' + (s<10? '0'+s : s);
}
console.log(getTime()) // 22:02:29
时间戳

从1970年1月1日0时0分0秒到现在经过的总毫秒数

获取时间戳的四种方式

var date = new Date();
// 方式1
date.valueOf();

// 方式2
date.getTime();

// 方式3
+new Date();

// 方式4 (不需要new)
Date.now();

以上的new Date()中以及+new Date()括号中都可以写进去数字或者字符串获得某个时间的时间戳。

倒计时
    function countDown(time){
      var now = +new Date();
      var target= +new Date(time)
      var seconds = (target - now) / 1000;
      var d = parseInt(seconds / 60 / 60 / 24);
      var h = parseInt(seconds / 60 / 60 % 24);
      var m = parseInt(seconds / 60 % 60);
      var s = parseInt(seconds % 60);

      return d +'天' + h + '时' + m + '分' + s + '秒';
    }

    console.log(countDown('2024-12-31 24:00:00')); // 327天1时43分12秒

基本包装类型

有点像Java的自动装箱与自动拆箱

基本数据类型

思考一个问题:明明只有对象类型才会有属性,为什么下面的string类型却可以输出长度呢?

var str = 'Jim.kk';
console.log(str.length); // 6

其实是执行了下面的一个简单操作:

// 1. 声明字符串
var str = 'Jim.kk';
// 2. 把简单数据类型包装为复杂数据类型
var temp = new String(str);
// 3. 把临时变量的值给 str
str = temp;
// 4. 销毁临时变量
temp = null;
字符串的内容不可改变
var str;
str = 'Jim';
str = 'kk';

看似str的值变化了,其实是在内存中新建了一个内存地址,将新的值存储到新的内存地址中。

要尽量避免在JS中拼接字符串。

获取字符的位置
var str = 'Jim.k___k';
console.log(str.indexOf('k')); // 4
console.log(str.indexOf('k',5)); // 8 

indexOf()会返回第一次出现的位置,后面加上一个数字,表示数字前面的都忽略,这个索引后面的第一次出现的该字母的位置。

其余与数组无异(也有lastIndexOf()),不多赘述。

根据位置返回字符
  1. chatAt(index) | 返回这个位置的字符
  2. charCodeAt(index) | 返回这个位置的 ASCII 码
  3. str[index] | 返回这个位置的字符
var str = 'Jim.kk';
console.log(str.charAt(3)); // .
console.log(str.charCodeAt(3)); // 46
console.log(str[3]); // .
拼接与截取字符串
  1. str1.concat(str2) | str1 + str2
  2. substr(start,lengtn) | 从start的位置开始截取长度为length长度的字符串
  3. slice(start,end) | 从start位置,截取到end位置,end不取
  4. substring(start,end) | 从start位置开始,截取到end位置,基本和slice相同,但是不接受负值
替换字符串
var str = 'Jim.cc';
console.log(tr.replace('cc','kk')); // Jim.kk

str = 'Jim.cc.cc';
console.log(tr.replace('cc','kk')); // Jim.kk.cc | 只会替换第一个
字符串转换为数组
var str = 'Jim.kk';
console.log(str.split('.')); // ['Jim','kk'] | 使用'.'进行分割

数据类型

  1. 简单数据类型存储到栈中
  2. 复杂数据类型存储到堆中 | 16进制的地址存储在栈中,然后指向堆中
简单数据类型
var nu = null;
console.log(typeof nu); // object | 返回的是一个空的对象

如果一个对象暂时没决定以后存什么,建议暂时存null

简单数据类型传参

简单数据类型传参是直接在内存中创建一个新的值,并且将实参的值赋值给形参

复杂类型传参

复杂类型传参传递的其实是地址值,先在栈中开辟一个内存空间存储形参,然后实参的值(一个16进制地址)赋值给这个值,然后拿着这个地址去堆中寻找复杂数据类型。

JS 执行队列

JavaScript 语言的一大特点就是单线程,也就是说,同一时间只能做一件事情。

为了解决这个问题,利用多喝CPU计算能力,HTML5提出了Web Woker标准,允许JavaScript脚本创建多个线程,于是,JS中出现了同步异步

  1. 同步:上一个任务结束了才去执行下一个任务
  2. 异步:上一个任务没结束的时候就开始下一个任务

任务执行机制

console.log(1);
setTimeout(function () {
    console.log(3);
},0)
console.log(2);

以上代码输出顺序为1、2、3

在这里插入图片描述

  1. 回调函数不属于同步任务,属于异步任务
  2. 当JS顺序执行同步任务的时候,发现了一个异步任务,就会创建一个任务消息队列
  3. 等所有同步任务中的任务执行完毕之后,才会去执行异步任务消息队列中的任务

异步任务分为以下几类:

  1. 普通事件:如click、resize等
  2. 资源加载:如load、error等
  3. 定时器:包括setInterval、setTimeout等

带点击事件的任务执行机制

console.log(1);
document.onclick = function () {
    console.log('我是Jim.kk');
}
console.log(2);
setTimeout(function () {
    console.log(3);
},3000);
  1. 当没点击「点击事件」的时候,点击事件是不会被放到任务队列中的,所以在我没点击页面的时候,页面中的任务队列如下所示(3秒之后,只有定时任务时间到了,任务队列中才会有任务):

在这里插入图片描述

  1. 定时任务执行完毕之后,异步消息队列中的任务会被清空,这时候的任务队列如下所示:

在这里插入图片描述

因为异步任务已经执行结束,消息队列被清空。

  1. 这时候若是点击了按钮,则如下所示:

在这里插入图片描述

  1. 等点击事件执行结束之后,任务队列中如下所示:

在这里插入图片描述

若是在三秒内点击了按钮,则同步任务处理结束之后,异步任务队列中会先出现一个异步点击任务,等它执行结束之后会消失,然后等到了三秒钟,异步任务队列中会出现一个定时任务,执行输出3,等执行结束之后还是会消失。

由于主线程不断地重复获取任务、执行任务、再获取任务、再执行任务。所以这种机制被称为事件循环(Event Loop)

立即执行函数 | IFEE

书写规范

  1. 由两个小括号连起来,前一个小括号中写函数
  2. 立即执行函数后面必须要加分号,否则下面跟的内容会报错
  3. 如果不加分号,可以给立即执行函数一个名字

立即执行函数的特点

  1. 独立开辟了一个作用于,里面的变量都是局部变量,所以两个立即执行函数中存在相同变量名不会报错
  1. 普通的立即执行函数
(function () {
    // 函数体
})();
  1. 带参数的立即执行函数
(function (a,b) {
    console.log(a+b); // 3
})(1,2);
  1. 有名字的立即执行函数
(function sum (a,b) {
    console.log(a+b); // 3
})(1,2);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/399842.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java EE初阶二十二】https的简单理解

1. 初识https 当前网络上,主要都是 HTTPS 了,很少能见到 HTTP.实际上 HTTPS 也是基于 HTTP.只不过 HTTPS 在 HTTP 的基础之上, 引入了"加密"机制&#xff1b;引入 HTTPS 防止你的数据被黑客篡改 &#xff1b; HTTPS 就是一个重要的保护措施.之所以能够安全, 最关键的…

AI人工智能写作,这5款AI软件帮你解决写作难题

在如今这个信息爆炸的时代&#xff0c;写作已经成为我们生活和工作中必不可少的一部分。但是&#xff0c;对于很多人来说&#xff0c;写作可能是一件挺费劲的事情&#xff0c;需要花费很多时间和精力。不过&#xff0c;幸运的是&#xff0c;随着人工智能技术的不断进步&#xf…

【2024软件测试面试必会技能】Selenium(5):元素定位的介绍及使用

Selenium元素定位介绍&#xff1a; 元素的定位和操作是自动化测试的核心部分&#xff0c;其中操作又是建立在定位的基础上的&#xff0c;举例&#xff1a;一个对象就是一个人&#xff0c;我们可以通过身份证号、姓名或者他的住址找到这个人。那么一个web对象也是一样的&#xf…

声反射是如何保护内耳的?

声反射是如何保护内耳的&#xff1f; 反射是人和动物通过中枢神经系统对刺激所产生的规律性反应。 在人耳中也同样存在这样一种反射&#xff0c;叫做“声反射”。当人耳受到足够强度的声刺激时&#xff0c;双耳镫骨肌发生反射性收缩&#xff0c;这就是声反射&#xff0c;又称镫…

Vue3_基础使用_3

今天主要学习的是hooks, vue3的使用比vue2方便很多了&#xff0c;但是呢各个功能块的逻辑有时候还是会缠绕在一起&#xff0c;这个时候使用hooks进行模块化管理开发&#xff0c;说白了就是将每个单独的业务放到自己的.ts中去写&#xff0c;以后修改就找到这个ts 不用到处去翻…

5.【架构师成长之路】职场新人:如何快速变得专业(下)

文章目录 导言一、凡事不苟且二、心态要开放1、勇于承担各种事2、别害怕犯错 本文总结说明 导言 上一篇文章我们讲了&#xff0c;作为新人最重要的事情就是“快速变得专业”。 我们先自问自答了一个问题&#xff1a;“新人为何要快速变得专业&#xff1f;新人难道不能就循序渐…

科技快讯:鸿道Intewell操作系统突破国际垄断,引领工控新革命

科东软件Intewell鸿道工业操作系统&#xff0c;已在多种严苛环境下运行检验&#xff0c;并应用于工业控制、智能制造、汽车电子、轨道交通、能源电力、航天航空等实时性要求极高的领域&#xff0c;历经30年的不懈努力和研发迭代&#xff0c;在功能和性能上可以替代风和VxWorks操…

【论文阅读】【yolo系列】YOLO-Pose的论文阅读

Abstract 我们介绍YOLO-pose&#xff0c;一种无热图联合检测的新方法&#xff0c;基于流行的YOLO目标检测框架的图像二维多人姿态估计。 【现有方法的问题】现有的基于热图的两阶段方法是次优的&#xff0c;因为它们不是端到端可训练的&#xff0c;训练依赖于surrogate L1 loss…

【JVM】计数器引用和可达性分析

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;JVM ⛺️稳中求进&#xff0c;晒太阳 C/C的内存管理 在C/C这类没有自动垃圾回收机制的语言中&#xff0c;一个对象如果不再使用&#xff0c;需要手动释放&#xff0c;否则就会出现内存泄漏…

常见消息中间件分享

文章目录 概念核心角色作用&使用场景应用解耦异步通信削峰填谷大数据流处理 使用模型点对点模型发布-订阅模型 常见消息中间件介绍一、kafka二、RabbitMQ三、RocketMQ 比较一、Kafka如何实现高吞吐量二、RocketMQ如何实现事务消息 概念 消息中间件是基于队列与消息传递技术…

猿辅导送给新时代家长的一份教育指南,让孩子“学会学习”

新课标发布以来&#xff0c;各学科综合素养内容占比逐渐提升&#xff0c;成为校内教学考察的新方向&#xff0c;素养教育也成为学校、家长讨论的新话题。论坛上&#xff0c;各领域教育创新者、教育实践者围绕素养教育&#xff0c;探讨了学习本质、学习兴趣、作业问题、厌学情绪…

JAVA并发编程之原子性、可见性与有序性

并发编程-原子性、可见性与有序性 一、CPU的可见性 1.1 缓存一致性问题的出现 CPU处理器在处理速度上&#xff0c;远胜于内存&#xff0c;主内存执行一次内存的读写操作&#xff0c;所需要的时间足够处理器去处理上百条指令。 为了弥补处理器与主内存处理能力之间的差距&am…

2023 re:Invent 用 PartyRock 10 分钟构建你的 AI 应用

前言 一年一度的亚马逊云科技的 re:Invent 可谓是全球云计算、科技圈的狂欢&#xff0c;每次都能带来一些最前沿的方向标&#xff0c;这次也不例外。在看完一些 keynote 和介绍之后&#xff0c;我也去亲自体验了一些最近发布的内容。其中让我感受最深刻的无疑是 PartyRock 了。…

3 Nacos源码下载并集成达梦数据库驱动

1、Nacos源码下载 源码直接下载gitee上的nacos2.2.3,具体链接:Nacos: 概览 欢迎来到 Nacos 的世界! Nacos 致力于帮助您发现、配置和管理微服务 - Gitee.com,具体如下图

在编老师可以有副业吗

许多在编老师或许都会面临这样一个问题&#xff1a;除了教书育人&#xff0c;我是否还能有点别的追求&#xff1f;副业&#xff0c;对于很多人来说是一个增加收入、拓展兴趣的途径&#xff0c;但对于在编老师而言&#xff0c;这个问题却显得有些复杂。 老师这份工作本身就充满…

宋仕强介绍说,萨科微slkor

宋仕强介绍说&#xff0c;萨科微slkor&#xff08;www.slkoric.com&#xff09;研制了碳化硅SiC SBD二极管、碳化硅SiC MOSFET管、IGBT管、超快恢复功率二极管等高端产品&#xff0c;萨科微SLKOR还有肖特基二极管、ESD静电保护二极管、TVS瞬态抑制二极管、通用二极管和三极管&a…

0-前置知识

前言 SpringBoot框架在设计之初&#xff0c;为了有更好的兼容性&#xff0c;在不同的运行阶&#xff0c;段提供了非常多的扩展点&#xff0c;可以让程序员根据自己的需求&#xff0c;在整个Spring应用程序运行过程中执行程序员自定义的代码。 ApplicationContextInitializer …

springcloud-网关(gateway)

springcloud-网关(gateway) 概述 \Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API&#xff0c;并为其提供跨领域的关注&#xff0c;如&#xff1a;安全、监控/指标和容错 常用术语 Route&#xff08;路由&#xff09;: 网关的基本构件。它由一个ID、一个目的地…

软考 系统分析师系列知识点之企业信息化规划(1)

所属章节&#xff1a; 第7章. 企业信息化战略与实施 第2节. 企业信息化规划 企业信息化建设是一项长期而艰巨的任务&#xff0c;不可能在短时间内完成。因此&#xff0c;企业信息化建设必然会分解成各个相对独立的项目&#xff0c;在不同时期分别实施&#xff0c;从而建立多个…

1902_野火FreeRTOS教程内核在STM32中用到的2个中断PENDSV和SYSTICK

1902_野火FreeRTOS教程内核在STM32中用到的2个中断PENDSV和SYSTICK 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 上面是涉及到的源代码&#xff0c;而这次需要分析的就是78、79行的两个中断。首先&#xff0c;需要确认NVIC_SYSPRI2寄存器的作用。 进一…