概述

JavaScript是世界上最流行的脚本语言

入门

引入js

1.内部引入

1
2
3
4
<script>
//....
alert("hello woerd");
</script>

2.外部引入

1
<script scr="js/ysmJs,js"></script>

基础语法

JS严格区分大小写

数据额类型

  • number(不区分小数和整数)

    NAN -> not a number

    Intinity -> 无限大

  • 字符串

  • 布尔值

  • 逻辑运算 同c++

  • 比较运算
    = 赋值
    == 等于(类型不一样值一样就行)
    === 绝对等于(类型要一样)

    NaN与自己也不想等,要用isNAN(NAN)才行

  • null 空

  • undefined 未定于的

  • 数组(类型可以不同)

    1
    2
    3
    4
    var arr = [1, 2, 'hello', null, true];
    //第二种
    new Array(1, 3, 3, 4, 'hello');
    //取数组越界会undefined
  • 对象(用逗号隔开)

    1
    2
    3
    4
    5
    6
    7
    var Person = {
    name :"Tom",
    age :3,
    tags :['js', 'web', 'java']
    }
    console.log(Person.name);
    console.log(Person.age);

浮点数问题

用|a - b| < 0.000001

字符串使用

  • 用’’或者””,注意不能乱用,包含要用不同类型的
  • 支持多行字符编写(输出和写的一样)
  • 模版字符串
    1
    2
    3
    let name = 'ysm';
    let age = 20;
    var smg='你好呀,${name}';
  • 字符串长度
    1
    str.length;
  • 大小写转换
    1
    2
    3
    var str='ysm';
    str.toUpperCase();
    str.toLowerCase();
  • str.indexOf(‘b’); //在字符串里第一次下出现的坐标
  • substring 从0开始截断字符串 //同c++

数组

  • 长度: arr.length
  • indexOf,通过元素获得下标索引
    注:”1”和1不同
  • sllce():用法同substring
  • push(), pop(), 尾部
  • unshift(), shift(), 头部
  • sort()排序
  • reverse()反转
  • concat()返回一个新数组
  • join 链接
  • 多维数组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var arr = [1, 2, 3, 4, 5];
    arr.length;
    arr.indexOf(2);
    aarr.slice(2, 5);
    arr.push(42) //返回数组长度
    arr;
    arr.pop();
    arr;
    arr.unshift(92);//在头部添加,返回数组长度
    arr;
    arr.shift();//在头部删除
    arr;
    arr.sort();
    arr.reverse();
    arr.concat(['a', 'b', 'c']);
    arr;
    arr.join('+');
    var arr2 = [[1, 2], [3, 4], [9, 12]];
    arr[1][1];

对象

  • JS中对象,大括号{…}表示一个对象,键值对用来描述属性xxx:xxx,多个属性之间用逗号隔开,最后一个属性不加逗号。
  • JS中的所有的键都是字符串,值是任意对象。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 定义了一个person对象,它有四个属性
    var person = {
    name:"zlk",
    age:20,
    email:"sada@qq.com",
    score:100
    };
    person.name = "kk"; //给对象中的属性赋值:
    person.name
    delete person.name; //若存在该属性则返回true,删除对象的属性
    person;
    person.str = "num23"; //增加一个属性,直接给新的属性添加值即可。
    person;
    'score' in person; //对象中是否存在该属性
    // 继承
    'toString' in person; //true
    person.hasOwnProperty('toString'); //false 判断一个属性是否是这个对象自身拥有的
    person.hasOwnProperty('age'); //true //私有的

控制流程

if, while, for同c++

for-each

1
2
3
4
var age = [1, 2, 3, 4];
age.forEach(function (value) {
console.log(value);
})

for…..in -下标

1
2
3
4
5
6
var age = [1, 2, 3, 4, 5];
for (var num in age) {
if (age.hasOwnProperty(num)) {
console.log(age[num]);
}
}

Map

1
2
3
4
5
6
7
8
9
// ES6语法 Map
// 学生成绩,学生姓名
// var names = ["Tone","jay","sony"];
// var scores = [92,84,96];

var map = new Map([['Tone',92],['jay',84],['sony',96]]);
var name = map.get('Tone'); // 通过key获得value
map.set('admin',123456); // 新增
map.delete('Tone'); //删除

Set

1
2
3
4
5

var set = new Set([1,2,3,4,5,6,7,8]);
set.add(2); // 添加
set.delete(1); // 删除
console.log(set.has(3));

iterator

