JavaScirpt总结

JavaScirpt

JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。

注意事项:标注尽量使用// xxxx //后面加个空格

函数定义:定义变量 变量类型 变量=变量值

例如var sum = 1;

console.log(); //相当于JAVA中的System.out.print(); 打印信息到控制台

数据类型(简略说明)

变量

var a = 1

number js不区分小数和整数

var num = 1;
123 // 整数
123.1 // 浮点型
1.123e3 // 科学计数法
-99 // 负数
NaN // not a number
Infinity // 表示无限大

字符串

'abc'    
"abc"

布尔值

true  
false

逻辑运算

&&  两个为真,结果为真
||  一个为真,结果为真
!  真就是假,假的就是真

比较运算符 对js来说不要使用== 作为比较 用===作为比较

=
==   // 等于(类型不一样,值一样,也会判断为true)
===  // 绝对等于(类型一样,值一样,才会判断为true)
  • NaN===NaN, NaN与所有的数值都不相等,包括自己
  • 只能通过isNaN(NaN)来判断

尽量避免使用浮点数来进行运算,会有浮点数损失

数组

Java的数组必须是相同类型的对象,js中不需要

//为保证代码的可读性,尽量使用[]
var arr = [1,2,3,4,'hello',null,true];

new Array(1,22,3,'hello');

取数组下标如果越界了不会报错,会报undefined

null 和 undefined

  • null 空
  • undefined 未定义

对象

对象使用的是{},数组使用的是[],每个属性要用,隔开,最后一个不需要

// 相当于JAVA中的Person person = new Person()
var person={   //name,age,tags为属性字段
    name: "hdt",
    age: 3,
    tags: ['js','hy','web']
}

控制台取对象的值

person.name
"hdt"
person.tags
(3) ["js", "hy", "web"]
person.age
3

严格检查模式 ES6新特性

严格检查模式,可以预防JavaScript的随意性导致产生的一些问题

<script>
 // IDEA需要设置支持ES6语法
 // 'use strict';   严格检查模式,预防javascript的随意性导致产生的一些问题
 // 必须写在javascript的第一行。
 // 局部变量建议都使用let去定义,var是全局变量
    'use strict';
    let i = 1;   // let为局部变量
    var b = 2;   // var为全局变量
</script>

数据类型(详细解析)

字符串

1、正常字符串我们使用' '" "包裹

2、注意转义字符\ (重要)

//严格检查模式
'use strict';
console.log("a");
console.log('b');
console.log("\'");

"\'"    // '
"\n"    // 换行
"\t"    // 大空格
"u4e2d" // Unicode字符
"x41"   // Ascll字符

3、多行字符串编写 ES6 (重要)

let ms = `hello
wo
java
`

4、模板字符串 ES6 (重要)

// name->name
let name = "hdt";
let age = 2;
let smg = `你好,${name}`

5、字符串长度 ES6

let stu = "heidaotu";
console.log(stu.length); // 打印长度
console.log((stu[0]));   // 打印数组中第一个数值

6、字符串不可变 (重要)

image-20220606135608954

7、大小写转换

// 这里是方法不是属性
console.log(stu.toUpperCase())
-> HEIDAOTU

console.log(stu.toLowerCase())
-> heidaotu

8、获取元素第一次出现的位置

console.log(stu.indexOf('d'))
-> 3

9、截取第一个元素到元素 (重要)

// [1,3)
console.log(stu.substring(1,3))
-> ei
// 从第一个字符串到最后
console.log(stu.substring(1))
-> eidaotu

数组

Array可以包含任意的类型数据

let arr = [1,2,3,4,5,6];

1、长度

加入arr.length赋值,数组大小会发生变化

arr.length=10
-> 10
console.log(arr)
-> (10) [1, 2, 3, 4, 5, 6, 空 ×4]

2、indexOf,通过元素获得下标索引

var arrs = [1,2,3,4,'1','2',"2"]
-> undefined
arrs.indexOf(2)
-> 1
arrs.indexOf('2')
-> 5
arrs.indexOf("2")
-> 5

字符串的'1',"1"和数字1是不同的

3、slice() 截取Array的一部分,返回一个新数组,和java的substring类似 (重点)

var arrs = [1,2,3,4,'1','2',"2"]
-> undefined
arrs.slice(1)
-> (6) [2, 3, 4, "1", "2", "2"]
arrs.slice(1,3)
-> (2) [2, 3]

