JavaScript学习笔记(仅供复习使用)
部分参考了廖海峰的JavaScript学习文件
链接:https://www.liaoxuefeng.com/wiki/1022910821149312
alert ('hello');
//类似于Java,严格大小写
1.只有变量 var,没有具体的类型,加var之后变为局部变量
var num =1;
alert(num);
2.条件控制,此处类似于Java,不再写例子
3.控制台打开–网页–console-console.log(变量名),尽量少使用
4.js不区分小数和整数,字符串单引号和双引号都可以’abc’ “abc”
5. ==表示等于(类型不一样,值一样,返回值为TRUE) =绝对等于(类型和值都一样,才会返回ture)
6.NAN not a number NAN 与所有的值都不想等,isNAN(NAN)返回的结果为真
7.浮点数问题:存在精度损失。undefine(未定义)NULL(空)
8.数组定义 例子 var arr = [1,2,5,‘hello’,null,true],越界报undefine
9.js中,类不需要class,定义方式为
/*
var person = {
name:"小明",
age:3,
tags:['js','java','web']
}
对象的使用:
1.删除: delete person.name
2.添加: person.haha=“haha”
3.判断在不在某个类里面 格式为XXX in XXX!
‘age’ in person 返回值为true或者false
对象为大括号。数组为中括号,每个属性之间用逗号隔开。最后一个可以不用逗号
/
//10.严格检查模式,预防js的随意性产生问题,一般建议let定义局部变量
/
‘use strict’ //必须写在第一行,表示严格检查模式
*/
11.模板字符串
let name ="xiaoming";
let msg =`nihaoya.${name}`
其中的引号为tab 上面的esc 下面
12 数组的大小可以发生变化,通过对数组长度赋值实现,过小会导致元素丢失
/*
var arr =[1,2,2,3] arr.length=4
输入 arr.length=10,------var arr =[1,2,2,3,empty*4 ]
出现4个空,调用查询为undefined
/
13 push 压入到尾部,pop 弹出尾部的一个元素 shift 从头部弹出,unshift 头部弹入
14 map 和 set map 的构造,查找,以及添加,删除
/
var map =new map(['tom',90],['jack',100],['jerry',89],['haha',80]);
var name =map.get('tom');
map.set ('admin',89)
map.delete('tom')
//遍历
for (let x of map){
console.log(x)}
set 指的是无序不重复的集合,具备去重的功能
var set =set new([1,2,3,3,3,3])
set.add(3)//添加
set.delete(2)//删除2
set.has(3)//查找
for(let x of set){
console.log(x)}//set遍历
15 具有iterable类型的集合可以通过新的for … of循环来遍历。
for … of循环是ES6引入的新的语法
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
console.log(x);
}
for (var x of s) { // 遍历Set
console.log(x);
}
for (var x of m) { // 遍历Map
console.log(x[0] + '=' + x[1]);
}
16.函数
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
1.function 指的是一个函数定义,2.abs函数名称,3.()里面是函数的参数,多个参数,使用逗号隔开
函数的第二种方式:
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
在这种方式下,function (x) { … }是一个匿名函数,它没有函数名。但是,这个匿名函数赋值给了变量abs,所以,通过变量abs就可以调用该函数。
上述两种定义完全等价,注意第二种方式按照完整语法需要在函数体末尾加一个;,表示赋值语句结束
js中允许传入任意个参数而不影响调用,但是传入参数过少,会出现undefined,可以传入多个参数,包括传入的某些参数函数内部并不需要。
关键字 arguments,功能:可以通过此关键字遍历传入的所有参数
function abs() {
for (var i = 0;i < arguments.length ;i++) {
console.log(arguments[i]);
}
return x >= 0 ? x : -x;
}
//遍历输入的参数,同时对参数进行判断
rest关键字:
function foo(a, b, ...rest) {
console.log('a = ' + a);
console.log('b = ' + b);
console.log(rest);
}
foo(1,2,3,4,5)
输出结果为:foo(1, 2, 3, 4, 5);
结果:
a = 1
b = 2
Array [ 3, 4, 5 ]
foo(1);
结果:
a = 1
b = undefined
Array []
对上述分析可以知道,如果参数过多,多余的参数放在一个数组里面
如果不足,对于不足部分输出undefined
rest参数只能写在最后,前面用…标识,从运行结果可知,传入的参数先绑定a、b,多余的参数以数组形式交给变量rest,所以,不再需要arguments我们就获取了全部参数。
如果传入的参数连正常定义的参数都没填满,也不要紧,rest参数会接收一个空数组(注意不是undefined)
17.变量作用域
全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中
此处举的例子参考廖雪峰的jsxue学习文档
唯一的全局变量MYAPP:
var MYAPP = {};
// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函数:
MYAPP.foo = function () {
return 'foo';
};
17.1 局部作用域
function foo() {
for (var i=0; i<100; i++) {
//
}
i += 100; // 仍然可以引用变量i
}
通过var定义的变量,实际可以在整个函数块进行使用,ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量:
function foo() {
var sum = 0;
for (let i=0; i<100; i++) {
sum += i;
}
// SyntaxError:
i += 1;
}
17.2 常量
ES6标准引入了新的关键字const来定义常量,const与let都具有块级作用域
const PI = 3.14;
PI = 3; // 某些浏览器不报错,但是无效果!
PI; // 3.14
17.3 解构赋值
var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
注意,对数组元素进行解构赋值时,多个变量要用[…]括起来
如果赋值中还有嵌套,格式如下:
let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
var person = {
name: '小明',
age: 20,
gender: 'male',
passport: 'G-12345678',
school: 'No.4 middle school',
address: {
city: 'Beijing',
street: 'No.1 Road',
zipcode: '100001'
};
var {name, age, passport} = person;
var {name, address: {city, zip}} = person;
如果出现嵌套时,要保证对应的层次是一致的
使用解构赋值对对象属性进行赋值时,如果对应的属性不存在,变量将被赋值为undefined
解构赋值还可以使用默认值,这样就避免了不存在的属性返回undefined的问题
将上述的改为:
var{name, age, passport,single=true} = person;
如果出现没有定义的属性,返回值为TRUE;
有些时候,如果变量已经被声明了,再次赋值的时候,正确的写法也会报语法错误:
// 声明变量:
var x, y;
// 解构赋值:
{x, y} = { name: ‘小明’, x: 100, y: 200};
// 语法错误: Uncaught SyntaxError: Unexpected token =
这是因为JavaScript引擎把{开头的语句当作了块处理,于是=不再合法。解决方法是用小括号括起来:
({x, y} = { name: ‘小明’, x: 100, y: 200});
18 方法:在一个对象中绑定函数,称为这个对象的方法
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年调用是25,明年调用就变成26了
代码分析:上述中age绑定方法,方式为: age: function () {}
调用函数外面的birth时,使用了this关键字,
在一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是xiaoming这个变量。所以,this.birth可以拿到xiaoming的birth属性
18.1 this的指向问题
上例中,直接书写的xiaoming.age;那么在function中,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
在本例中对age,进行了拆分,此时的this的指向与上例不同,此种this指向为window
18.2.1 利用apply 方法决定this指向哪个对象
要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。
用apply修复getAge()调用:
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, 参数为空
18.2.2
另一个与apply()类似的方法是call(),唯一区别是:
apply()把参数打包成Array再传入;
call()把参数按顺序传入。
比如调用Math.max(3, 5, 4),分别用apply()和call()实现如下:
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
19 内部对象
19.1 json,字符串固定为“”
1.所有的键值对 都用key:value
JSON是JavaScript Object Notation的缩写,它是一种数据交换格式
number:和JavaScript的number完全一致;
boolean:就是JavaScript的true或false;
string:就是JavaScript的string;
null:就是JavaScript的null;
array:就是JavaScript的Array表示方式——[];
object:就是JavaScript的{ … }表示方式。
例子:
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\"W3C\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
var s = JSON.stringify(xiaoming);
console.log(s);
只想输出指定的属性,可以传入Array:
JSON.stringify(xiaoming, ['name', 'skills'], ' ')
20 新的class继承
初始:
function Student(name) {
this.name = name;
}
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
}
利用class:
class student{
constructor(name){
this.name=name;}
//构造hello方法
hello (){
alert('hello');
}
}
相比之下:初始的函数,需要使用xx.prototype.hello=function(){}来进行声明,
class的定义包含了构造函数constructor和定义在原型对象上的函数hello()(注意没有function关键字),
这样就避免了Student.prototype.hello = function () {…}这样分散的代码。
继承:
class xiao extends student{
constructor(name, grade) {
super(name); // 记得用super调用父类的构造方法!!!!!
this.grade = grade;
}
书写方式和Java中相同,在这里相当于原型指向父类。
子类的构造函数可能会与父类不太相同,例如,此处的xiao需要name和grade两个参数,并且需要通过super(name)来调用父类的构造函数,否则父类的name属性无法正常初始化。
'use strict';
class Animal {
constructor(name) {
this.name = name;
}
}
class Cat extends Animal {
constructor(name, say){
super(name);
this.say=say;
}
hello (){
alert(this.say);
alert('测试成功');
}
}
let aaa = new Animal('aaa');
let Kitty = new Cat('Kitty','miaomiao');
Kitty.hello();
21.操作BOM对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js.js">//外部引入js文件
</script>
</head>
<body>
<div id ="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
let h1=document.getElementsByTagName('h1');
let p1=document.getElementById('p1');
let p2=document.getElementsByClassName('p2');
let father=document.getElementById('father');
let childrens = father.children; //获取父节点下的所有子节点
</script>
</body>
</html>
操作一个节点,首先应该获得该节点。
上述例子为寻找某一个节点,实际中一旦寻找到一个节点,周围的节点都可以找到
21.1 更新节点
一种是修改innerHTML属性,这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树:
第二种是修改innerText或textContent属性,这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签
两者的区别在于读取属性时,innerText不返回隐藏元素的文本,而textContent返回所有文本
修改CCS的例子
var p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px';
p.style.paddingTop = '2em';
21.2插入DOM
1.如果这个DOM节点是空的,例如,
如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点。
2.不为空时,有两个方法
方法一:有两个办法可以插入新的节点。一个是使用appendChild,把一个子节点添加到父节点的最后一个子节点
例子:来源于:https://www.liaoxuefeng.com/wiki/1022910821149312/1026155949848768
实现如下:
<!-- HTML结构 -->
<p id="js">JavaScript</p>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
var js =document.getElementById('js')//获取js的节点信息
list =document.getElementById('list') //获取子节点情况
list.appendChild(js) //在js添加一个子节点
2.从零创建一个节点,然后插入到指定位置
var
list = document.getElementById('list'),
haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);
3.插入到指定位置之前:使用关键字insertBefore
使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前
<div id="list">
<p id="java">Java</p>
<p id="python">python</p>
<p id="scheme">Scheme</p>
</div>
js部分代码如下:
let list =document.getElementById('list');
let ref = document.getElementById('python') ;//确定Python的位置
//创建一个节点
let haskell= document.getElementById('p');
haskell.id ='haskell';
haskell.innerText='haskell';
//关键字insertBefore
list.insertBefore(haskell,ref);
补充:使用insertBefore,关键在找到参考节点。一般的办法为遍历所有子节点,迭代children实现
例子如下:
var
i, c,
list = document.getElementById('list');
for (i = 0; i < list.children.length; i++) {
c = list.children[i]; // 拿到第i个子节点
}
21.3 删除节点
找到该节点的以及父节点,调用父节点的removeChild删掉自己
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self;
21.操作表单
用JavaScript来操作表单,可以获得用户输入的内容,或者对一个输入框设置新的内容
包含:MD5加密,实现简单的表单操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.18.0/js/md5.js"></script>
</head>
<body>
<form>
<p>
<span> 用户:</span><input type ="text" id ="username" required>
</p>
<p>
<span> 密码:</span><input type ="password" id ="psw" required>
</p>
<p>
<span>性别:</span>
<input type ="radio" name ="sex" value ="boy" id="boy">男
<input type ="radio" name ="sex" value ="girl" id="girl">女
</p>
<button type="button" onclick="aaa()">提交</button>
</form>
<script>
function aaa(){
var
usr= document.getElementById('username');
pwd =document.getElementById('psw');
console.log(usr.value);
console.log(pwd.value);
pwd.value= md5(pwd.value)
console.log(pwd.value);
alert('登陆成功')
}
</script>
</body>
</html>