可以使用iterator来遍历Map,set

  • 遍历数组
    1
    2
    3
    4
    var arr = [3, 4, 5, 6, 7, 9];
    for(var x of arr) {
    console.log(x);
    }
  • 遍历Map
    1
    2
    3
    4
    var map = new Map([['Tone', 92], ['Jay', 84], ['sony', 96]]);
    for(let x of map) {
    console.log(x);
    }

函数

定义函数

没有return返回undefined

  • 方法一
    1
    2
    3
    4
    5
    6
    7
    function abs(x) {
    if (x >= 0) {
    return x;
    } else {
    return -x;
    }
    }
  • 方法二 匿名函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var abs = function(x) {
    if (x >= 0) {
    return x;
    } else {
    return -x;
    }
    }
    abs(12);
    abs(-12);
    规避传参问题
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var abs = function(x){
    // 手动抛出异常来判断
    if(typeof x!= 'number'){
    throw 'Not a Number';
    }
    if(x>=0){
    return x;
    }else{
    return -x;
    }
    }
    arguments是一个JS免费赠送的关键字;代表传递进来的所有参数是一个数组!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var abs = function(x){
    console.log("x=>"+x);
    for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
    }
    if(x>=0){
    return x;
    }else{
    return -x;
    }
    }
    abs(123, 456, 6);
    x=>123
    123
    456
    6

作用域问题

同c++

  • 所有的变量定义都放在函数的头部,这个是在JS 建立之初就存在的规范。 不要乱放,便于代码维护;

全局变量

1
2
3
4
5
6
7
8
//全局变量x
var x = 1;

function qj(){
console.log(x);
}
qj();
console.log(x);

全局对象 window,默认所有的全局变量都会自动绑定在window对象下

1
2
3
var x = 'xxx';
alert(x);
alert(window.x);//默认所有的全局变量,都会自动绑定在window对象下

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x = 'xxx';
window.alert(x);
//方法也可以作为变量
var old_alert = window.alert;
old_alert(x);

window.alert = function (){

}
//alert()失效了,因为我们重写了 alert()
window.alert('123');
//恢复
window.alert = old_alert;
window.alert('123');

规范

所有变量都会绑定到 window上。如果不同的 js 文件,使用了相同的全局变量,就会产生冲突,如何减少这样的冲突呢?

我们可以把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突问题,
jQuery中就是使用的该方法:jQuery.name,简便写法:$()。

局部作用域(局部变量建议用 let 定义!)

使用var关键字除了局部作用域变量还可以继续使用!

1
2
3
4
5
6
7
function aaa() {
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log(i + 1);//有问题--->i出了这个作用域还可以使用
}
aaa();

ES6 的 let 关键字,解决了局部作用域冲突的问题!

1
2
3
4
5
6
7
function aaa() {
for (let i = 0; i < 10; i++) {
console.log(i);
}
console.log(i + 1);//Uncaught ReferenceError: i is not defined
}
aaa();

常量

在ES6引入了常量关键字 const定义常量,此时常量一旦定义便不可以修改。

1
2
3
4
const PI = '3.14';
console.log(PI);
//下面报错了
PI = '3.11';//Attempt to assign to const or readonly variable(尝试赋值给const或只读变量)

方法

定义方法:把函数放在对象的里面,对象只有两个东西:属性和方法

1
2
3
4
5
6
7
8
9
10
var person = {
name: 'ysm',
birth: 2005,
age:function () {
var now = new Data().getFullYear();
return now - this.birth;
}
}
console.log(person.name);
console.log(persom.age());

在 js 中可以使用 apply 控制 this 指向。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function getAge() {
//今年-出生的年
var now = new Date().getFullYear();
return now - this.birth;
}
var person = {
name:'ysm',
birth:2005,
//方法
age: getAge
}
var xiaoming = {
name:'小明',
birth:2000,
//方法
age: getAge
}
getAge().apply(person, []);//指定该方法中的this,指向kuangshen,参数为空

内部对象

  • typeof
    1
    2
    3
    4
    5
    6
    7
    8
    typeof 123
    typeof '123'
    typeof true
    typeof NaN
    typeof []
    typeof {}
    typeof Math.abs
    typeof undefined
  • Date
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var now = new Date();
    console.log(now);//打印此刻的中国标准时间
    console.log(now.getFullYear());//年
    console.log(now.getMonth());//月 (0~11),0代表1月
    console.log(now.getDate());//日
    console.log(now.getDay());//星期几
    console.log(now.getHours());//时
    console.log(now.getMinutes());//分
    console.log(now.getSeconds());//秒
    console.log(now.getTime());//时间戳 全世界统一 1970.1.1 0:00:00 到现在的总毫秒数
    console.log(new Date(1543541513213));//将时间戳转为时间
    console.log(now.toLocaleString());//转换为当地时间
  • json
  • ajax