4、push(),pop() 尾部

arrs
-> (8) [1, 2, 3, 4, "1", "2", "2", "a"]
arrs.push('b','c')  // push()为压入到尾部
-> 10
arrs
-> (10) [1, 2, 3, 4, "1", "2", "2", "a", "b", "c"]
arrs.pop()			// pop()为弹出尾部元素
-> "c"
arrs
-> (9) [1, 2, 3, 4, "1", "2", "2", "a", "b"]

5、unshift(),shift() 头部

arrs
-> (9) [1, 2, 3, 4, "1", "2", "2", "a", "b"]
arrs.unshift('a','b')   // unshift()为压入到头部
-> 11
arrs
-> (11) ["a", "b", 1, 2, 3, 4, "1", "2", "2", "a", "b"]
arrs.shift()			// shift()为弹出头部元素
-> "a"
arrs
-> (10) ["b", 1, 2, 3, 4, "1", "2", "2", "a", "b"]

6、排序 sort() 元素反转reverse()

arr
-> (3) ["B", "A", "C"]
arr.sort()    // 排序
-> (3) ["A", "B", "C"]
arr.reverse() // 元素反转
-> (3) ["C", "B", "A"]

7、拼接concat()

arr
-> (3) ["C", "B", "A"]
arr.concat("D","E",1)
-> (6) ["C", "B", "A", "D", "E", 1]
arr
-> (3) ["C", "B", "A"]

concat() 并没有修改数组,只是返回一个新的数组

8、连接符join()

打印拼接数组,使用特定字符串连接

arr
(3) ["C", "B", "A"]
arr.join("-")
"C-B-A"

9、多维数组

let arr = [[1,2],[3,4],["5","6"]];
arr
(3) [Array(2), Array(2), Array(2)]0: (2) [1, 2]1: (2) [3, 4]2: (2) ["5", "6"]length: 3__proto__: Array(0)
arr[1][1]
4

对象

键值对

var 对象名 = {
    属性名: 属性值,
    属性名: 属性值,
    属性名: 属性值
}
// 定义了一个person对象,它有4个属性
var person = {
    name: "hdt",
    age: 22,
    email: "402@qq.com",
    score: 99
}

js中对象,{...}表示一个对象,键值对描述属性 XXX:XXX,多个属性用逗号隔开,最后一个不需要加逗号

JavaScript中的所有键都是字符串,值是任意对象

1、对象赋值

person.name = "hdttt"
"hdttt"
person.name
"hdttt"

2、使用一个不存在的对象属性,不会报错,提示urdefined

person.toto
undefined

3、动态的删减属性,通过delete删除对象的属性

person
{name: "hdttt", age: 22, email: "402@qq.com", score: 99}
delete person.name
true
person
{age: 22, email: "402@qq.com", score: 99}

4、动态的添加,直接添加新属性即可

person
{age: 22, email: "402@qq.com", score: 99}
person.from="大草原"
"大草原"
person
{age: 22, email: "402@qq.com", score: 99, from: "大草原"}

5、判断属性值是否存在这个对象中 xxx in xxx

'age' in person
true
//继承
'toString' in person
true

6、判断一个属性是否是这个对象自身拥有的hasOwnProperty()

person.hasOwnProperty('age')
true
person.hasOwnProperty('toString')
false

流程控制

if判断

let sum = 1;
if (sum>0){
    console.log("大于");
}else {
    console.log("小于");
}

while循环,避免死循环

let sum = 1;
while (sum<50){
    sum++;
    console.log(sum)
}

do{
    sum++;
    console.log(sum)
}while (sum<50)

for循环

let sum = 1;
for (let i = 0; i < 20; i++) {
    console.log(i)
}

foreach循环

let a = [1,2,66,9,3];
a.forEach(function (e){  // 对函数方法进行循环
    console.log(e);
})

for in 循环,类似于java中的foreach循环

let a = [1,2,66,9,3];
// b为下标索引
for (let b in a){
    console.log(a[b]);
}

for of 循环,类似于java中的foreach循环

//通过for of 来进行遍历数组
let arr = [1,22,77,44];
for (let x of arr){
    console.log(x);
}

Map和Set ES6

Map:

