JavaScript学习笔记

前言:
学习B站UP主狂神说视频笔记整理视频链接
文章参考廖雪峰的官方网站

简介

前端三要素:HTML(结构),CSS(展示),JavaScript(行为)

什么是JavaScript

JavaScript(简称“JS”)
是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript
基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格

JavaScript的标准是ECMAScript 。截至 2012 年,所有浏览器都完整的支持ECMAScript 5.1,旧版本的浏览器至少支持ECMAScript 3 标准。2015年6月17日,ECMA国际组织发布了ECMAScript的第六版,该版本正式名称为 ECMAScript 2015,但通常被称为ECMAScript 6 或者ES2015。

什么是ECMAScript

ECMAScript是一种由Ecma国际通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展

最新版本已经到es6版本~
但是大部分浏览器还只停留在支持es5代码上!
开发环境—线上环境,版本不一致

快速入门

在HTML书写JS的方式(掌握)

方式一:<script>标签内写入JavaScript代码

<head>
...
 <!--方式一:<script>标签内写入JavaScript代码-->
    <script>
        alert("helloJavaScript")
    </script>
</head>

script标签可以放在head或body或页面的其他位置中,通常会放在head或body中

方式二:通过<script>标签引入外部的JS文件

<head>
...
<!--方式二:引入外部JS 注意不能使用自闭和标签-->
<script src="js/hello.js"></script>
</head>