面向对象编程

在Java中:类是模板,对象是具体实例;而在 JS 中,我们需要转换一下思维方式!

原型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var Student = {
name:"张三",
age:3,
sex:"男",
run : function () {
console.log(this.name + " run...");
}
}
//小明也是学生,就没必要再重新写Student类中的某些属性和方法
var xiaoming = {
name:"小明"
}

//小明的原型指向Student ("原型"可以理解为"父类")
xiaoming.__proto__ = Student;
console.log(xiaoming.run());

var Bird = {
fly : function () {
console.log(this.name + " fly...");
}
}
//js的原型比较随意,也可以把小明指向鸟
xiaoming.__proto__ = Bird;
console.log(xiaoming.fly());

class集继承

class 关键字,是在 ES6 引入的

1
2
3
4
5
6
7
8
9
10
11
12
13
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('hello,' + this.name);
}
}
var jerry = new Student("jerry");
var jack = new Student("jack");

console.log(jerry.hello());
console.log(jerry.hello());

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//ES6之后========================
//定义一个学生的类
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('hello,' + this.name);
}
}
//定义一个小学生类继承Student
class XiaoStudent extends Student{
constructor(name,grade){
super(name);
this.grade = grade;
}
myGrade(){
alert(this.name + '是一名小学生');
}
}

var jerry = new Student("jerry");
var jack = new Student("jack");
var tom = new XiaoStudent("tom");

console.log(jerry.hello());
console.log(jack.hello());
console.log(tom.myGrade());

继承的本质还是原型,只是换了一种更加友好的写法而已

原型链__proto__

操作BOM对象(重点)

javascript 和浏览器关系?

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

BOM:浏览器对象模型

拓展:浏览器内核有Edge、Chrome、Safari、FireFox、Opera

window对象(重要),代表浏览器窗口

1
2
3
4
5
6
7
8
9
10
11
// window代表浏览器窗口
window.alert(1); //弹窗
undefined
window.innerHeight;
699
window.innerWidth
158
window.outerHeight
818
window.outerWidth
1065

screen对象, 代表, 代表屏幕尺寸

  • screen.height
  • screen.width

location, 代表当前页面的URL信息

1
2
3
location;
// 设置新的地中
location.assign('http://');

document(内容DOM),代表当前页面,HTML DOM文档树展开

获取具体的文档树节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM</title>
<script>
var dl = document.getElementById('app');
</script>
</head>
<body>

<dl id="app">
<dt>java</dt>
<dd>javaSE</dd>
<dd>javaWeb</dd>
<dd>javaEE</dd>
</dl>

</body>
</html>

获取cookie

document.cookie

操作DOM对象(重点)

DOM:文档对象模型

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

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

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

下面的示例代码用的是原生JS代码

1.获取Dom节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>

<div id="father">
<h1>标题一</h1>
<p id = "p1">p1</p>
<p class = "p2">p2</p>
</div>

<script>
//对应css选择器
var father = document.getElementById('father');
var h = document.getElementsByTagName('h1');
var p1 = document.getElementById('p1');
var p2 = document.getElementsByClassName('p2');

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

</body>

2.更新DOM节点

先拿到 id1

1
2
3
4
5
6
7
8
9
<body>
<div id="id1">
<!--一个空标签-->
</div>

<script>
var id1 = document.getElementById('id1');
</script>
</body>

操作文本

id1.innerText=’456’; 修改文本的值。
id1.innerHTML=’123‘; 可以解析HTML文本的标签。
操作CSS
id1.style.color = ‘blue’; 修改文本颜色;
id1.style.fontSize=’22px’; 修改文字大小;
id1.style.padding=’2em’; 修改文本位置;

删除DOM节点

步骤:

  • 先获取父节点
  • 再通过父节点删除自己
    删除节点P1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>

    <div id="father">
    <h1>标题一</h1>
    <p id="p1">p1</p>
    <p class="p2">p2</p>
    </div>

    <script>
    var self = document.getElementById('p1');
    var father = p1.parentElement;
    father.removeChild(self);

    // 删除是一个动态过程
    father.removeChild(father.children[0]);
    // father.removeChild(father.children[1]);
    // father.removeChild(father.children[2]);
    </script>

    </body>
    </html>
    注意:删除多个节点的时候,children 是在时刻变化的,删除节点的时候一定要注意。