//ES6
let map= new Map([['tom',100],['hdt',99],['data','d1']]);
let data = map.get('tom');  // 获取
console.log(data);
map.set('heidaotu',1234);   // 添加或更改
map.delete('tom');			// 删除

Set: 无序不重复的集合

let set = new Set(1,2,2,1,3,2);
set.add(4);     // 添加
set.delete(1);  // 删除
set.has(2);     // 判断是否存在

iterator

ES6新特性 for of

遍历数组

//通过for of 来进行遍历数组
let arr = [1,22,77,44];
for (let x of arr){
    console.log(x);
}

遍历Map

let map = new Map([['bob',3],['alic',76],['mos',40]]);
for (let x of map){
    console.log(x);
}

遍历Set

let set = new Set([1,2,2,7,4,4,9]);
for (let x of set){
    console.log(x);
}

函数

定义函数

定义方式一 后端推荐使用方式一

abs求绝对值,函数

function abs(x){   // 函数function   abs求绝对值
    if (x>=0){
        return x;
    }else {
        return -x;
    }
}

一旦执行到return,则结束函数返回结果,如果没有执行return,则会返回undefined

定义方式二

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

调用函数

abs(10)
10
abs(-10)
10

参数问题:JavaScript可以传递任意的参数,也可以不传递参数

假如不存在如何规避

var abs = function (x){  	   // x为参数
    if (typeof x!=="number"){  // typeof运算符的返回类型为字符串  
        throw "Not a Number";  // 手动抛出异常
    }
    if (x>=0){
        return x;
    }else {
        return -x;
    }
}

typeof

js提供了typeof运算符,用来检测一个变量的类型。typeof运算符的返回类型为字符串,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算。

arguments

arguments是一个JavaScript的关键字:

传递进来的是所有的参数,这是一个数组