下`

  • 1.方式二引入不能使用自闭和标签,必须成对出现
  • 2.如果script标签是用于引入JS文件的,就不要在该标签内部再书写JS代码,否则写了也不会执行!

控制台与严格检查模式

控制台

浏览器F12打开控制台
在这里插入图片描述
Debug断点调试
在这里插入图片描述
浏览器本地存储
在这里插入图片描述

严格检查模式

JavaScript是门非常随意的语言,为了防止它的随意性产生的问题,通过设置use strict检查代码

使用步骤:
1.IDEA中设置支持EC6语法
在这里插入图片描述

2.定义use strict

必须写在<script>第一行

<script>
     "use strict"
     let i=1;
</script>

语法入门

在JavaScript中严格区分大小写

注释格式

JS的注释符合和Java的注释符合相同,如下:

// 单行注释内容
/* 多行注释内容 */

数据类型

基本数据类型

JS的基本数据类型一共有五种,分别为数值类型(number)、字符串类型(string)、布尔类型(boolean)、undefined、null。

(1)数值-numbe

在JS中不区分整数和浮点数

说明案例
整数123
浮点数123.1
科学计数法1.123e3
负数-99
NaNnot a number
Infinity无穷大

注意点:
尽量避免使用浮点数进行运算,存在精度问题

(2)字符串

1.JS中的字符串是基本数据类型,和Java中不同的是,JS中的字符串可以用单引号或双引号引起来。

<script>
        var str1 = "Hello JS";
        var str2 = 'Hello JS';
</script>

2.注意转译字符\

<script>
        var str1 = "Hello\'";//输入引号
        var str2 = 'Hello \n JS'; //换行
</script>

3.多行字符串编写,使用``符号包裹

<script>
        var str1 = `1234567
        22222222222211111`;//与Java不同的是 不用+号连接
</script>

注意:反引号在键盘的ESC下方,数字键1的左边:
在这里插入图片描述

4.模板字符串

<script>
      var name= "秦疆";//定义模板
      var hello="你好,${name}";//引入模板
</script>

5.字符串长度
与Java一样,字符串具有不变性

<script>
      var name= "秦疆";
      console.log(name.length);
</script>

6.截取字符串substring

<script>
      var name= "HelloWord";
      console.log(name.substring(1,3));
</script>
(3)布偶值

布尔类型常用条件测试中,值为true和false

(4)null和undefined
  • null:空
  • undefined:未定义

复杂数据类型

JS的复杂数据类型主要指对象 需要注意的是,在JS中,数组、函数也属于对象

数组

Array 对象用于在单个的变量中存储多个值,可以包含任意类型的数据
(1)通过Array构造函数创建数组
例如,声明一个空数组:

var arr1 = new Array();

例如,声明一个指定初始值的数组:

var arr2 = new Array(88,"Hello" ,true , 100);

(2)通过数组直接量创建数组
例如,声明一个空数组:

var arr1 = [];

例如,声明一个指定初始值的数组:

var arr2 = [88,"Hello" ,true , 100];

提示:

  1. 数组的length属性可以返回数组的长度
  2. 如果给arr.length赋值,数组的长度就可以发生变化,数值较小元素就会丢失
  3. 与字符串不同的是,数组具有可变性,如arr[0]=1;
  4. 不同类型的元素是不一样的,如"1" != 1
  5. slice ()截取Array的一部分,返回一个新数组,类似于String中的substring
  6. 使用push()在尾部加入值,pop()从尾部删除值
  7. 使用unshift()在头部加入值,shift()在头部移除值
  8. sort()可以对当前Array进行排序
对象

若干个键值对,在JavaScript中所有键都是字符串,值是任意类型

<script>
/*格式*/
     var user={
            name: "秦疆",
            age: 12,
            sex: "男"
        }
</script>

提示:

  1. 使用不存在的属性,不会报错
  2. 使用delete 对象属性名动态删除属性
  3. 使用hasOwnProperty()判断一个属性是否是这个对象自身拥有的
Map与Set

Map与Set是EC6的新特性

Map:KV键值对

 <script>
     "use strict"
     //EC6新特性 Map Set
     let map = new Map();
     map.set("tom",123);//设置一个元素
     console.log(map.get("tom"));//获取一个元素
     map.delete("tom");//删除一个元素
</script>

Set:无序不重复集合

<script>
     "use strict"
     //EC6新特性 Map Set
     let set = new Set();
     set.add("1");//添加
     set.add("2");
     set.delete("2");//删除一个元素
     console.log(set.has("2"));//是否包含某个元素
</script>
Lterable迭代

遍历数组

<script>
     "use strict"
      var arr=[3,4,5];
      for (let x of arr){
          console.log(x);
      }
</script>

遍历Map

  <script>
     "use strict"    
     var map = new Map( [["tom", 100],[ "jack",90],[ "haha",80]]);
     for (let x of map){
         console.log(x);
     }
</script>

遍历Set

<script>
     "use strict"
     let set = new Set([1,2,3]);
     for (let x of set){
         console.log(x);
     }
</script>

变量声明

在JS中通过var声明变量

<script>
    var a = 10; //声明变量,赋值为数值10
    var b = true; //声明变量,赋值为布尔值true
    var c = "Hello JS"; //声明变量,赋值为字符串"Hello JS"
</script>

在JS中声明的变量不区分类型,可以指向任意的数据类型

<script>
    var x = 10; //声明变量,赋值为数值10
        x = true; //将x赋值为布尔值true
        x = "Hello JS"; 将x赋值为字符串"Hello JS"
</script>

在EC6中通过let声明局部变量更加安全

<script>
    let a= 10; //let声明变量
</script>

JS运算符

JS和Java中的运算符大致相同

算术运算符: +,-,*,/,%,++,--
赋值运算符: =,+=,-=,*=,/=,%=
比较运算符: ==,!=,>,>=,<,<=
位运算符: & , |
逻辑运算符: && ,||
前置逻辑运算符: ! (not)
三元运算符: 表达式 ? 表达式 : 表达式
...

比较运算符(重要)

= 赋值
==  类型不一样 值一样 也会判断为true 1="1"
===  类型一样 值一样才会判断为true

注意点:

  1. 这是js的缺陷 坚持使用===比较
  2. NaN===NaNcy与任何值比较都不相等 包括自己

流程控制

if分支结构

if分支结构用于基于不同的条件来执行不同的动作。语法结构如下:

if (条件 1){
	当条件 1true 时执行的代码
}else if (条件 2){
	当条件 2true 时执行的代码
}else{
	当条件 1 和 条件 2 都不为 true 时执行的代码
}

switch语句

使用 switch 语句来选择要执行的多个代码块之一。语法结构如下:

switch(n){
    case 1:
        执行代码块 1
        break;
    case 2:
        执行代码块 2
        break;
    default:case 1case 2 不同时执行的代码
}

执行原理:首先设置表达式 n(通常是一个变量)。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行。请使用 break 来阻止代码自动地向下一个 case 运行。

for循环语句

for 循环的语法结构如下:

for (语句 1; 语句 2; 语句 3){
	//被执行的代码块
}

while循环

JS中while循环也分为while和do/while循环,下面为while循环语法结构

while (条件){
    //需要执行的代码
}

while 循环会在指定条件为真时循环执行代码块。

函数

定义函数

在JavaScript中,定义函数的方式如下:

function abs(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

上述abs()函数的定义如下:

  • function指出这是一个函数定义;
  • abs是函数的名称;
  • (x)括号内列出函数的参数,多个参数以,分隔;
  • { ... }之间的代码是函数体,可以包含若干语句,甚至可以没有任何语句。

请注意,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。

如果没有return语句,函数执行完毕后也会返回结果,只是结果为undefined

由于JavaScript的函数也是一个对象,上述定义的abs()函数实际上是一个函数对象,而函数名abs可以视为指向该函数的变量。

因此,第二种定义函数的方式如下:

var abs = function (x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};

在这种方式下,function (x) { ... }是一个匿名函数,它没有函数名。但是,这个匿名函数赋值给了变量abs,所以,通过变量abs就可以调用该函数。
上述两种定义完全等价,注意第二种方式按照完整语法需要在函数体末尾加一个;,表示赋值语句结束。

调用函数

调用函数时,按顺序传入参数即可:

abs(10); // 返回10
abs(-9); // 返回9

JS中允许传任意个参数,也可以不传递参数

abs(10, 'blablabla'); // 返回10
abs(-9, 'haha', 'hehe', null); // 返回9
abs(); // 返回NaN

参数进来是否存在问题?
假设不存在参数,如何进行规避?

function abs(x) {
   //手动抛出异常来判断
    if (typeof x !== 'number') {
        throw 'Not a number';
    }
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

typeof

判断参数的类型
格式:

typeof x(参数)

arguments

JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array:

function foo(x) {
    console.log('x = ' + x); // 10
    for (var i=0; i<arguments.length; i++) {
        console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
    }
}
foo(10, 20, 30);

arguments包含所有的参数,有时我们只想使用多余的参数来进行附加操作,需要排除已有参数

rest

ES6的新特性,获取除了已经定义的参数之外的参数

function aaa(a,b,...rest) {
            console.log("a=>"+a);
            console.log("b=>"+b);
            console.log(rest);
        }

rest参数只能写在最后面,并且格式为...rest
在这里插入图片描述

变量作用域

在JavaScript中,用var申明的变量实际上是有作用域的。

如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量:

'use strict';

function foo() {
    var x = 1;
    x = x + 1;
}

x = x + 2; // ReferenceError! 无法在函数体外引用变量x

ps:非要想实现的话,可以研究一下闭包

如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。换句话说,不同函数内部的同名变量互相独立,互不影响:

'use strict';

function foo() {
    var x = 1;
    x = x + 1;
}

function bar() {
    var x = 'A';
    x = x + 'B';
}

由于JavaScript的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行:

'use strict';

function foo() {
    var x = 1;
    function bar() {
        var y = x + 1; // bar可以访问foo的变量x!
    }
    var z = y + 1; // ReferenceError! foo不可以访问bar的变量y!
}

如果内部函数和外部函数的变量名重名怎么办?

function foo() {
    var x = 1;
    function bar() {
        var x = 'A';
        console.log('x in bar() = ' + x); // 'A'
    }
    console.log('x in foo() = ' + x); // 1
    bar();
}

foo();

这说明JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量。

变量提升

JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:

'use strict';

function foo() {
    var x = 'Hello, ' + y;
    console.log(x);
    var y = 'Bob';
}

foo();

运行结果会发现:y=undefined
这正是因为JavaScript引擎自动提升了变量y的声明,但不会提升变量y的赋值。
对于上述foo()函数,JavaScript引擎看到的代码相当于:

function foo() {
    var y; // 提升变量y的申明,此时y为undefined
    var x = 'Hello, ' + y;
    console.log(x);
    y = 'Bob';
}

由于JavaScript的这一怪异的“特性”,我们在函数内部定义变量时,请严格遵守“在函数内部首先申明所有变量”这一规则。最常见的做法是用一个var申明函数内部用到的所有变量:

function foo() {
    var
        x = 1, // x初始化为1
        y = x + 1, // y初始化为2
        z, i; // z和i为undefined
    // 其他语句:
    for (i=0; i<100; i++) {
        ...
    }
}

全局变量

不在任何函数内定义的变量就具有全局作用域。实际上,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性:

       "use strict"
        //全局变量
        var x ="helloWord";
        function foo() {
            alert(x);
            alert(window.x);//默认所有全局变量都会绑定到window对象上
        }

alert()这个函数本身也是一个window变量

"use strict"
//全局变量
var old =window.alert;
old(123);
window.alert=function () {

}
window.alert(345);//失效
window.alert=old;//恢复
window.alert(678);

你可能猜到了,由于函数定义有两种方式,以变量方式var foo = function () {}定义的函数实际上也是一个全局变量,因此,顶层函数的定义也被视为一个全局变量,并绑定到window对象:

'use strict';

function foo() {
    alert('foo');
}

foo(); // 直接调用foo()
window.foo(); // 通过window.foo()调用

Javascript 实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错RefrenceError

规范

由于我们所有的全局变量都会绑定到我们的 window 上,如果不同的js 文件,使用了相同的全局变量,就会引发冲突~>如果能够减少冲突?

"use strict"
//唯一全局变量 不绑定到window上
var listapp={};

//定义全局变量
listapp.name="王根基";
//定义函数
listapp.app=function (x) {

}

把自己的代码全部放入自己定义的唯一空问名字中,降低全局命名冲突的问题–

局部变量

由于JavaScript的变量作用域实际上是函数内部,我们在for循环等语句块中是无法定义具有局部作用域的变量的:

'use strict';

function foo() {
    for (var i=0; i<100; i++) {
        //
    }
    i += 100; // 仍然可以引用变量i
}

为了解决块级作用域,ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量:

'use strict';
function foo() {
    var sum = 0;
    for (let i=0; i<100; i++) {
        sum += i;
    }
    // SyntaxError:
    i += 1;
}

常量

由于varlet申明的是变量,如果要申明一个常量,在ES6之前是不行的,我们通常用全部大写的变量来表示“这是一个常量,不要修改它的值”:

var PI = 3.14;

ES6标准引入了新的关键字const来定义常量,constlet都具有块级作用域:

'use strict';

const PI = 3.14;
PI = 3; // 某些浏览器不报错,但是无效果!
PI; // 3.14

方法

在一个对象中绑定函数,称为这个对象的方法

在JavaScript中,对象的定义是这样的:

var xiaoming = {
    name: '小明',
    birth: 1990
};

但是,如果我们给xiaoming绑定一个函数,就可以做更多的事情。比如,写个age()方法,返回xiaoming的年龄:

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth;
    }
};

xiaoming.name; // 调用属性
xiaoming.age(); // 调用方法必须得带括号

它在内部使用了一个this关键字,这个东东是什么?

一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是xiaoming这个变量。

让我们拆开写:

function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 25, 正常结果
getAge(); // NaN 

单独调用函数getAge()怎么返回了NaN?请注意,我们已经进入到了JavaScript的一个大坑里。

JavaScript的函数内部如果调用了this,那么这个this到底指向谁?

答案是,视情况而定!
如果以对象的方法形式调用,比如xiaoming.age(),该函数的this指向被调用的对象,也就是xiaoming,这是符合我们预期的。

如果单独调用函数,比如getAge(),此时,该函数的this指向全局对象,也就是window

apply
在js中可以控制this的指向

function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空

内部函数

Data

时间函数

基本使用:

 "use strict"
        let dat = new Date();
        dat.getFullYear();//年份
        dat.getMonth();//月份 0-11 代表月
        dat.getDate();//日期
        dat.getDay();//星期几
        dat.getHours();//时
        dat.getMinutes()//分
        dat.getSeconds();//秒
        dat.getTime();//时间戳 全世界统一 1970

转换:

在这里插入图片描述
注意点:调用的是一个方法不是一个属性

JSON

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广泛。

在JavaScript一切皆为对象、任何js支持的类型都可以用JSON来表示;number,string…

格式:

  • 对象都用{}
  • 数组都用[]
  • 所有的键值对都是 key:value

javascript中使用JSON

      //编写一个javascript 对象
        var user= {
            name: "秦疆",
            age: 3,
            sex: "男"
        }
        //将js对象转换成JSON
        var jsonuser = JSON.stringify(user);
        //将JSON字符串转换成JS对象
        var parse = JSON.parse(jsonuser);
        console.log(parse);

面向对象

什么是面向对象

JavaScript的面向对象编程和大多数其他语言如Java、C#的面向对象编程都不太一样。如果你熟悉Java或C#,很好,你一定明白面向对象的两个基本概念:

  • 类:类是对象的类型模板,例如,定义Student类来表示学生,类本身是一种类型,Student表示学生类型,但不表示任何具体的某个学生;

  • 实例:实例是根据类创建的对象,例如,根据Student类可以创建出xiaoming、xiaohong、xiaojun等多个实例,每个实例表示一个具体的学生,他们全都属于Student类型。

所以,类和实例是大多数面向对象编程语言的基本概念。

不过,在JavaScript中,这个概念需要改一改。JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。

原型继承(不推荐使用)

原型是指当我们想要创建xiaoming这个具体的学生时,我们并没有一个Student类型可用。那怎么办?恰好有这么一个现成的对象:

var robot = {
    name: 'Robot',
    height: 1.6,
    run: function () {
        console.log(this.name + ' is running...');
    }
};

我们看这个robot对象有名字,有身高,还会跑,有点像小明,干脆就根据它来“创建”小明得了!

于是我们把它改名为Student,然后创建出xiaoming

var Student = {
    name: 'Robot',
    height: 1.2,
    run: function () {
        console.log(this.name + ' is running...');
    }
};

var xiaoming = {
    name: '小明'
};
//原型 小明指向Student 
xiaoming.__proto__ = Student;

注意最后一行代码把xiaoming的原型指向了对象Student,看上去xiaoming仿佛是从Student继承下来的:

xiaoming.name; // '小明'
xiaoming.run(); // 小明 is running...

xiaoming有自己的name属性,但并没有定义run()方法。不过,由于小明是从Student继承而来,只要Studentrun()方法,xiaoming也可以调用:
在这里插入图片描述
JavaScript的原型链和Java的Class区别就在,它没有“Class”的概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已。

什么是原型链?

在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。

当我们用obj.xxx访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,最后,如果还没有找到,就只能返回undefined
在这里插入图片描述
举个栗子~!
建一个Array对象:

var arr = [1, 2, 3];

其原型链是:

arr ----> Array.prototype ----> Object.prototype ----> null

Array.prototype定义了indexOf()、shift()等方法,因此你可以在所有的Array对象上直接调用这些方法。
当我们创建一个函数时:

function foo() {
    return 0;
}

函数也是一个对象,它的原型链是:

foo ----> Function.prototype ----> Object.prototype ----> null

由于Function.prototype定义了apply()等方法,因此,所有函数都可以调用apply()方法。

很容易想到,如果原型链很长,那么访问一个对象的属性就会因为花更多的时间查找而变得更慢,因此要注意不要把原型链搞得太长。

Class继承(推荐使用)

在上面的章节中我们看到了JavaScript的对象模型是基于原型实现的,特点是简单,缺点是理解起来比传统的类-实例模型要困难,最大的缺点是继承的实现需要编写大量代码,并且需要正确实现原型链。

新的关键字classES6开始正式被引入到JavaScript中。class的目的就是让定义类更简单。

定义

用新的class关键字来编写Student,可以这样写:

class Student {
    //构造器
    constructor(name) {
        this.name = name;
    }

    hello() {
        alert('Hello, ' + this.name + '!');
    }
}
//使用
let student = new Student("王根基");
student.hello();

继承

用class定义对象的另一个巨大的好处是继承更方便了。现在,原型继承的中间对象,原型对象的构造函数等等都不需要考虑了,直接通过extends来实现:

class xiaomin extends Student{
            constructor(name,age){
                //必须调用父类的构造器 否则会报错
                super(name);
                this.age=age;
            }
            helloword(){
                alert("name:"+this.name+"age:"+this.age);
            }
        }

BOM对象

BOM:浏览器对象模型

JavaScript和浏览器关系?

JavaScript 诞生就是为了能够让他在浏览器中运行!

window-浏览器窗口

window对象不但充当全局作用域,而且表示浏览器窗口

window对象有innerWidthinnerHeight属性,可以获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。

兼容性:IE<=8不支持。

window.innerHeight
//210 内部宽度
window.innerWidth
//1280 内部高度
window.outerWidth
//1280
window.outerHeight
//690

还有一个outerWidthouterHeight属性,可以获取浏览器窗口的整个宽高。

navigator-浏览器信息

navigator对象表示浏览器的信息,最常用的属性包括:

  • navigator.appName:浏览器名称;
  • navigator.appVersion:浏览器版本;
  • navigator.language:浏览器设置的语言;
  • navigator.platform:操作系统类型;
  • navigator.userAgent:浏览器设定的User-Agent字符串。

在这里插入图片描述
大多数时候,我们不会使用navigator对象,因为会被人为修改!
不建议使用这些属性来判断和修改代码

screen-屏幕信息

screen对象表示屏幕的信息,常用的属性有:

  • screen.width:屏幕宽度,以像素为单位;
  • screen.height:屏幕高度,以像素为单位;
  • screen.colorDepth:返回颜色位数,如8、16、24。
screen.width
// 1280
screen.height
// 720
screen.colorDepth
// 24

location-URL信息

location对象表示当前页面的URL信息。
在这里插入图片描述
要加载一个新页面,可以调用location.assign()。如果要刷新当前页面,调用location.reload()方法非常方便。

location.reload();//刷新页面
location.assign('https://www.bilibili.com/video/BV1JJ41177di?p=19');//加载新页面

document-文档树

document对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。

获取具体的文档树根节点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HelloScript</title>
    
</head>
<body>
<dl id="app">
    <dt>Java</dt>
    <dd>JavaEE</dd>
    <dd>JavaSE</dd>
</dl>

<script>
    var dl= document.getElementById('app');
</script>
</body>
</html>

JavaScript可以通过document.cookie读取到当前页面的Cookie

document.cookie; // 'v=123; remember=true; prefer=zh'

由于JavaScript能读取到页面的Cookie,而用户的登录信息通常也存在Cookie中,这就造成了巨大的安全隐患,这是因为在HTML页面中引入第三方的JavaScript代码是允许的

Cookie安全性问题

为了解决这个问题,服务器在设置Cookie时可以使用httpOnly,设定了httpOnlyCookie将不能被JavaScript读取。这个行为由浏览器实现,主流浏览器均支持httpOnly选项,IE从IE6 SP1开始支持。

为了确保安全,服务器端在设置Cookie时,应该始终坚持使用httpOnly

history-浏览器历史记录(不推荐使用)

history对象保存了浏览器的历史记录,JavaScript可以调用history对象的back()forward (),相当于用户点击了浏览器的“后退”或“前进”按钮。

history.back();//后退
history.forword();//前进

DOM对象

DOM:文档对象模型
在这里插入图片描述

核心

由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM。

始终记住DOM是一个树形结构。操作一个DOM节点实际上就是这么几个操作:

  • 更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;

  • 遍历:遍历该DOM节点下的子节点,以便进行进一步操作;

  • 添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;

  • 删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点。

在操作一个DOM节点前,我们需要通过各种方式先拿到这个DOM节点。

最常用的方法是document.getElementById()document.getElementsByTagName(),以及CSS选择器document.getElementsByClassName()

获取DOM节点

  //标签选择器
   let h1 = document.getElementsByTagName("h1");
   //id选择器
   let p1 = document.getElementById("p1");
   //class选择器
   let p2 = document.getElementsByClassName("p2");

   let fals = document.getElementById("fals");
   let children = fals.children;//获取父节点下的所有子节点
    // fals.firstChild;获取第一个节点
    // fals.lastChild; 获取最后一个节点

这是原生代码,以后都会使用Jquery

更新节点

<body>
<div id="fals">

</div>
<script>

    let fals = document.getElementById("fals");
    //修改文本的值
    fals.innerText="123";
    //修改超文本
    fals.innerHTML="<a href=\"www.baidu.com\">123</a>";
    //操作CSS
    fals.style.color="steelblue";
    fals.style.fontSize="200px";//注意驼峰命名

</script>
</body>

注意点:属性使用字符串包裹

删除节点

要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉:

    //拿到待删除节点
    let dl123 = document.getElementById("dl123");
    //拿到父节点
    let parent = dl123.parentElement;
    //删除
    let delt = parent.removeChild(dl123);

注意到删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。

使用children可以获取到父节点下所有子节点,它是一个数组可以通过下标获取节点fals.children[1]

当我们用如下代码删除子节点时:

var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 浏览器报错

浏览器报错:parent.children[1]不是一个有效的节点。原因就在于,当<p>First</p>节点被删除后,parent.children的节点数量已经从2变为了1,索引[1]已经不存在了。

插入节点

当我们获得了某个DOM节点,想在这个DOM节点内插入新的DOM,应该如何做?

如果这个DOM节点是空的,例如,<div></div>,那么,直接使用innerHTML = '<span>child</span>'就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。

如果这个DOM节点不是空的那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点。

有两个办法可以插入新的节点。

使用appendChild,把一个已有的子节点添加到父节点的最后一个子节点

<body>


<p id="js">JavaScript</p>
<div id="list">
    <p id="se">javase</p>
    <p id="ee">javaee</p>
    <p id="me">javame</p>
</div>

<script>
   let js = document.getElementById("js");
   let list = document.getElementById("list");
   // 追加到div最后面
   list.appendChild(js);
</script>
</body>

在这里插入图片描述
更多的时候我们会从零创建一个新的节点,然后插入到指定位置:

   //创建方式一:
   let newp = document.createElement("p");
   newp.id="newp";
   newp.innerText="helloword";
   //插入到div最后面
   list.appendChild(newp);

   //创建方式二
    let myscript = document.createElement("script");
    //万能设置值的方式setAttribute
    myscript.setAttribute("type","text/javascript");
   //插入到div最后面
   list.appendChild(myscript);

在这里插入图片描述
还可以插入CSS样式

 //创建style标签
   let mystyle = document.createElement("style");
   //设置CSS样式
   mystyle.setAttribute("type","text/css");
   mystyle.innerText="body{\n" +
       "            background: steelblue;\n" +
       "        }";

   //获取head标签
   let myhead = document.getElementsByTagName("head")[0];
   //插入到子后面
   myhead.appendChild(mystyle);

注意:获取<head>标签时,它在第0个位置
在这里插入图片描述
insertBefore

如果我们要把子节点插入到指定的位置怎么办?

可以使用parentElement.insertBefore(插入节点, 在哪个节点前插入);

    //获取div节点
    let list = document.getElementById("list");
    let ee = document.getElementById("ee");
    let js = document.getElementById("js");
    list.insertBefore(js,ee);

在这里插入图片描述

操作表单

用JavaScript操作表单和操作DOM是类似的,因为表单本身也是DOM树。

不过表单的输入框、下拉框等可以接收用户输入,所以用JavaScript来操作表单,可以获得用户输入的内容,或者对一个输入框设置新的内容。

HTML表单的输入控件主要有以下几种:

  • 文本框,对应的<input type="text">,用于输入文本;

  • 口令框,对应的<input type="password">,用于输入口令;

  • 单选框,对应的<input type="radio">,用于选择一项;

  • 复选框,对应的<input type="checkbox">,用于选择多项;

  • 下拉框,对应的<select>,用于选择一项;

  • 隐藏文本,对应的<input type="hidden">, 用户不可见,但表单提交时会把隐藏文本发送到服务器。

获取值

如果我们获得了一个<input>节点的引用,就可以直接调用value获得对应的用户输入值:

// <input type="text" id="email">
var input = document.getElementById('email');
input.value; // '用户输入的值'

这种方式可以应用于textpasswordhidden以及select

对于单选框和复选框,value属性返回的永远是HTML预设的值,而我们需要获得的实际是用户是否“勾上了”选项,所以应该用checked判断:

// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false
tue.checked; // true或者false

设置值

设置值和获取值类似,对于textpasswordhidden以及select,直接设置value就可以:

// <input type="text" id="email">
var input = document.getElementById('email');
input.value = 'test@example.com'; // 文本框的内容已更新

对于单选框和复选框,设置checkedtruefalse即可。

提交表单

提交表单时 MD5对密码加密

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HelloScript</title>
    <!--md5工具类-->
    <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<!--表单级别的提交时间:
onsubmit
-->
<div id="div123">
    <form action="#" method="post" onsubmit="return dist()">
        <p>
            <span>用户名:</span><input type="text" name="username" id="name1">
        </p>

        <p>
            <span>密码:</span><input type="password" id="pwd">
        </p>
        <!--隐藏域 隐藏真实密码-->
             <input type="hidden" name="md5-password" id="password">
            <input type="submit" value="提交">

    </form>
</div>
<script>
    function dist() {
        let username = document.getElementById("name1").value;
        let pwd = document.getElementById("pwd").value;//获取输入密码
        let password = document.getElementById("password");//获取隐藏域
        password.value =md5(pwd);//MD5加密
        alert(password.value);
        //可以校验表单内容 true就是通过提交 false就是阻止提交
        return false;
    }
</script>
</body>
</html>

JQuery

JavaScript世界中使用最广泛的一个库。

使用jQuery

使用jQuery只需要在页面的引入jQuery文件即可:

<html>
<head>
    //本地
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    //CDN
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
	...
</head>
<body>
    ...
</body>
</html>

$符号

$ 是著名的jQuery符号。实际上,jQuery把所有功能全部封装在一个全局变量jQuery中,而$也是一个合法的变量名,它是变量jQuery的别名

window.jQuery; // jQuery(selector, context)
window.$; // jQuery(selector, context)
$ === jQuery; // true
typeof($); // 'function'

快速上手

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HelloScript</title>
    <!--Jqury CDN-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<!--
jquery公式: $("#test-jqury").click();
-->
<a href="" id="test-jqury">点击</a>

<script>
    //点击事件
    $("#test-jqury").click(function () {
        alert("helloJqury")
    })
</script>
</body>
</html>

JQuery选择器

首先请看原生JS选择器

   //id选择器
   document.getElementById();
   //类
    document.getElementsByClassName();
    //标签选择器
    document.getElementsByTagName();

原生JS代码中,选择器复杂且类型较少

在Jquery中 CSS代码的选择器 它全部都能用

//jQuery css 中的选择器它全部都能用!
$('p' ).click();//标签选择器
$( '#id1' ).click(); //id选择器
$( '.class1 ' ).click() //cLass选择器

Jquery文档工具站

事件

因为JavaScript在浏览器中以单线程模式运行,页面加载后,一旦页面上所有的JavaScript代码被执行完后,就只能依赖触发事件来执行JavaScript代码。

浏览器在接收到用户的鼠标或键盘输入后,会自动在对应的DOM节点上触发相应的事件。如果该节点已经绑定了对应的JavaScript处理函数,该函数就会自动调用。

Jquery常用事件如下:
在这里插入图片描述

  //当网页元素加载完毕之后 响应事件
    $(function () {
        //获取鼠标移动事件
        $("#mouseMove").mousemove(function (e) {
            $("#mouseMove").text("x"+e.pageX+"Y:"+e.pageY);
        })
    });

操作DOM

     /*节点文本操作*/
    $(function () {
        //操作文本
        $("#text-u1 li[class=js]").text();//获取值
        $("#text-u1 li[class=js]").text("JavaSE");//设置值

        //操作html
        $("#text-u1 li[name=python]").html();//获取html
        $("#text-u1 li[name=python]").html("<li name='js'>mmm</li>");//设置值
    });

版权声明:本文为weixin_46684099原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。