头图

前言

最近整理代码时,我翻看了前段时间备考蓝桥杯Web组的练习代码。当时,我是跟着蓝桥云课的《JavaScript 基础入门》课程边学边敲的,因此本文涵盖了该课程的大部分内容。我习惯将知识点、遇到的问题以及探究结果嵌入在代码注释中,注释写得非常细致。

为了便于阅读,我将代码按1.1、1.2、2.1等章节分点整理,结构清晰、条理分明,让大家能像读文章一样轻松理解代码。现在,我将这些学习笔记分享给大家,希望能为JavaScript初学者提供帮助,顺便心痛一下那300块钱学费(

全文共800+行,干货满满!


正文

1.html

摘要

DOM事件:点击,双击,移入,移出

DOM节点:为test.js里的dom操作提供div目标

注意

请在浏览器或通过 Live Server 插件打开 1.html,确保 test.js 与 1.html 位于同一目录并已引入,以运行JavaScript代码。同时,1.html 中包含 test.js 的DOM操作所需的关键 div 元素。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 导航栏 -->
    <div class="navbar">
        <a    class="navbarButton" >首页</a>
        <!-- 使用querySelectorAll返回的是一个静态Nodelist,要设置color需要历遍..nodelist是类数组型,有length属性,但是没有继承所有的数组方法,以此来避免额外的性能开销..也可以用静态方法Array.from(变量名)转换成数组
        nodelist的历遍可以使用forEach方法,
        onmouseover="document.querySelectorAll('.navbarButton').forEach(e1 => e1.style.color = 'red')"-->
        
        <a   class="navbarButton">HTML</a>
        <a   class="navbarButton">CSS</a>
        <a   class="navbarButton">JavaScript</a>
        <a   class="navbarButton">关于</a>
        <a   class="navbarButton">帮助</a>
    </div>
    <!-- 主体 -->
    <div class="head1" id="head1">
        hahaha
    </div>
    <div class="forpro">
        <h1>输出当前的时间:</h1>
        <div id="forpro_timer_divId" class="forpro_timer_divClass"></div>
        <div class="forpro_container_divClass" id="forpro_container_divId"></div>
    </div>
    <div class="dom_par" id="dom_parID" ></div>
    <div class="dom_onclick" style="background-color: #ee5844;margin: 0 0 0 0;">
        <p 
        style="margin: 0 0 0 0;" 
        onclick="this.innerHTML = '我爱学习,身体好好!'" 
        ondblclick="this.innerHTML = '我爱学习,身体好好好!'" 
        onmouseover="this.innerHTML = '你把鼠标移到了上面'"
        onmouseleave="
            this.innerHTML = '你把鼠标移开了';
            setTimeout(() => {
                this.innerHTML ='请点击文本,双击该文本或把鼠标移动到上面';
            }, 1000);">
        请点击文本,双击该文本或把鼠标移动到上面</p>
    </div>
    <!-- 这里p是一个段落,内容会被margin撑大 -->
</body>
<style>
    /* 导航栏 */
    .navbar{
        background-color: #f5f5dc;
        display: flex;
        gap: 16px;
    }
    .navbarButton{
        text-decoration: none;
        color: #2424eb;
        display: flex;
        gap: 160px;
        font-size: 24px;
    }
 
    .navbarButton:active{
        background-color: red;
    }
    /* 主体 */
    .head1{
        /* width: 100%; */
        background-color: antiquewhite;
    }
    .forpro h1{
        margin: 0 0 0 0;
        background-color: #ffe793;
    }
    .forpro_timer_divClass{
        background-color: #ee5844;
        
    }
    .forpro_container_divClass{
        background-color: #a6e22e;
        height: 320px;
        overflow: auto;
    }
</style>
<script src="test.js" ></script> 
<!-- script最好放在最下面,防止dom找不到元素,或者用defer延迟执行脚本,知道文档加载完毕才执行脚本
同时,放在下面时添加的标签也是添加在下面 -->
</html>

test.js

摘要

变量:动态类型;命名规则
运算符:===;==;类型转换
数组:创建;增删;截取
字符串:查找;截取;替换
类型转换:显式;隐式
函数:声明;自执行;嵌套
对象:字面量;原型链
JSON:键值对;无方法
内置对象:数组;日期;数学

DOM事件:点击;双击;移入;移出
DOM节点:增删改查
BOM:窗口控制;定时器
作用域:函数级;无块级
闭包:保留变量
函数进阶:this绑定;参数处理

注意

以下是 test.js 的代码,依赖 1.html 中的 div 元素进行DOM操作,请通过 1.html 运行。

//1.1 变量
console.log("hello world");
var name = "实验楼";
// 变量必须以字母,下划线,美元符号$头,不能以数字开头
//大小写区分
//动态类型语言,不需要指定变量将包含什么类型
//给一个带引号的值,就是字符串."1"也是字符串,可以用typeof查看类型
 
/*1.2 运算符
不等于!==
1
*/
 
/*1.3 数组
创建并赋值数组*/
//var myarray = new Array[1 ,2 ,3 ,4 ,5];
var myarray = [1 ,2 ,3 ,4 ,5];
// 多维数组
var student = [
    ["张三" ,"男" ,"18"],
    ["李四" ,"男" ,"220"]
    ];
student[0][2];
//获取数组长度
var len_stu = student.length;
console.log(len_stu);
//将字符串转化为数组--对字符串使用split()方法
"1:2:3:4".split(":");
"a|b|c".split("|");
//将数组转化为字符串——对数组使用join()方法
myarray.join(":");
myarray.toString();     //也可以使用tostring方法来转换,但是无法指定分隔符,只能是逗号
console.log(myarray);
//在数组尾部添加一个或多个元素,使用push()方法
var arr = ["1" ,"2" ,"3" ,"4"];
arr.push("5" ,"6");
console.log(arr);
// 删除数组的最后一个元素,并把数组的长度减1,用pop()方法
arr.pop();
console.log(arr);
//如果数组为空则不改变数组,然后返回undefined值
var arr_b = [];
arr_b.pop();
console.log(arr_b ,typeof(arr_b));
//在开头添加,用unshift。删除开头,用shift
 
//1.4 无
//==,相等操作符,比较值是否相等,不比较类型
/*===,全等操作符,比较值和类型是否相等。
比如说,null和undefined的值相等,但是他们的类型不相等
undefined表示所有未赋值变量的默认值
null表示一个变量不在指向任何对象的地址
*/
 
//1.5字符串
//连接字符串,直接用+
//数字转字符串,使用tostring
var myNum = 9123;
var myString = myNum.toString();
var hello_str = "Hello World";
console.log(typeof(myNum));
//获取长度,继续用length
console.log(myString.length);
//获取字符串第一个字符
console.log(myString[0]);
//查找字符串是否包含某个字词,没找到会返回-1
/*str.indexOf(searchValue, fromIndex);
fromIndex,开始查找的位置,默认为0,fromIndex >= str.length,则返回-1
特殊情况:被查找的字符串为空字符串时,当 fromIndex <= 0 时返回 0,0 < fromIndex <= str.length 时返回 fromIndex,fromIndex > str.length 时返回 str.length
*/
myString.indexOf("9");
//从字符串当中提取用slice(strat,end)
var res1_myString =myString.slice(0,2);
console.log(hello_str);
//转换大小写
/*toLowerCase() ,全部转化为小写
toUpperCase() ,全部转化为大写
*/
var lowercase_hello = hello_str.toLowerCase();
console.log(lowercase_hello);
//替换字符串的某一部分,用replace,注意这个只能替换第一次出现的字符串,要替换的话要用全局替换方式
var replace_hello = hello_str.replace("World" ,"shiyanlou");
console.log(replace_hello);
console.log(hello_str.replace(/o/g ,"hello"));
 
//1.6转换成字符串
//使用tostring()可以带参,括号内是进制方式
//有的值没有 toString() 方法,所以需要用 String(),比如 null 和 undefined
 
//1.7 任意值转换成数值类型
//number()可以把任意值转化成数值,如果将转化的字符串里面有一个不是数字的字符,则返回NaN(not a number)
//parseInt()把字符串转化成整数,可带两个参数,(字符串 ,进制)
var num1 = "12";
console.log(parseInt(num1 ,2) ,typeof(num1));
//字符串转换成浮点数,但是只支持十进制数,如果内容只有整数,则解析成整数
console.log(parseFloat(num1));
//隐式类型转换,执行-0操作。如果该字符串不是纯粹的数字字符串,尽管在-0之后,它的数据类型变为number,但是其值为NaN
console.log(typeof("1221" - 0));
NoPureNumTransform = "abc" - 0;
console.log(typeof(NoPureNumTransform) ,NoPureNumTransform);
 
//1.8 转换成布尔类型
console.log(Boolean(123));
//在控制语句,比如if当中,会将括号里面的条件隐式转换成布尔值
var message;    //这句语句中定义了一个messaage变量,但是没有赋值,默认为undefined,它的布尔值为false
console.log(message);
if (message) {
    
}
else{
    console.log("false");
}
 
//2.1 条件
// 三元表达式 条件表达式?结果1:结果2
 
//2.2 循环
//continue使得当亲一次循环下的下面的语句都不执行
 
//2.3 函数
//方法需要依附于对象使用比如说console.log,这是面向对象编程的一个体现
//常规法创建函数
RegularFunction(1 ,2);  //这样写没问题,js会把当前作用域的函数声明放到最前面
function RegularFunction(a ,b) {
    console.log(a + b);
}
//函数表达式创建函数,比如说上面的可以改编为
var FunExpressFunction = function (a ,b) {  /*但是如果用表达式法创建函数,这样就和定义其他基本类型的边框
                                            一样,没什么特殊的,只会按顺序执行,所以就不能把调用放在声明
                                            前面,同时后面的这个function也是一个匿名函数,函数名就是
                                            变量名。要是想不命名直接调用,可以用自调用*/
    console.log(a + b);
}
FunExpressFunction(2 ,3);
//js当中,后定义的函数会覆盖之前定义的函数
//如果函数中没有返回值或者return后面没有跟任何值,则默认返回undefined
//匿名函数的自调用,可以避免全局变量污染,原理:()()
(function () {
    console.log("self-calling!");
})();
 
//练习1:打印直角三角形
console.log("\n");
var TimesInp;
//TimesInp = prompt("请输入三角形的行数");
 
//最好进行显示类型转换,保证逻辑严密
var goal = 10;//prompt("请输入要打印的三角形行数");
goal = Number(goal);    //因为prompt获取到的是字符串
console.log(typeof(goal));
if (goal > 10) {
    console.log("输入的数字太大了" ,typeof(goal));
}
 
//3.1 json简介
//在javascript里面所有事物都是对象,字符串,数组,日期等
//属性就是和对象相关的值,也可以理解为特征
//方法就是在对象上执行的动作,也可以理解为行为
//例如,一辆汽车就是现实生活里面的对象,它的名字,它的颜色,它的价格等特征就是汽车对象的属性。它能启动,驾驶,加速刹车就是汽车对象的方法
 
//3.2 json格式
//json是一种轻量级的数据交换语言
//json源于JavaScript,其数据格式与语言无发热,但是有许多语言都支持json
//json的文件扩展名是.json,官方的MIME类型是application/json
//注意:
//json是一种纯数据格式,它只有属性,没有方法。
//json的属性必须用“ ”引起来
//json要求两头有{}来使其合法
//可以把JavaScript对象原原本本的写入json数据,比如说:字符串,数字,数组,布尔值,还有其他字面值对象
//层级关系:
/*可以用{
    [],[]
}
的形式实现多层嵌套,也就是以数组作为顶层结构,实现存放多个对象
也可以用对象存放对象或者混合的方式
{
    "student": [],
    "age": {}
}
*/
 
//3.3 常用内置对象
/*1.Array对象,
常用属性:length,获取数组的长度
常用方法:
concat() 方法,用于链接两个或多个数组,并返回结果,语法为
arrayObject.concat(arrayX ,arrayY ,...);
例子:
*/
var ToConcat_a = [1 ,2 ,3];
var ToConcat_b = [4 ,5 ,6];
var ToConcat_c = ["one" ,"two" ,"three"];
console.log(ToConcat_a.concat(ToConcat_b ,ToConcat_c));    
//意思就是对象ToConcat_a使用了concat()方法拼接了字符串对象ToConcat_b ,ToConcat_c
//test:2025年1月8日16:45:05
//pop()方法:弹出,删除并返回数组的最后一个元素。
//push()方法:拉长,向数组的末尾添加一个或多个元素,并返回拉长之后数组的长度
//reverse()方法:倒序,颠倒数组的顺序,返回修改后的数组本身
//shift()方法:移除,删除并返回数组的第一个元素,先进先出,队列,其他的元素向前移动.
    /*注:队列:有顺序,按时间处理的系统,确保了请求和任务处理的公平性,更符合人类直觉.
    在C语言中如果要这样操作,那就需要更改每个位置的元素,所以我们给数组添加顺序一般添加到 末尾,为什么JavaScript能这样?答:JavaScript的数组是动态分的,数组元素在内存中的位置不一定是连续的.数组是对象,对象的属性时可以动态改变的.除外,JavaScript 提供了对数组的高级抽象,背后处理了很多底层细节。可以让开发者不必考虑一些底层问题
    */
//unshift()方法:移除的反义词,添加,向数组的开头添加一个或多个元素,并返回新的长度
//slice()方法:切片,从数组中提取一部分并返回。其中start的值是必需的,规定从何处开始选取。可以为负数。end的值是可选的,规定从何处结束选取,如果没有设置,默认为从start开始选取到数组后面的所有元素。该方法不会修改数组,只会返回值
var slice_a =[1 ,2 ,3 ,4 ,5 ,6];
console.log(slice_a.slice(2 ,5));
//splice()方法,拼接剪接,用于删除或替换当前数组的某些项目.语法为arrayObject.splice(start ,deleteCount ,options);
                                            //其中start的值是必需的,规定删除或替换项目的位置
                                            //deleteCount的值是必需的,规定要删除的项目数量,如果设置为0,则不会删除项目
                                            //option的值是可选的,规定替换它的新项目
                                            //和slice()方法不同的是,splice()方法会修改项目
var splice_s = [1 ,2 ,3 ,4 ,5, 6];
splice_s.splice(2 ,2 ,"abc");   //012从序号为2的元素开始删,删两个,然后把删掉的部分替换为"abc"
//sort()方法,排序,会改变原始数组!,语法为arrayObject.sort(sortby).其中sortby这个参数可选,参数必须为函数,在这个函数中,传入a和b的值,若传出的结果为大于零的数字,则说明前者比后者更靠前。没参数的话,默认按字符编码排序
var sort_arr1 = ["a" ,'z' ,'k' ,'w' ,'x'];
document.write( 
    `<div class ="sort_arr1_resultDiv" style="background-color : lightblue";>
    ${sort_arr1}
    </div>`  );   //注:write方法只能在加载过程中使用,如果使用了defer标签,现代浏览器禁止在文档加载完成后使用document.write
document.getElementById("head1").innerHTML += 
    `<div class ="sort_arr1_resultDiv" style="background-color : #007acc";>
    ${sort_arr1.sort()}
    </div>`
//数字排列-从小到大
function sortNum_ByOlder(a ,b){
    return a - b;   //从小到大排序
}
function sortNum_ByOlderRev(a ,b){
    return b - a;   //从大到小排序,(b - a)相对于(a - b)来说是绝对值
}
var sort_arr2 = [11 ,55 ,22 ,44 ,66 ,33];
let sort_arr2_div = document.createElement('div');
sort_arr2_div.className = "sort_arr2_divClass";
sort_arr2_div.style.backgroundColor = "#a47aee";
sort_arr2_div.innerHTML += (sort_arr2.sort(sortNum_ByOlder) + "<br \>"  );
document.body.appendChild(sort_arr2_div);
//数字排序-从大到小
var sort_arr4 = [1 ,22 ,44 ,6 ,55 ,5 ,2 ,4 ,66];
let sort_arr4_div = document.createElement('div');
sort_arr4_div.className = "sort_arr4_divClass";
sort_arr4_div.style.backgroundColor = "#8eaa85";
sort_arr4_div.innerHTML += (sort_arr4.sort(sortNum_ByOlderRev) + "<br \>");
document.body.appendChild(sort_arr4_div);   //  appendchild后面放DOM元素
//toString()方法,把数组转化为字符串,并返回结果
 
/*2.String对象 
常用属性:length,获取字符串长度*/
//charAt()方法,获取指定位置处的字符.StringObject.charAt(index);index是下标.字符串的第一个字符的下标是0.如果参数不在0与String.length之间,该方法则返回一个空字符串
var charAt_str = "Hello World!";
let charAt_str_div = document.createElement('div');
charAt_str_div.className = "charAt_str_divClass";
charAt_str_div.style.backgroundColor = "#7762c8";
charAt_str_div.innerHTML += (charAt_str.charAt(2) + "<br \>");
document.body.appendChild(charAt_str_div);
//conct()方法,连接字符串,等效于“+”,“+”,更常用,与数组中的concat()方法类似
var concatstr_a = "hello world!";
var concatstr_b = "shiyanlou";
console.log(concatstr_a.concat(concatstr_b));
//slice()方法,提取字符串的片段,并在新的字符串中返回被提取的部分
//indexof()方法,检索字符串
//toString()方法,返回字符串
//toLowerCase()方法,把字符串转换为小写
//toUpperCase()方法,把字符串转换为大写
//replac()方法,替换字符串中的某些部分
//split()方法,把字符串分割为字符串数组
 
/*3.Data对象 */
//Date()方法,返回当前的日期和时间
//getDate()方法,从Date对象中返回一个月中的某一天(1-31)
//getDay()方法,从Date对象中返回一周中的某一天(1-6)
//getMonth()方法,从Date对象中返回月份(0-11)
//getFullYear()方法,从 Date对象中以四位数字返回年份
//getHours()方法,返回Date对象的小时(0-23)
//getMinutes()方法,返回Date对象中的分钟(0-59)
//getSecond()方法,返回Date对象中的秒数
//getMilliseconds()方法,返回Date对象中的毫秒(0-999)
 
/*4.Math对象
常用属性:*/
//E属性,返回常数e(2.7118281828...)
console.log(Math.E.toPrecision(100) ,Math.PI.toFixed(100));
//LN2属性,返回2的自然对数ln2
//LN10属性,返回10的自然对数ln10
//LOG2E属性,返回以2为底的e的对数(log2e)
//LOG10E属性,返回以10为底的e的对数(log10e)
//PI属性,返回π
//SQRT1_2属性,返回1/2的平方根
//SQRT2属性,返回2的平方根
/*常用方法: */
//abs(x)方法,返回x的绝对值
//round(x)方法,返回x四舍五入后的值
//sqrt(x)方法,返回x的平方根
//ceil(x)方法,返回大于等于x的最小整数.ceil天花板向上取整
//floor(x)方法,返回小于等于x的最大整数,floor地板向下取整
//sin(x)
//cos(x)
//tan(x)
//acos(x)
//asin(x)
//atan(x)
//exp(x),exponential指数,返回e的x次幂
//pow(n,m),返回n的m次幂
//log(x)
//max(a ,b),返回a,b中较大的的数
//min(a ,b),返回a,b中较小的数
//random(),返回大于0小于1的一个随机数
console.log(Math.random().toPrecision(50));
 
//3.4 创建对象和访问对象
//1.通过对象字面量来创建
var literal_student = {
    name:"zhangsan" ,
    age: 18 ,
    gender: "male",
    sayHi: function (params) {
        console.log("hi , my name is " + this.name);
    },
};
//在控制台输入student.gender可以调用对象的属性,输入student.sayHi()可以调查用对象的方法
//通过上面的例子你会发现对象的属性和方法都通过"."来调用
//2.通过new Object()创建对象
var newObject_student = new Object();
(newObject_student.name = "zhangsan"),
(newObject_student.age = 10),
(newObject_student.gender = "male"),
(newObject_student.sayHi = function (params) {
    console.log("hi,my nane is" + this.name);
});
//3.通过工厂函数创建对象
function createStudent(name ,age ,gender){  //定义了一个名字叫createStudent的工厂函数。这个函数用来创建和返回一个新的对象
    var factory_student = new Object(); /*创建了一个空对象factory_Student..new Object()会返回一个空对象
                                        
                                        工厂函数是手动在函数体里面使用new var了一个对象,然后再用return返回了回去(但是也可以在调用的时候在函数名前面加上new关键字来自动创建并绑定),而且由于是在函数体里面创建并返回的,所以每个传入并创建的对象都有独立的内存空间,会比较占内存,如果在工厂函数中定义方法,每个对象实例都会有一份独立的副本,导致较高的内存占用..因此,工厂函数适用于简单的对象创建,但是在需要大量对象共享方法的情况下,使用构造函数+prototype会更加高效
                                    
                                        */
    
    factory_student.name = name;    //将传入的值赋值给
    factory_student.age = age;
    factory_student.sayHi = function (params) {
        console.log("hi,my name is" + this.name);   //this.name会引用当前对象的name属性
    };
    return factory_student;    //注意返回值..用于返回创建的学生对象
}
var factory_s1 = createStudent("zhangsan" ,18 ,"male");
//4.自定义构造函数来创建对象
function custom_student(name ,age ,gender){ //创建了一个函数,传入name,age,gender
    this.name = name;   
    this.age = age;
    this.gender = gender;
    this.sayHi = function (params) {
        console.log("hi ,my name is " + this.name);
    }
}
var s1 = new custom_student("zhangsan" ,18 ,"male");   //当使用关键字new调用一个函数是,会自动创建一个新对象并绑定到this上
 
//3.5 prototype属性
//什么是prototype?  这是一个属性,指向一个对象,这个对象可以用来存储共享的属性和方法,从而实现对象实例之间的复用..
//每个函数(包括构建函数在创建时,都会自动创建一个prototype属性,该属性指向一个空对象,这个对象的是用来存储可以被共享的属性和方法
 
//3.6一些关键字 
//1.new关键字
//构建函数是一种很特殊的函数.主要用来在创建对象时初始化对象,即为对象成员赋初值,总与new运算符一起用在创建对象的语句中.这里有特别注意的几点:
//*构建函数用于创建一类对象,首字母要大写
//*内部使用this关键字给对象添加初值
//*使用new关键字调用对象构造函数
 
//2.this关键字
//谁调用this,它就是谁
//函数在执行this时2是不确定的,只有在调用的时候才可以确定
//普通函数被直接调用时(不是通过对象的方法,或者特定绑定),函数内部的this默认指向全局变量.在浏览器环境中,全局变量就是Window
function DefultThis_test(){
    console.log(this);
}
//当函数被作为一个对象的方法被该对象调用时,那么this指向的就是该对象
//构造函数中的this,始终是new的当前对象
 
//3.7 历遍对象的属性
//通过for...in语句用于历遍数组或者对象属性,对数组或对象属性进行循环操作
var cycle_student ={
    name :"zhangsan",
    age :18,      //之所以不使用"",是因为尽管有强制类型转换,但是当使用+运算符的时候,仍然会视为拼接而不是加法,因此应该要明确类型
    gender :"male"
};
/*for循环用法:for..in是专门设计用于对象属性遍历的结构,结构为定义一个循环变量用于某个对象,历遍对象中的可枚举属性,并将对象的每个属性名依次赋值给循环变量,然后依次执行循环体
for (var key in object) {
    // 在每次迭代时,key 是对象中的一个属性名
    // 通过 object[key] 可以访问对应属性值
}
相比于for循环,for..in会自动完成初始化,条件判断,更新操作..
*/
console.log("before delete:");
 
for (var cycle_key in cycle_student){   /*
                                        注:cycle_key是一个变量,当中存储的是该对象的所有属性的名字*/
 
    console.log("cycle_student." +cycle_key +":" +cycle_student[cycle_key]);
}
 
//3.8 删除对象的属性
//使用delete操作符删除对象的属性
//delate返回true或flase,被delete的对象不存在时也会返回true,只有对象存在而且有DontDelete属性时才返回flase
console.log("after delete:");
delete cycle_student["name"]; //naem(不加引号)会被认为是一个变量,找不到变量就会删不了..而不加引号表示这是一个属性的名字
delete cycle_student.age;   //也可以用点语法
for (var cycle_key in cycle_student){   /*
                                        注:cycle_key是一个变量,当中存储的是该对象的所有属性的名字*/
 
    console.log("cycle_student." +cycle_key +":" +cycle_student[cycle_key]);
}
 
//3.9 写一个函数,格式化日期对象,最终输入形式为:yyyy/MM/dd HH:mm:ss。
//这里再详细讲解一下date对象。
//在赋值的时候可以new一个date对象,
// 当Date(),也就是没有传入值的时候,此时的return值类似"2025-01-17T13:48:42.491Z"..当有传入值的时候,会把参数格式化为上面的形式
var format_date_Milliseconds = 0;
var format_date_date = new Date();
function format_date() {
    format_date_date = new Date();
    var format_date_year = format_date_date.getFullYear();
    var format_date_mouth = (format_date_date.getMonth() + 1).toString().padStart(2 ,'0');  //pad填充padding,start在开头,padstart在开头填充
    var format_date_day = format_date_date.getDate().toString().padStart(2 ,'0');
    var format_date_hour = format_date_date.getHours().toString().padStart(2 ,'0');
    var format_date_minute = (format_date_date.getMinutes()).toString().padStart(2  ,'0');  //toString()是方法,调用的时候必须加()*2
    var format_date_second = format_date_date.getSeconds().toString().padStart(2 , "0");
    format_date_Milliseconds = format_date_date.getMilliseconds().toString().padStart(3 ,"0")
    return (
      format_date_year +
      "/" +
      format_date_mouth +
      "/" +
      format_date_day +
      " " +
      format_date_hour +
      ":" +
      format_date_minute +
      ":" +
      format_date_second +
      "\t" +
      format_date_Milliseconds
    );
 }
console.log(format_date());
var forpro_i = 0;
var TextEncoder = document.createTextNode("过去了一毫秒");
var forpro_tiemout = setInterval(
    function(){
        
    if (format_date_date.getMilliseconds() != format_date_Milliseconds) {   //注意是!=
        document.getElementsByClassName("forpro")[0].appendChild(TextEncoder);
        }
        //因为多个元素可以共享同一个类名,所以通过元素名选择的返回值就是一个数组,在使用是要指定数组的第几个元素
        document.getElementById("forpro_container_divId").innerHTML += 
                                                                        `<pre> ${format_date()}</pre>  
                                                                        `;
        forpro_i++;
        document.getElementById("forpro_timer_divId").innerHTML = `<p style="font-size: 24px;margin:0 0 0 0;">你发呆了${forpro_i}秒</p>`;
        var forpro_container_div_scrollHeight = document.querySelector("#forpro_container_divId").scrollHeight;
        document.querySelector("#forpro_container_divId").scrollTop = forpro_container_div_scrollHeight;    //在css中,是通过.来选中class,表示该选择器适用于所有拥有该类的元素..在css中,使用#来选中id
} ,1000
);
 
//3.10 总结
//这节课学习了常用的内置对象 Array对象,String对象,Date对象,Math对象
//还有创建和访问对象
 
//4.1 web api
//浏览器是一个封装较为完善的软件,它给我们提供了操作浏览器功能和页面元素的接口。在本节中,我们将对这些接口进行学习
//web api 是浏览器提供的一套操作浏览器功能和界面元素的api(bom和dom)。
 
//4.2 bom简介
//browse Object model 浏览器对象模型,指的是由web浏览器暴露的所有对象组成的表示模型。bom和dom(document Object model文档操作模型)不同,既没有标准的实现,也没有严格的定义,所以浏览器厂商可以自由地实现BOM
//作为显示文档的窗口,浏览器程序将其视为对象的分层集合。当浏览器分析文档时,它将会创建一个对象的集合,以定义文档,并详细说明它应如何显示。浏览器创建的对象称为文档对象,它是浏览器使用的更大对象集合的一部分。此浏览器集合对象统称为浏览器对象模型或BOM
 
// BOM顶级对象window以及常用的操作方法
//window是浏览器的顶级对象,当调用Window下的属性和方法时,可以忽略window
 
//对话框
//alert() 显示带有一段消息和一个确认按钮的警告框
//prompt() 显示可提示用户输入的对话框
//confirm()显示一段消息以及确认按钮和取消按钮的对话框
 
//页面加载事件
//onload
window.onload = function () {
    //当页面完成加载时执行
    //即当页面完全加载所有内容时(包括图像,脚本文件,css文件等),执行
};
//onunload
window.onunload = function (){
   
    //当用户完全退出页面时执行
};
 
//获取浏览器宽度
var window_width = window.innerWidth;   //窗口内部的宽度,包含浏览器窗口的内容宽度,包括滚动条的宽度,使用在需要获取窗口的总可视宽度时
console.log(window_width + "\n" +
    document.documentElement.clientWidth + "\n" +   //获取html文档的宽度,即<html>的可见宽度,不包含滚动条的宽度,在当需要精确控制内容宽度而忽略滚动条时使用
    document.body.clientWidth);    //<body>元素的宽度,可能会被超宽元素撑大,不包含滚动条的信息
 
//获取浏览器高度
var window_height =window.innerHeight;
console.log(window_height + '\n' +
            document.documentElement.clientHeight + '\n' +
            document.body.clientHeight);
 
//定时器
//setTimeout()方法,在指定的毫秒数到达之后执行指定的函数,只执行一次..
//clearTimeout()方法取消由setTImeout()方法设置的timeout
//创建一个定时器,2000毫秒后执行
var timerId = setTimeout(
    function(){
        console.log("Hello shiyanlou");
    } ,2000
);
//取消定时器的执行
clearTimeout(timerId);
 
// setInterval()方法,设定定时调用的函数,也就是可以按照给定的时间(单位毫秒)周期调用函数,
//clearInterval()方法,取消由setInterval()方法设定的timeout
//创建一个定时器,每隔两秒调用一次
var timerId = setInterval(
    function(){
        var date = new Date();
        console.log(date.toLocaleDateString());
    } ,1
);
clearTimeout(timerId)
 
//4.3 DOM简介
    //文档对象模型(document Object Model,简称DOM),是W3C组织推荐的处理可拓展标志性语言的标准编程接口。DOM定义了访问HTML和XML文档的标准。我们这里主要学习HTML DOM。DOM可以吧HTML看成是文档树,通过DOM提供的API可以对树上的节点进行操作
    //DOM能改变HTML输出流:在JavaScript中,使用document.write("新设置的内容<p>标签也可以生成</p>")可以直接像html输出流写内容
    document.write("<div style = 'background-color:#ce70d6'>新设置的内容<p style='margin:0 0 0 0;' id='p1'>标签也可以生成</p></div>");
    //字符串中的双引号会与hrml标签的双引号冲突..对此,可以是使用单引号'来包裹html标签的属性值,或者使用转义,也就是用两个\"p\包裹
//改变HTML内容,使用innerHTML属性改变HTML内容.比如修改标签p中的内容
document.querySelector("#p1").innerHTML = "hello 实验楼";
//改变html属性
document.querySelector("#p1").id = "p2";
try {
    document.querySelector("#p1").innerHTML = "hello ";
} catch (error) {
    console.log("发生错误,但已忽略:"  ,error); 
} //会报错选不到,然后会影响后续代码的执行
 
// DOM节点
    //根据W3C的html dom标准,html文档中的所有内容都是节点:整个文档就是一个文档节点,而每个HTML标签都是一个元素节点。html标签中的文本则是文本节点,html标签;则是属性节点,一切都是节点
        //document-文档节点-整个文档 window.document
        //documenttype-文档类型节点-文档的类型
        //element-元素节点-html元素(比如<body><div>等)
        //attribute-属性节点-html元素的属性(比如class="right")
        //text-文本节点-html文档中出现的的文本
        //documentfragment-文档碎片节点-文档的片段
 
//Dom节点的操作
//获取节点
    //要操作节点,首先我们要找到节点.主要有以下三种方法:
        //1.通过id找到html元素
        //2.通过标签名找到html元素:使用方法getELementByTagName()来选取元素..如果有多个同类型标签那么我们可以通过下标来确认,比如:
document.getElementsByTagName("div")[0];
//下标为[0]表示选取第一个div标签,
document.getElementsByTagName("div")[1];
//下标为[1]表示选取第2个div标签
        //3.通过类名来找到html标签
            //使用方法getElementsByClassName()通过元素的类名来选取元素
console.log( document.getElementsByClassName("forpro_container_divClass"));
//返回包含class="name"的所有元素的一个列表
//DOM节点之间的关系
        //DOM的节点并不是孤立的,我们从DOM树中可以看出,节点和节点之间存在相对关系,就如同一个家族一样,有父辈,有兄弟,有儿子等.下面我们来看一下有哪些节点:
        //父节点 parentNode
        //兄弟节点 nextSibiling nextELementSibiling previousSibiling previousELementSibiling
        //子节点 firstChild firstELementChild lastChild lastELementChild
        //所有子节点 childNodes children
    //例如,在下面这个文档中
    /*<html>
        <head>
            <title>DOM 节点演示</title>
        </head>
        <body>
            <h1>我是h1标签</h1>
            <p>我是p标签</p>
        </body>
    </html> */
        //<html>节点没有父节点,它是根节点
        //<head>和<body>的父节点是<html>节点
        //文本节点 我是p标签 的父节点是<p>节点
        //<html>节点有两个子节点<head>和<body>
        //<h1>节点和<p>节点是兄弟节点,同时也是<body>的子节点
    //需要注意以下几点:
        //childNodes 它是标准属性,它返回指定元素的子元素集合,包括html节点,所有属性,文本节点
        //children 非标准属性,它返回指定元素的子元素集合.但让只返回html节点,甚至不返回文本节点
        //nextSibiling和preViousSibiling获取的是节点,获取元素对应的属性是nextELementSibiling和previousELementSibiling
        //nextELementSibiling和previousELementSibiling有兼容性问题,Ie9以后才支持
//DOM节点的操作
    //1.创建节点
        //创建元素节点,使用createELement()方法.比如
var dom_par = document.createElement("p");
        // 创建属性节点,使用createAttribut()方法
var dom_par_attr = document.createAttribute("background-color:red");
dom_par.setAttribute("style" ,"margin:0 0 0 0");  //属性是附加到元素节点上的,不属于子节点,不能用append..append是用来插入子节点的..要用setAttribute()..而margin不是属性名,是css的一个字符串,提到style的时候,后面要直接跟一个字符串作为样式的参数。或者用点语法对创建出来的或选中的div的style进行修改
 
        //创建建文本节点,使用createTextNode()方法
var dom_par_node = document.createTextNode("hhh");
    //2.插入子节点
        // appendChild()方法向节点添加最后一个子节点
document.querySelector("#dom_parID").append(dom_par);   //appendChild是较早的api,兼容性强。但是一次只能添单一节点,而append可以添加多个节点,而且可以添加字符串文本
 
        //insertBefore(goal_node ,point_node)方法在指定的子节点前面插入新的子节点..如果第二个参数没写或者为null,则默认插入到后面
    //3.删除节点
        //使用removeChild()方法.写法为
        //父节点.removeChild(子节点);
        //node.parentNode.removeChild(node);    如果不知道父节点是什么,可以用点语法获取,也就是可以这样写
    //4.替换子节点
        //使用replaceChild()方法.语法为:
        //node.replaceChild(newnode ,oldnode)   //后面是被替换的目标
    //5.操作节点的属性
        //获取getAttribut(属性名);
        //设置setAttribut(name ,value);
// dom_par.setAttribute(dom_par_attr)
        //删除removeAttribut(name);
console.log(document.querySelector("#dom_parID").getAttribute("id"));
//DOM事件
    //事件的定义
        //在什么时候执行什么事
    //事件三要素
        //事件由事件源 +事件类型 +事件处理程序 组成
            //事件源:触发事件的元素
            //事件类型:触发事件的方法(比如鼠标点击或键盘点击)
            //事件处理程序:事件触发以后要执行的代码
    //常用的事件
        //onclick onclick鼠标单击
        //ondbclick ondbclick鼠标双击
        //onkeyup onkeyup按下并释放键盘上面的一个按键时触发
        //onchange onchange文本内容或下拉菜单中的选项发生改变
        //onfocus onfocus获得焦点,表示文本框等获得焦点..配合失去焦点使用,可以做到仅在获得焦点的时候显示提示信息
        //onblur onblur失去焦点,表示文本框等失去焦点
        //onmouseover onmouseover鼠标悬停,即鼠标停留在图片等的上方
        //onmouseout onmouseout鼠标移出,即离开图片等所在的区域
        //onload onload网页文档加载事件
        //onunload 关闭网页时
        //onsubmit 表单提交时
        //onreset 重置表单时
 
//5 值类型和引用类型及其异常
//5.1值类型和引用类型
    //值类型
        //以下变量中存储的是对应的值,值和变量名都存储在栈中
        //值类型又叫基本数据类型,原始类型,在JavaScript中值类型有以下五种
            //数据类型
            //布尔类型
            //undefined
            //null
            //字符串
var Primitive_num = 18;
var Primitive_flag = true;
var Primitive_un = undefined;
var Primitive_nu = null;
var Primitive_str = "zhangsan";
    //引用类型
        //引用类型又称复合数据类型,在JavaScript中引用类型有以下三种
            //对象
            //数组
            //函数
        //引用类型存储在堆中
        //变量名存储在栈中,里面的值是地址,指向存储对象的内存处
var Reference_arr = [1 ,2 ,3];
var Reference_p = {
    name :"张三",
    age :18
};
 
//5.2 值类型和引用类型的特征
    //值类型的特征
        //值类型的值是不可变的,不可变指的是值类型指向的空间不可变,例如
var Primitive_a = 2;
/*JavaScript 在栈内存中为变量 a 分配空间,并将值 2 存储在栈上的一个地址位置(假设是地址 A)。
然后a 变量现在指向这个地址 A,也就是存储 2 的位置*/
Primitive_a += 2;
console.log(Primitive_a);
            //也就是a变量指向的地址值变了,但是内存中2的地址值没有变
        //按值传递的变量之间互不影响,比如
var Primitive_b = Primitive_a;
/*JavaScript复制了一份a的值到其他地方,然后让b指向这个地方 */
Primitive_a = Primitive_a + 2;
console.log(Primitive_a ,Primitive_b);
        //再看下面一段代码
console.log(Reference_p.name ,Reference_p.age);
var Reference_p1 = Reference_p;
Reference_p1.name = "李四";
console.log(Reference_p.name ,Reference_p.age)
/*因为Reference型变量存储的是地址,复制的时候也仅仅是把地址复制了一份,所以改变p1指向的对象的内容也改变了p指向的对象的内容。*/
function foo(o){
    o.age += 1; //注意,当数据类型为字符串时,哪怕用+=1,也是在字符串后面加上“1”这个字符
}
foo(Reference_p);
console.log(Reference_p.age);
/*同样地当参数为引用类型时,函数内和函数外的两个变量不同,但是共同指向同一个对象,在函数修改对象数据时会影响外部
注:其实我们可以这样理解。引用数据类型中的地址是一把钥匙,钥匙指向的是宝藏,复制一把钥匙后,两把钥匙打开的是同一个宝藏 */
 
//5.3 调试工具的使用
//在调试的时候,可以加一句console.log()语句来打印出来
    //设置断点,逐步运行
        //设置断点的方案很简单,直接左键点击代码旁边的数字行数
        //选中右键选择将变量加入watch窗口,实时查看它的值的变化
        //然后刷新,点击运行,可以逐段运行代码
 
//5.4 异常处理
    //当出现错误时,JavaScript引擎通常会停止,并生成一个错误信息
    //异常捕获
        //可以使用try-catch语句捕获异常
try {
    //这里写可能出现异常的代码
} catch (error) {   //给错误信息赋个形参
    //执行的代码
}
        //注意:
            //语句try和catch是成对出现的
            //如果在try中遇到了错误,try里面出现错误的语句后面的代码都不执行,直接跳转到catch中,catch处理错误的信息
            //如果try中没有出现错误,则不会执行catch中的代码,执行完try中的代码直接执行后面的代码、
            //在try或catch执行完以后,代码会继续执行,不会中断
    //throw语句
        //通过throw语句,我们可以创建自定义错误。throw语句通常和try catch语句一起使用
 
        
 
 
//7 函数进阶
//在前面的课程中,我们已经学习了一下这些函数的相关内容:函数声明,函数表达式和function()构造函数,以及函数的参数,返回值,调用..现在我们将继续学习函数进阶的内容..
//7.1 call apply bind
    //在学习call(),apply(),bind()方法之前,我们先来复习一下this的指向性问题,我们前面说过一个口诀:谁调用this,它就指向谁..让我们先来看一个例子
function this_foods() { }
this_foods.prototype = {
    price: "¥15",
    say: function () {
        console.log("My price is" + this.price);
    }
};
 
var this_apply = new this_foods();
this_apply.say();
var this_orange = new this_foods();
this_orange.say();
 
    //也就是说上述例子调用say()方法,最后打印的结果都是一样的,但是如果我们想打印橘子的价格是10元呢?又不想重新定义say()方法..JavaScript为我们专门提供了一些函数方法来帮我们更优雅第处理函数this指向问题..这就是我们接下来要学习的call() ,apply() ,bind()三个函数方法
    //call
        //call()方法调用一个函数,其具有一个指定的this值和分别地提供的参数(参数的列表)..语法为
            //fun.call(thisArg ,arg1 arg2)
        //注: thisArg指的是在fun函数中指定的this的值..如果指定了null或者undefined,则内部的this指向window,同时,值为原始值(数字 ,字符串 ,布尔值)时,this会自动指向原始值,是一个可选项
            //arg1 ,arg2 ,...指定的参数列表,也是可选项
            //
            //call()允许为不同的对象分配和调用属于一个对象的函数/方法..你可以使用call()来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新的对象中在写一次这个方法)
        //1.使用call()方法调用函数并指定上下文的this..前面的例子可以写成
        var this_apple = new this_foods();
        this_orange = {
            price: "¥10",
        }
        this_apple.say.call(this_orange);   //使用call让console.log("My price is" + this.price);里面的this指向this_orange
        //2.在一个子构造函数中,你可以通过调用父构造函数的call()方法来实现继承
        //
    //apply
        //apply()方法和call()方案类似,唯一的区别是call()方法接受的是参数,apply()方法接受的是数组,语法为
        //fun.apply(thisArg ,[argsArray]);
        //例子:
var apply_array = ["a" ,"b" ,"c"];
var apply_nums = [1 ,2 ,3];
apply_array.push.apply(apply_array ,apply_nums);
//注:使用concat()方法链接数组,不会改变数组,而是创建一个新数组..而使用push()是接受可变数量的参数的方式来添加元素..使用apply则可以链接两个数组..使用apply是为了将指定的数组变更为这两个数组
console.log(apply_array);
    //bind
        //bind()方法创建一个新的函数(称为绑定函数),在调用时设置this关键字作为提供的值
        //bind()方法用于绑定到一个函数,当绑定函数被调用时,参数thisArg会作为原函数运行时的this指向
//递归
//在函数中,递归就是自己直接或间接的调用自己
//例子:计算1到10之间 的整数相加的和
function recurrence_foo(n){
    if(n==0){
            return 0;
    }else{
        return n+recurrence_foo(n-1);
    }
}
var recurrence_a = recurrence_foo(10);
console.log(recurrence_foo(10));
console.log(recurrence_a);
 
//7.2 作用域
//作用域就是变量和函数的课访问范围
//在JavaScript中是没有块级作用域 的,即不会把{}扩在一起的代码视为一个作用域,例如
{
    var block_num = 123;
    {
        console.log(block_num);
    }
}
console.log(block_num);
 
//7.3 闭包
//7.4 arguments对象
    //在函数代码中,使用特殊对象argument,无需明确指出变量名,我们就能访问它们..第一个参数是argument[0] ,第二个参数是argument[1] ,以此类推..比如:
function arguments_foo(params) {
    console.log(arguments[0]);  //取传入参数的第一个
    console.log(arguments[1]);
}
arguments_foo(2 ,3);    //打印2 3
    //还可以用arguments对象检测函数参数个数,引用argument.length即可..来看一个历遍参数求和的例子
function arguments_add(){
    var arguments_sum = 0;
    for(var i = 0;i < arguments.length;i++){
        arguments_sum += arguments[i]; 
    }
    console.log("参数的个数为:" + arguments_sum);
}
arguments_add();    //0
arguments_add(1);   //1
arguments_add(1 ,2);    //3
arguments_add(1 ,2 ,3); //6
 
//7.5 function对象
    //function()对象创建函数的语法如下
    //var function_name = new Function(arg1 ,arg2 ,... ,argN ,Function_body)
    //注意:每个参数都必须是字符串,Function_body是函数主体..
    //直接new一个Function出来,直接把参数和函数体都塞进去

希望这些笔记对你有所帮助,感觉不错的话,动手点个赞吧,祝学习顺利。


timeRATE
1 声望0 粉丝