插入节点

获得了某个 Dom 节点之后,假设这个 Dom 节点是空的,我们可以通过 innerHTML 增加一个元素;反之,如果这个 Dom 节点已经存在元素了,通过innerHTML就会产生覆盖。
appendChild(),追加到后面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<p id="js">JavaScript</p><!--现在我们想把这个标签添加到 div中-->
<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
</div>

<script>
var js = document.getElementById('js');
var list = document.getElementById('list');

list.appendChild(js);//追加到后面
</script>
</body>

效果:

1
2
3
4
5
6
7
<!--现在我们想把这个标签添加到 div中-->
<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
<p id="js">JavaScript</p>
</div>

上面是将一个已经存在的节点添加到别处,现在我们新创建节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
var js = document.getElementById('js');//已经存在的节点
var list = document.getElementById('list');
//通过JS创建一个新的节点
var newP = document.createElement('p');//创建一个p标签
newP.id = 'newP';
newP.innerText = 'Hello,Kuangshen';
//创建一个标签节点
var myScript = document.createElement('script');
myScript.setAttribute('type','text/javascript');

//可以创建一个style标签
var myStyle = document.createElement('style');//创建了一个空style标签
myStyle.setAttribute('type','text/css');
myStyle.innerHTML = 'body{background-color:chartreuse;}';//设置标签内容

document.getElementsByTagName('head')[0].appendChild(myStyle);
</script>

追加在前面 insertBefore()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<!--现在我们想把这个JavaScript添加到div中JavaEE的前面-->
<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>
var ee = document.getElementById('ee');
var js = document.getElementById('js');
var list = document.getElementById('list');
//要包含的节点.insertBefore(newNode,targetNode)
list.insertBefore(js,ee);
</script>
</body>

操作表单

表单form—–>DOM树:

  • 文本框—-text
  • 下拉框—-select
  • 单选框—-radio
  • 多选框—-checkbox
  • 隐藏域—-hidden
  • 密码框—-password
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <body>

    <form action = "post">
    <p>
    <span>用户名:</span>
    <input type="text" id = "username" />
    </p>
    <!-- 多选框的值就是定义好的value -->
    <p>
    <span>性别:</span>
    <input type = "radio" name = "sex" value = "man" id = "boy"/>
    <input type = "radio" name = "sex" value = "woman" id = "girl"/>
    </p>
    </form>

    <script>
    var input_text = document.getElementById("username");
    var boy_radio = document.getElementById("boy");
    var girl_radio = document.getElementById("girl");
    // 得到输入框的值
    // input_text.value;
    // 修改输入框的值
    input_text.value="admin";

    // 对于单选框,多选框等等固定的值,boy_radio.value只能取到当前的值
    boy_radio.checked = true; // 赋值
    girl_radio.checked; // 查看返回的结果,是否为true,如果为true,则被选中。
    </script>

    </body>

    提交表单

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- MD5加密工具类 -->
    <script src = "https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js">

    </script>
    </head>
    <body>

    <!--
    表达绑定提交事件
    onsubmit= 绑定一个提交检测的函数,true;false
    将这个结果返回给表单,使用onsubmit接收
    -->
    <form action="http://guozhivip.com/" method="post" onsubmit="return aaa()">
    <p>
    <span>用户名:</span>
    <input type="text" id="username" name="username"/>
    </p>
    <p>
    <span>密码:</span>
    <input type="password" id="password" />
    </p>
    <input type="hidden" id="md5-password" name="password">

    <!--绑定事件,onclick被点击,一般通过按钮级别进行操作-->
    <!--<button type="submit" onclick="aaa()">提交</button>-->
    <button type="submit">提交</button>

    </form>

    <script>
    function aaa(){
    alert(1);
    var username = document.getElementById("username");
    var pwd = document.getElementById("password");
    // console.log(uname.value);
    // console.log(pwd.value);
    var md5pwd = document.getElementById("md5-password");
    // MD5 算法
    // pwd.value = md5(pwd.value);
    md5pwd.value = md5(pwd.value);
    console.log(pwd.value);
    // 可以校验判断表单内容,true就是通过提交,false就是阻止提交
    return false;
    }
    </script>

    </body>
    </html>

jQuery

javaScript 和 jQuery的关系?

  • jQuery库,里面存在大量的 JavaScript 函数
    学了再补