function arr(x){
    for (let i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
}
arr(1,2,3)
1.html?_ijt=hv7bimleciumh99299091biiec:14 1
1.html?_ijt=hv7bimleciumh99299091biiec:14 2
1.html?_ijt=hv7bimleciumh99299091biiec:14 3
undefined

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

rest ES6

function arr(x,y,...rest){
    console.log(x);
    console.log(y);
    console.log(rest);
}
arr(1,2)
1.html?_ijt=hv7bimleciumh99299091biiec:13 1
1.html?_ijt=hv7bimleciumh99299091biiec:14 2
1.html?_ijt=hv7bimleciumh99299091biiec:15 []
undefined
arr(1,2,3,4,5)
1.html?_ijt=hv7bimleciumh99299091biiec:13 1
1.html?_ijt=hv7bimleciumh99299091biiec:14 2
1.html?_ijt=hv7bimleciumh99299091biiec:15 (3) [3, 4, 5]
undefined

rest 可以获取除了已经定义的其他所有参数作为数组,rest只能写在最后面...rest

变量的作用域

在JavaScript中,var有作用域范围,如果在函数内定义var,那么在函数外就不可以使用,如果想要实现,需要用闭包

function arr(){
    var x = 1;
    x+=1;
}
x+=2;  // x is not defined

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

function arr(){
    var x = 1;
    function arr1(){  // 内部函数可以访问到外部函数,反之不行
        var y = x+1;  // 2
    }
    function arr2(){
        var z = y+1;  // Uncaught ReferenceError: arr2 is not defined
    }
}

如果内部函数变量和外部函数变量重名,会由内向外查找,如果外部存在这个函数变量,则内部函数会屏蔽外部函数变量

function arr(){
    var x = 1;
    function arr1(){
        var x = 3;
        console.log(x);
    }
}

提升变量的作用域

function arr(){
    var x='x'+y;
    console.log(x);
    var y='y';
}
arr()
xundefined

js自动提升了y的声明,但是不会赋值,这个是在JavaScript建立的时候就存在的特性,养成规范把声明写在头部,便于维护

var x,y;
x='x'+y;
console.log(x);
y='y';

全局函数

var x = 2;           // 设置全局变量
function arr(){
    alert(x);
    alert(window.x); // 默认所有的全局变量,都会自动绑定在window对象
}

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

var x ='xxx';
window.alert(x);
var old_alert = window.alert;
// ode_alert(x);
window.alert = function (){

}
// 发现alert失效
window.alert(123);
// 恢复
window.alert = old_alert;
window.alert(555);

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

规范

由于我们的所有全局变量都绑定到window上,不同的js文件,使用了相同的全局变量会产生冲突,为了减少冲突采取唯一全局变量

// 定义唯一全局变量
var hdt = {};
// 定义全局变量
hdt.name= "heidaotu";
hdt.add = function (x,y){
    return x+y;
}

把自己代码全部放入自己定义的唯一空间名字中,减少全局变量命名冲突

let ES6

for (let i = 0; i < 100; i++) {
    console.log(i);
}
console.log(i+1);   //i is not defined

局部变量简易使用let去定义作用域

常量const

在ES6前,常量定义为全大写,但是可以被修改,因此需要约束,衍生出const关键词

// ES6前的常量定义
var PI = 3.14;
console.log(PI);
PI=11;
console.log(PI);

// ES6的常量定义
const PI = 3.14;
console.log(PI);
PI=3;  //不允许被修改

方法

定义方法

方法就是把函数放在对象的里面,对象只有属性和方法

var number={
    age: 30,
    name: '黑刀图',
    firstname: function (){         // 方法
        return this.age+this.name;  // this默认指向调用它的那个对象
    }
}

// 属性
number.age;
// 调用方法要带()
number.firstname()

拆开

function getName(){
    return '测试'
}
var number={
    age: 30,
    name: '黑刀图',
    firstname: getName()
}

apply

getName.apply(number,[]);  //this.指向了number,参数为空

内部对象

Data

var now = new Date();
now.getFullYear();  // 年
now.getMonth();     // 月
now.getDate();      // 日
now.getDay();       // 星期
now.getHours();     // 小时
now.getMinutes();   // 分钟
now.getSeconds();   // 秒
now.getTime();      // 时间戳  从1970.1.1 00:00:00 到现在的毫秒数 全世界统一
var data = new Date(1623136515980);     // 时间戳转换为当前时间

JSON

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

格式:

  • 对象都用{}
  • 数组都用[]
  • 所有键值对 key:value
var stu={
    name: 'hdt',
    age: 10
}
// 将对象转换为JSON字符串
var json = JSON.stringify(stu);
console.log(json);      // {"name":"hdt","age":10}
// 将JSON字符串转换为对象  参数为JSON字符串
var obj = JSON.parse('{"name":"hdt","age":10}');
console.log(obj);

面向对象编程

class ES6

1、定义一个类,属性,方法

class stu {
    constructor(name) {     //constructor为构造器
        this.name=name;
    }
    hello(){
        alert("hello");
    }
}
var hdt = new stu("heidaotu");

hdt.hello();

2、继承

class stu {
    constructor(name) {     //constructor为构造器
        this.name=name;
    }
    hello(){
        alert("hello");
    }
}
class hdt extends stu{
    constructor(name,cont) {   //继承父类
        super(name);
        this.cont=cont;
    }
    mystu(){
        alert("我是一个测试");
    }
}
var stu1 = new hdt("黑道图",20);

操作BOM对象(重点)

浏览器对象模型,被广泛应用于 Web 开发之中,主要用于客户端浏览器的管理。

window

window代表浏览器窗口

window.innerHeight  // 内部浏览器高度
558
window.innerWidth	// 内部浏览器宽度
150
window.outerHeight	// 浏览器高度
644
window.outerWidth	//浏览器宽度
727

Navigator(不建议使用)

Navigator封装了浏览器的信息,不建议使用这些属性来判断和编写代码

screen

代表屏幕尺寸

screen
Screen {availWidth: 1440, availHeight: 860, width: 1440, height: 900, colorDepth: 24, …}
screen.width
1440
screen.height
900

location(重要)

location代表当前url信息

host: "www.baidu.com"
href: "https://www.baidu.com/"
protocol: "https:"
location.reload();	//刷新页面
location.assign('https://www.cnblogs.com/HeiDaotu/');	//设置新的地址

document

document代表当前的页面,HTML DOM文档树

document.title
"新建标签页"
document.title='黑道图'
"黑道图"
document.title
"黑道图"

获得具体的文档树节点

<dl id="hdt">
    <dt>java</dt>
    <dd>javaee</dd>
    <dd>javase</dd>
</dl>
<script>
    'use static';
    var id = document.getElementById('hdt');
</script>

document可以直接获取cookie

document.cookie
"pglt-edgeChromium-dhp=161; pglt-edgeChromium-ntp=161; MUID=26E7A8036F2F656635BEB82F6E01649F; MicrosoftApplicationsTelemetryDeviceId=cecce560-efa8-482d-80fd-80b5e1e149f2; MSFPC=GUID=64740e73015c487d9ec010a184502a90&HASH=6474&LV=202105&V=4&LU=1620015643234; weaSpartanRecentLocations=||22.5229|114.055|%E7%A6%8F%E7%94%B0%E5%8C%BA|%E5%B9%BF%E4%B8%9C%E7%9C%81|%E4%B8%AD%E5%8D%8E%E4%BA%BA%E6%B0%91%E5%85%B1%E5%92%8C%E5%9B%BD|CN|zh-cn|1|%E6%B7%B1%E5%9C%B3%E5%B8%82||; ai_session=npA6I|1623148787970|1623149999431.4"

劫持cookie原理

<script src="aaa.js">  // 恶意人员通过定到其他js来获取到你的cookie</script>

服务端设置 cookie:httpOnly即可安全

history(不建议使用)

history代表浏览器的历史记录

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

操作DOM对象(重点)

核心

DOM是动态的

浏览器网页就是一个DOM树形结构

  • 更新:更新DOM节点
  • 删除:删除一个DOM节点
  • 遍历DOM节点:得到DOM节点
  • 添加:添加一个新的DOM节点

要操作一个DOM节点,就必须要先获得这个DOM节点

获得一个dom节点

<div id="father">
    <p></p>
    <a id="hdt"></a>
    <h1 class="cl"></h1>
</div>
<script>
    //对应css选择器
    document.getElementById("hdt");
    document.getElementsByTagName("p");
    document.getElementsByClassName("cl");
    var father = document.getElementById("father");

    var childrens = father.children[index];  // 获取父节点下的所有子节点
    //father.firstChild
    //father.lastChild
</script>

更新dom节点

<div id="d1">
</div>
<script>
    'use static';
    var d1 = document.getElementById("d1");
</script>

操作文本

  • d1.innerText="case" 修改文本的值
  • d1.innerHTML="<h1>test</h1>" 可以解析html标签

操作css

d1.style.color='yellow'
d1.style.fontSize='20px'
d1.style.padding='3px'

删除节点

删除节点的步骤:先获取父节点,在通过父节点删除自己

<div id="d1">
    <p id="p1">p1</p>
    <h1 id="h1">h1</h1>
</div>
<script>
    'use static';
    // let father = document.getElementById("d1");
    let self = document.getElementById("p1");
    var father = p1.parentElement;	// 获取父节点
    father.removeChild(self);		// 删除子节点
</script>

插入节点

我们获得某个dom节点,假设这个dom节点为空,我们可以通过innerHTML就可以增加一个元素,但是如果dom节点已经有元素就不能这样做。

追加

<body>
<p id="p1">tojava</p>
<div id="d1">
    <p id="p2">javaee</p>
    <p id="p3">javase</p>
    <p id="p4">javamp</p>
</div>
<script>
    var d1 = document.getElementById("d1");
    var p1 = document.getElementById("p1");
    var p2 = document.getElementById("p2");
    d1.appendChild(p1);		//	追加
</script>
</body>

创建一个新的标签,实现插入

<body>
<div id="d1">
    <p id="p2">javaee</p>
    <p id="p3">javase</p>
    <p id="p4">javamp</p>
</div>
<script>
    var p = document.createElement("p");
    p.id="p1";
    p.innerText = "hdt";
    var d1 = document.getElementById("d1");
    d1.append(p);

	// 创建一个标签节点(通过这个属性,可以设置任意的值)
    var myscrpit = document.createElement("script");
    myscrpit.setAttribute('type','text/javascript');    	// setAttribute可以修改任意的值
</script>
</body>

insert

<body>
<p id="p1">jsp1</p>
<div id="d1">
    <p id="p2">javaee</p>
    <p id="p3">javase</p>
    <p id="p4">javamp</p>
</div>
<script>
    var p1 = document.getElementById("p1");
    var d1 = document.getElementById("d1");
    var p3 = document.getElementById("p3");
    d1.insertBefore(p1,p3); // d1为要包含的节点
</script>
</body>

操作表单(验证)

表单是什么 form DOM树

  • 文本框 text
  • 下拉框
posted @ 2021-11-07 14:05  HeiDaotu  阅读(78)  评论(0编辑  收藏  举报