@artman328
2022-06-29T01:05:17.000000Z
字数 24323
阅读 2175
javascript
目前,熟练的 JavaScript 程序员在北上广深的月薪收入大约为 20k ~ 40k 之间。
https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript
HTML 文档即网页文档,它是:
<标签名>
</标签名>
<标签名 />
<div id="emp-info"> ... </div>
<p class="error"> ... </p>
<span style="color:red"> ... </span>
选择器 {
样式属性1:值1;
样式属性2:值2;
…
}
选择器:标签名,#id号, .类名,...
样式属性:color, margin, padding, background, ...
用 JavaScript 语言编写
以事件为驱动,用于确定页面的行为(主要是与用户的交互行为)
文档类型定义:<!DOCTYPE html>
头部:<head> ... </head>
元数据:<meta ... >
标题:<title> ... </title>
<link rel="stylesheet" ... >
<style> ... </style>
体部
<script> ... </script>
<script src="..."></script>
document.write("输出内容")
document.getElementById("#id").innerHTML = "输出内容"
类和对象是当今编程语言的重要概念。
类就是某类事物,如:学生、发票、会议等。
对象就是任何具体的事物,如:某个学生、某张发票、某次会议等。
某一类事物都有共同的属性,如:学生,共同的属性有:学号、姓名、性别、出生日期等。
某一类事物都有共同的行为,如:学生,共同和行为有:学习、唱歌、考试等。
在人类社会中,人与人之间、组织与组织之间的互动完成了各种事务的管理。在编程中,将所有事物都超自然化(赋予生命),让它们之间互动来完成事务的管理,叫面向对象的编程方法。
因此,会议作为一类“活”的事物,它就有了自己的行为:“发邀请函”、“统计参会人数”、“开幕”、“闭幕”等。
想像一个管理程序,其中一个叫做 hr 的部门对象,它把一个叫做 liming 的 “人员” 对象 “加入(行为)” 到自己的 “全体人员(属性)” 集合对象中,并 “保存(行为)” 到数据库……
在编程术语中,对象的行为又叫方法。
读取一个对象的属性,语法格式是:
// 获取对象属性值,格式:对象名.属性名
billy.name
写入一个对象的属性:
billy.name = "Billy"
让一个对象实施行为(执行方法)的语法格式是:
// 对象名.行为名(参数…)
billy.say("Hello!");
billy.fullName();
从一个类(或构造函数)生成一个对象的方法是:
new Student(); // 生成一个新的学生对象
Console 是浏览器内的控制台,给编程人员提供与浏览器互动、调试程序的平台。编程人员往往向控制台输出各种信息以便于调试程序。
常用方法:
console.log("要输出的信息内容")
console.warn("要输出的警告内容")
console.error("要输出的错误内容")
console.table(要以表格形式输出的集合数据)
参阅:https://developer.mozilla.org/en-US/docs/Web/API/Console
document 是一个代表网页对象。
常用方法:
document.getElementById(“标签的id号”) // 获取特定 id 号的标签对象
document.write("写到网页<body>标签内的内容") // 向页面写内容
Element 对象代表网页中的某个标签。
常用属性:
Element.innerText // 标签内文本
Element.innerHTML // 标签内的下级 html 标签及其内容
语句是计算机程序的基本单元。程序由一条条语句构成。
JavaScript 的语句结束标志是“;”(英文分号)。标准规定,结束标志可以省略,解释器在读入程序时会自动加上。但为了避免某些情况下产生歧义,建议尽可能使用结束标志。
计算机程序的主要功能是处理数据。变量是一个被命名的装载数据的“容器”(计算机内存空间)。因其装载的数据可根据要求改变,因此叫变量。
要使用变量,需要事先声明。
声明变量的基本语句:
var 变量名; // (老标准,只能在函数内隐蔽,其它语句块内全局可见。不推荐使用)
// 或:
let 变量名;(语句块内隐藏,外部不可见)
// **注意:var、let 和 变量名之间至少一个空格。**
// 例如:
let name;
// 同时声明多个变量
let name, gender, age;
// 格式:变量名=表达式 (=号两旁可加空格便于阅读)
// 其中的表达式会得到一个具体值(或对象、函数等)
// 如:
let name, gender, age;
name = "Billy";
gender = "Male";
age = 30;
let sum;
sum = 100 + 200 + 300;
let tbody;
tbody = document.getElementById("app");
let name = 'Billy', gender = 'Male', age = 30;
let sum = 100 + 200 + 300;
let tbody = document.getElementById("app");
常量也是一个被命名的装载数据的“容器”(计算机内存空间)。但因其装载的数据不可再改变,因此叫常量。
// 格式:const 常量名 = 值;
// 如:
const PI = 3.14;
const AGE_MAX = 30;
// 注意:常量在声明时需要即刻赋值。常量名通常用大写字母,便于与变量区别。
只能字母、数字、下划线构成
不能数字开头
尽量使用含有说明意义的英文单词或单词组合
不能用 JavaScript 语言的保留字(编译器辅助,不用死记)
用 typeof 操作符获取数据类型
表示法:
特殊值:Infinity(正无穷), -Infinity(负无穷), NaN(Not a Number: 不是一个数值)
let n = 1.6e-3;
typeof n // "number"
n = 10/0 // Infinity
typeof n // "number"
n = -10/0 // -Infinity
typeof n // "number"
n = 12/"abc" // NaN
typeof n // "number"
表示法:
'Hello', "OK", `My name is ${name}`, "I'm a programmer.", "\"Yes.\", he said."
let s = "\"Yes.\", he said";
// 或者
let s = '"Yes.", he said.';
typeof s // "string"
表示法:true(真), false(假)
let finished = false;
typeof finished // "boolean"
表示法: undefined
let x;
typeof x // "undefined"
x = true;
typeof x // "boolean"
表示法:null
let y = null;
typeof y // "object", 空值是一个空对象,它没有任何属性和方法。
运算符 | 含义 | 例子 |
---|---|---|
+ | 加法运算 | x+y |
- | 减法运算 | x-y |
* | 乘法运算 | x*y |
/ | 除法运算 | x/y |
% | 取模运算(求余运算) | x%y |
++ | 自增1 | x++ 或 ++x 相当于 x=x+1 |
-- | 自减1 | x-- 或 --x 相当于 x=x-1 |
关系运算的结果是逻辑值:true 或 false。
运算符 | 含义 | 例子 |
---|---|---|
< | 小于 | x |
> | 大于 | x>y |
<= | 小于等于 | x<=y |
>= | 大于等于 | x>=y |
== | 等于 | x==y |
!= | 不等于 | x!=y |
=== | 严格等于 | x===y |
!== | 严格不等 | x!==y |
下表中的 a 或 b 可以是逻辑值,也可以是关系运算表达式。
运算符 | 含义 | 例子 | 规则 |
---|---|---|---|
&& | 与 | a && b | 全真才真 |
|| | 或 | a || b | 全假才假 |
! | 非 | !a | 取反 |
注意: && 比 || 有较高的运算优先级。
含义:如果……
示例程序1:
判断一个数是否是偶数,是则输出信息。
let i = 99;
if ( i % 2 === 0 ){ // if: 如果
console.log(`i 是偶数:${i}`);
}
练习1:
判断一个数是否处于100到999之间,是则输出信息。
含义:如果……否则……
示例程序2:
判断一个数是否是偶数,根据结果输出信息。
let i = 100;
if ( i % 2 === 0 ){
console.log(`i 是偶数:${i}`);
}
else{ // else: 否则
console.log(`i 是奇数:${i}`);
}
练习2:
判断两个数之和是否在100到999之间,根据结果输出相应信息。
含义:如果……否则如果……否则……
示例程序3:
根据小车档位,判断车处于什么模式下。
let op = 'D';
if ( op == 'D' ){
console.log(`${op}: 自动档模式!`);
}
else if ( op == 'P' ){
console.log(`${op}: 停车模式!`);
}
else if ( op == 'R' ) {
console.log(`${op}: 倒车模式!`);
}
else {
console.log(`${op}: 其它模式!`);
}
练习3:
有一个数表示整点时刻:0~23点,请根据这个数,判断是否是凌晨[0~8)、上午[8~12)、下午[12~18)和晚上[18~0)点。根据结果输出相应信息。
// 条件判断?值1 :值2,条件为真,返回值1,否则返回值2
let age = 18;
let result = (age>=18)?'adult':'child'; // 'adult'
// 等同于
let result;
if(age>=18){
result = 'adult';
}
else{
result = 'child';
}
let op = 'D';
switch(op) { // switch: 切换
case 'D': // case: 一旦
console.log(`${op}: 自动档模式!`);
break;
case 'P':
console.log(`${op}: 停车模式!`);
break;
case 'R':
console.log(`${op}: 倒车模式!`);
break;
default:
console.log(`${op}: 其它模式!`);
}
如果满足一条case,会从其下的第一条语句开始执行,而不管随后的语句是否在另外的case之下,但一碰到 break 语句整个switch 语句就结束(跳出语句块)。
// 输出 0 到 9:
for (let i=0; i<10; i++){ // for: 针对
console.log(i);
}
// 输出 0 到 9 的偶数:
for (let i=0; i<10; i++){
if( i%2>0 ){
continue; // 不继续往下,回到 for 处重新开始下一轮。continue: 断续
}
console.log(i);
}
// 遇到第一个被3整除的非零整数时结束循环
for (let i=0; i<10; i++){
if( i>0 && i%3==0 ){
break; // 不再执行循环体内剩下的语句,直接跳出循环。break: 打断
}
console.log(i);
}
let count = 9;
while(count>0){ // while: 在 ... 期间
console.log(count);
count --;
}
// 同样可用 continue 和 break 语句
let count = 9;
do { // do: 做
console.log(count);
count --;
} while(count>0);
loop1:
for (i = 0; i < 3; i++) { //第一个循环加了标签: "loop1"
loop2:
for (j = 0; j < 3; j++) { //第二个循环加了标签: "loop2"
if (i === 1 && j === 1) {
continue loop1; // 从 loop1 循环开始处重新开始
}
if ( j === 2 ){
continue loop2; // 从 loop2 循环开始处重新开始
}
if (i === 2 && j === 1){
break loop1; // 跳出 loop1 循环
}
console.log(`i = ${i}, j = ${j}`);
}
}
函数是完成特定任务的程序段,它可接受输入数据,也可给出(返回)结果数据。
// function: 功能,函数
function getPayment (price,discount=0.9){ // price, discount 叫做参数。0.9 是 discount 的默认值
return price * discount + 1;
}
function sayHello(name){
console.log(`Hello, ${name}.`);
}
let payment = getPayment(1000,0.85); // 851
// or
let payment = getPayment(1000); // 901,没有传入 discount, 采用默认值 0.9
sayHello("Tracy") // Hello, Tracy.
函数可被赋予一个变量:
let getPayment = function (price,discount){
return price * discount + 1;
}
// 或者写成
let getPayment = (price,discount) => {return price * discount + 1;}
// 函数体只有一句 return 的话,也可写成
let getPayment = (price,discount) => price * discount + 1;
这时,变量名就是函数名。
函数还可以作为参数传递给其它函数。
function doSomething(price,discount,func){
return func(price,discount);
}
let payment = doSomething(1000,0.8,getPayment); // 801
有时候,可直接传入函数定义
doSomething(1000,0.8,function(x,y){return x*y-5;}) // 795
// 或写成
doSomething(1000,0.8,(x,y)=>x*y-5)
// 格式:由 { } 包裹的一系列属性名(键)和属性值的组合,属性名和属性值之间用冒号分隔,每对属性名和属性值中间用逗号分隔。
let person = {name:"Billy", gender:"Male", age:30, location:{city:"Kunming",province:"Yunnan"}};
// 为便于阅读
let person = {
name: "Billy", // key: value, 键:值
gender: "Male",
age: 30,
location: { // 嵌套对象
city: "Kunming",
province: "Yunnan"
}
}
//读取对象属性
console.log(person.name) // Billy
console.log(person["name"]) // Billy
console.log(person.location.city) // Kunming
console.log(person["location"]["city"]) // Kunming
// 修改对象属性
person.name = "Ben";
// 或者
person["name"] = "Ben";
// 添加对象属性
person.title = "Dr.";
person.location.zipcode = "661300";
// 删除对象属性
delete obj.title;
let firstName = "Billy", lastName = 'Smith', gender = "Male", age = 35;
// 传统写法
let person = {
firstName: firstName,
lastName: lastName,
gender: gender,
age: age,
fullName: function(){
console.log(`${this.firstName} ${this.lastName}`);
}
}
// 简洁写法
let person = {
firstName,
lastName,
gender,
age,
fullName(){
console.log(`${this.firstName} ${this.lastName}`);
}
}
let obj = {
width: 100,
height: 200,
add(a,b){
return a+b;
}
};
let {width, height} = obj; // 取出 obj 的 width 属性值给外部变量 width, height 属性值给外部变量 height
let {width: w, height: h} = obj; // 取出 obj 的 width 属性值给外部变量 w, height 属性值给外部变量 h
let { add } = obj; //取出 add 函数给外部变量 add
add(10,20) // 30
属性:length
方法:push(e), pop(), unshift(e), shift(), splice(), forEach(), map(), filter(), reduce(),sort()
let data = new Array(10,20,'a','b',true);
// 或者:let data = [10,20,'a','b',true]
data.length // 5, length: 长度,在此指数组的元素数量。
data[0] // 10, 取第一个元素,索引号为零
data[2] // 'a'
// --------------- 修改元素值,添加、弹出元素, 数组即刻改变------------
data[1] = 200; // 把第二个元素(20)改成 200
data.push(false); // 6, 向数组尾部添加元素,变成:[10,200,'a','b',true, false]
data.pop(); // fasle, 从数组尾部弹出一个元素,变成:[10,200,'a','b',true]
data.unshift('zero'); // 6, 向数组头部添加元素,变成:['zero',10,200,'a','b',true]
data.shift(); // "zero", 从数组头部弹出一个元素,变成:[10,200,'a','b',true]
data.splice(2,1) // 从第 2 位开始删除 1 个元素,变成:[10,200,'b',true]
// ------------------ join 将所有元素用分隔符相连组成字符串,原数组不变 -----------------
let data = ['This', 'is', 'a', 'variable'];
let s = data.join();
console.log(s); // "This,is,a,variable"
s = data.join(' ');
console.log(s); // "This is a variable"
console.log(data); // ['This', 'is', 'a', 'variable'], data 不变
// ------------------ forEach 遍历所有元素执行传入的函数,原数组不变 --------------------
let data = [1,2,3,4,5];
data.forEach(function(e){
e = e*2;
console.log(e); // 2 4 6 8 10
});
console.log(data); // [1,2,3,4,5]
// ------------------ map 遍历所有元素生成新的数组, 原数组不变 ------------------------
let data = [1,2,3,4,5];
let arr = data.map(function(e){
return e*2;
}) // map 对每个元素执行一次传入的函数,返回值构成一个新的数组对象。
// 或者
let arr = data.map(e=>e*2)
console.log(data); // [1,2,3,4,5]
console.log(arr); // [2,4,6,8,10]
// ------------------------------- sort 排序, 原数组即刻改变 --------------------------
let numData = [3,2,4,1,30];
numData.sort() // 将元素转换成字符串后升序排序。sort: 排序
console.log(numData); // [1,2,3,30,4] !!!
// 传入比较函数,比较(a,b): a: 前一个元素,b: 后一个元素,函数返回小于0的值,a前b后,返回大于0的值,b前a后,返回0,ab位置不变。
numData.sort(function(a,b){
if(a>b){
return -1;
}
else if(a<b){
return 1;
}
else{
return 0
}
}); // [30,4,3,2,1] ,
//数字数组简洁排序
numData.sort((a,b)=>a-b); // 升序,[1, 2, 3, 4, 30]
numData.sort((a,b)=>b-a); // 降序,[30, 4, 3, 2, 1]
// ---------------- filter 遍历所有元素并过滤生成新数组,原数组不变 ------------------------------
let data = [1, 'a', 10, 'hello', true, null, undefined, NaN]
// 取出所有数字元素,但不包括正负无穷、NaN
let num = data.filter(e=>typeof e === "number" && isFinite(e) && !isNaN(e));
console.log(num); // [1,10]
console.log(data); // [1, 'a', 10, 'hello', true, null, undefined, NaN]
1、已知一个“待办事宜”对象的数组,对象属性包含编号(id),事宜( todo),已完成( finished),请编写一个函数,从一个“待办事宜”数组中过滤出“已完成”或“未完成”的记录(数组)。
function getTodos(const todos,finished=false){
return todos.filter(t=>t.finished==finished);
}
todoList = [
{id:1,todo:"Do something 1", finished=false},
{id:2,todo:"Do something 2", finished=false},
{id:3,todo:"Do something 3", finished=true},
{id:4,todo:"Do something 4", finished=false},
{id:5,todo:"Do something 5", finished=false},
{id:6,todo:"Do something 6", finished=true},
{id:7,todo:"Do something 7", finished=false},
{id:8,todo:"Do something 8", finished=false},
{id:9,todo:"Do something 9", finished=true},
{id:10,todo:"Do something 10", finished=false}
]
console.log(getTodos(todoList));
console.log(getTodos(todoList,true));
以下建立一个自定义类 Person。
class Person {
constructor(id,name,gender,dob){
this.id = id
this.name = name
this.gender = gender
this.dob = dob
}
desc(){
let self = `This is me, name: ${this.name}, gender: ${this.gender}, date of birth: ${this.dob}. `
return self
}
}
p = new Person(1,'Bill','Male','1990-10-10')
console.log(p.desc())
// +, -, *, /, %, +=, -=, ++, --
// 运算结果类型:number
10 + 20 // 30
10 - 20 // -10
10 * 20 // 200
10 / 20 // 0.5
9 % 2 // 1, 取余数运算
10/0 // Infinity
-10/0 // -Infinity
23/"abc" // NaN
let x = 10, y;
x += 2 // 12, 相当于 x = x + 2
x -= 2 // 10, 相当于 x = x - 2
x ++ // 返回 10,x: 11, 相当于 x = x + 1
++ x // 返回 12,x: 12
x -- // 返回 12,x: 11
-- x // 返回 10,x: 10
y = x ++ // y: 10, x: 11
y = ++ x // y: 12, x: 12
y = x -- // y: 12, x:11
y = -- x // y: 10, x: 10
// >, >=, <, <=, ==, ===, !=, !==
// 运算结果类型:boolean
10 > 20 // false
10 >= 20 // false
10 < 20 // true
10 <= 20 // true
10 == 20 // false
10 === 20 // false, 严格相等,类型和值都必须相同
10 == "10" // true, "10" 被转换为数字类型10,再比较
10 === "10" // false, 类型不同
10 != "10" // false
10 !== "10" // true
// paserInt 用于从字符串开头解析出整数值
parseInt("12.34千克");// 12, parse: 解析, int: 整型
// parseFloat 用于从字符串开头解析出小数
parseFloat("12.34千克"); // 12.34,float: 漂浮,浮点型(小数)
parseInt("重量:12.34千克");// NaN, 特殊数值,Not a Number, 不是一个数值
parseFloat("重量:12.34千克"); // NaN
// isNaN 用于判断结果是否是 NaN (不能用==)
let n = parseInt("abc123");
n == NaN; // false
isNaN(n) // true
// isFinite 用于判断一个数是否不是无穷大。Finite:有限的
n = 100 / 0;
n == Infinity // true
isFinite(n) // false
toFix(), toPrecision(), ...
let num = new Number(12.3);
// 或者: let num = 12.3, 操作 num 的属性或执行 num 的方法时,会自动转换成 Number 对象。
num.toFixed(2) // "12.30", 设置固定长度的小数位数,fixed: 固定的
(24).toFixed(3) // "24.000"
(24.16).toFixed(1) // "24.2"
(23).toPrecision(5) // 23.000, 设置数字位数。precision: 精确度
(23).toPrecision(1) // 2e+1, 2 * 10^1
数学对象:Math
abs(), floor(), ceil(), random(), round(), pow(),...
// 求绝对值
Math.abs(-100); // 100
// x 的 y 次方
let x=2, y=3;
Math.pow(x,y); // 8
// 取小数的整数部分,不作四舍五入
Math.floor(23.001) // 23
Math.floor(23.999) // 23
// 取小数的整数部分,只要小数部分大于零,就进位
Math.ceil(23.001) // 24
Math.ceil(23.999) // 24
// 将小数四舍五入到整数
Math.round(1.50) // 2
Math.round(1.49) // 1
// 获得 [0,1) 之间的随机小数
Math.random(); // 0.06092176944881755
1、请编写一个函数,接收两个整数参数,随机返回两个参数值之间(含两个参数值)的任意一个整数。
function randInt(min,max){
if(min>max){
let tmp = min;
min = max;
max = tmp;
}
return min + Math.floor(Math.random()*(max-min+1));
}
let name = "Billy", age = 35;
console.log("Hi, my name is " + name +", and I'm " + age +".");
let name = "Billy", age = 35;
console.log(`Hi, my name is ${name}, and I'm ${age}.`);
== , === : 两个字符串所有字节相同,长度相同,则相等
// === : 两个字符串所有字节相同,长度相同,则相等
"abc" === "abc" // true, 严格相等,数据类型和值都相等
"123" === 123 // false,类型不同
"123" == 123 // true, "123" 被自动转换为数字 123,再比较
// > 和 < : 逐个字符比较,编码大的字母字符串大,若相同,继续比较。如果比较到某个字符串的结尾,都相同,而另一个字条串还没结束,长的字符串大。
"abc" > "bbc" // false, a:97, b:98, c:99, ...
"abcde" > "abc" // true
let s = new String("Hello");
// 或 let s = "Hello"; 操作 s 的属性或执行 s 的方法时,会自动转换成字符串对象。
console.log(s) // 查看属性和方法,方法在 __proro__ 中
s.length; // 5,length: 长度
s.charAt(1) // "e" char: 字符,at: 在
s.charCodeAt(1) // e: 101,code: 编码,代码
s.concat(" world!") // "Hello world!", concat:串联
s.startsWith("He") // true,start: 开始,with: 用,以
s.endsWith("llo") // true,end: 结束
s.includes("ll",2) // true,第二个参数为开始搜索位置(第一个字符位置为0), include: 包括
s.indexOf("l") // 2,找到的第一个字符串的开始位置, index: 索引
s.lastIndexOf("l") // 3, 找到的最后一个字符串的开始位置,last: 最后的
s.repeat(3) // "HelloHelloHello", repeat: 重复
s.replace("ll","99") // "He99o", replace: 替换
s.substr(1,4) // "ello", 从第 1 位取 4 个字符,sub: 子,下一级
s.substring(1,4) // "ell", 从第 1 个位置取到第 4 个位置的字符,但不包含第 4 位的字符。
s.slice(1,4) // "ell", 同 substring。slice: 切片
s.split("ll") // ["He","o"], 以 "ll" 作为分隔符,把字符分割成由几个子串构成的数组。split: 分裂
" \tOK\n".trim() // "OK", 去除字符串头尾的空白字符和换行符。"\t" 代表 tab 键的空白,"\n" 代表换行符号。trim: 修剪
" \tOK\n".trimStart() // "OK\n",只修剪开头
" \tOK\n".trimEnd() // " \tOK",只修剪结尾
s.toUppercase() // "HELLO", upper case: 大写
s.toLowerCase() // "hello", lower case: 小写
// 正则表达式对象
let re = new RegExp('ab+c','g'); // 表达式:一个a,1到多个b,后面是一个c。g: global, 全局
// 或 let re = /ab+c/g, 操作 re 的属性或执行 re 的方法时,会自动转换成正则表达式对象。
"abcdefabbcddabbbbbc".match(re); // ["abc", "abbc", "abbbbbc"], match: 符合,匹配
"2019/10/31".replace('/','-') // "2019-10/31"
"2019/10/31".replace(/\//,'-'); // "2019-10/31"
"2019/10/31".replace(/\//g,'-'); // "2019-10-31"
"abcdefabbcddabbbbbc".replace(/ab+c/, ''); // "defabbcddabbbbbc"
"abcdefabbcddabbbbbc".replace(/ab+c/g, ''); // "defdd"
参阅:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
// JSON : JavaScript Object Notation, JavaScript 对象注记格式字符串,用于在网络中交投结构化数据。
let person = {
name: "Billy", // key: value
gender: "Male",
age: 30,
location: {
city: "Kunming",
province: "Yunnan"
}
}
// 对象转换为字符串
JSON.stringify(person) // '{"name":"Billy","gender":"Male","age":30,"location":{"city":"Kunming","province":"Yunnan"}}', stringify: 字符串化
// 字符串转换为对象
JSON.parse('{"name":"Billy","gender":"Male","age":30,"location":{"city":"Kunming","province":"Yunnan"}}'); // {name:"Billy",...},parse: 解析
// localStorage: 浏览器本地存储对象
localStorage.setItem("product","Brother Printer");
localStorage.getItem("product"); // "Brother Printer"
localStorage.removeItem("product") // remove: 移除,拿掉
localStorage.getItem("product"); // null
// localStorage 只能存储字符串,如果要存储对象数据,用 JSON 做来回转换即可
let obj = {id: 1, name: "Brother Printer", category: "Printer"};
localStorage.setItem("mydata",JSON.stringify(obj));
let out_obj = JSON.parse(localStorage.getItem("mydata"));
console.log(out_obj.name,out_obj.category);
1、编写一段代码,从中国大陆身份证号码中取出其中的出生年(7~10位)、月(11~12位)、日(13~14位)和性别(17位,奇数:男,偶数:女)信息。
let idNo = '531013197812010013';
let year = idNo.substr(6,4);
let mon = idNo.substr(10,2);
let day = idNo.substr(12,2);
let gender = parseInt(idNo.substr(17,1))%2===0? '女':'男';
2、请从字符串 "hdsgfiywebv7345hcgaf72hdbc981jgdavc7avc982shavchv8shavc889casvc0" 中删除所有数字。
let s = "hdsgfiywebv7345hcgaf72hdbc981jgdavc7avc982shavchv8shavc889casvc0";
s.replace(/[0-9]+/g,'');
// 或:
s.replace(/\d+/g,'');
let d = new Date(); // 2019-07-25 11:27:55, 获得日期对象,为当前日期(年月日)、时间(时分秒)。
d.getYear() // 19
d.getFullYear() // 2019, 按本地时区,
d.getUTCFullYear() // 2019, 按国际标准时间
d.getMonth() // 6 (月份 从0~11,6 表示 7 月份)
d.getDay() // 4 (星期四)
d.getDate() // 25 (日)
d.getHours() // 11 (时)
d.getMinutes() // 27 (分)
d.getSeconds() // 55 (秒)
d.getMilliseconds() // 491 (毫秒)
d.getTime() // 1564025275491, 1970-01-01 00:00:00 到 d 的时间的毫秒数。
d.getTimeZoneOffset(); // 与国际标准时间的时差秒数(负数为提前,正数为滞后)
// 注意以上相关的 setter 和 相应的 UTC (Universal Time Coordinated) 版本
// 生成特定日期的日期对象
let mydate = new Date(2000,11,1) // '2000-12-01'
mydate = new Date('2000-12-01') // '2000-12-01'
// 获取日期字符串
mydate.toDateString() //
mydate.toLocaleDateString('zh-CN') //
参阅:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date
let d1 = new Date("2010-10-01");
let d2 = new Date("2010-10-01");
d1 == d1 // false
d1 === d2 // false
d1.getTime() == d1.getTime() // true
Number(d1) == Number(d2) // true
+d1 == +d2 // true
d1 = new Date("2010-10-01");
d2 = new Date("2010-10-30");
+d1 > +d2 // false
+d1 < +d2 // true
// -------------- 从某个日期往前往后计算日期 ---------------------
let d1 = new Date(); // 获取当前日期时间
console.log("当前:", d1.toISOString())
// 20 天后的日期
d1.setDate(d1.getDate() + 20);
console.log("20天后:", d1.toISOString());
d1 = new Date的();
// 3 个月后的日期
d1.setMonth(d1.getMonth() + 3);
console.log("3个月后:", d1.toISOString());
d1 = new Date();
// 5 年后的日期
d1.setFullYear(d1.getFullYear() + 5)
console.log("5年后:", d1.toISOString());
d1 = new Date();
// 650 天前的日期
d1.setDate(d1.getDate() - 650);
console.log("650天前:", d1.toISOString());
// --------------- 两个日期之间的距离 --------------------
let d1 = new Date("2010-01-01");
let d2 = new Date("2020-05-30");
let diff = Math.abs(d1 - d2);
console.log('相距毫秒数:',diff);
let days = diff / (24 * 60 * 60 * 1000)
console.log('相距天数:', days);
moment.locale('zh-CN'); // 设定中文本地化
moment.months();
//["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
// -------------------- 设置获取日期时间成分 -----------------------------
let m = moment(); // 获取当前日期时间
m.format('YYYY-MM-DD'); // "2019-07-26"
m.year() // 2019
m.year(2025) // 重新设定年份
// 同理:month(), date()
m.format('YYYY-MM-DD') // "2025-07-26"
// ------------------ 计算日期时间差别 ----------------------------------
let d1 = moment('2000-05-31')
let d2 = moment('2001-05-30')
d1.diff(d2,'years') // 0
d2 = moment('2001-05-31')
d1.diff(d2,'years') // -1, 比较两个日期,少 1 年。
// 尝试 "months"(月), "weeks"(周), "days"(天),
// "hours"(小时), "minutes"(分), "seconds"(秒), "milliseconds"(毫秒)
//------------------- 添加一定时间范围到特定日期 -----------------------------
let d3 = moment('2010-01-01');
d3.add(3, 'years'); // "2013-01-01"
d3.add(10,'months'); // "2013-11-01"
d3.add(-10, 'days') // "2013-10-22"
window 对象表示一个包含DOM文档的窗口,其 document 属性指向窗口中载入的 DOM文档 。使用 document.defaultView 属性可以获取指定文档所在窗口。
window作为全局变量,代表了脚本正在运行的窗口,暴露给 Javascript 代码。
重要属性:document, location
可在浏览器的console中查看各种对象的方法、属性及其继承关系。
document对象代表整个文档。它是 window 对象的一个属性。通常,在调用window对象的属性和方法时,window对象可以省略不写,即 document 其实是 window.document,而 isNaN() 其实是 window.isNaN()
常用方法:
document.getElementById("id"),返回HTMLElement对象。
document.getElementsByClassName("class"),返回HTMLElement集合对象。
document.querySelector("selector"),返回HTMLElement对象。
document.querySelectorAll("selector"),返回HTMLElement集合对象。
selector, 选择器,是指通过一定规则构建字符串以找到特定的 HTML 元素。如:"#container" 会找到具有 id="container" 的元素。".item" 会找到所有具有 class="item" 的元素等。详细的选择器如下表。
选择器 | 例子 | 例子描述 | CSS版本 |
---|---|---|---|
.class | .intro | 选择 class="intro" 的所有元素。 | 1 |
#id | #firstname | 选择 id="firstname" 的所有元素。 | 1 |
* | * | 选择所有元素。 | 2 |
element | p | 选择所有 <p> 元素。 |
1 |
element,element | div,p | 选择所有 <div> 元素和所有 <p> 元素。 |
1 |
element element | div p | 选择 <div> 元素内部的所有 元素。 |
1 |
element>element | div>p | 选择父元素为 <div> 元素的所有 <p> 元素。 |
2 |
element+element | div+p | 选择紧接在 <div> 元素之后的所有 <p> 元素。 |
2 |
[attribute] | [target] | 选择带有 target 属性所有元素。 | 2 |
[attribute=value] | [target=_blank] | 选择 target="_blank" 的所有元素。 | 2 |
[attribute~=value] | [title~=flower] | 选择 title 属性包含单词 "flower" 的所有元素。 | 2 |
[attribute|=value] | [lang|=en] | 选择 lang 属性值以 "en" 开头的所有元素。 | 2 |
:link | a:link | 选择所有未被访问的链接。 | 1 |
:visited | a:visited | 选择所有已被访问的链接。 | 1 |
:active | a:active | 选择活动链接。 | 1 |
:hover | a:hover | 选择鼠标指针位于其上的链接。 | 1 |
:focus | input:focus | 选择获得焦点的 input 元素。 | 2 |
:first-letter | p:first-letter | 选择每个 <p> 元素的首字母。 |
1 |
:first-line | p:first-line | 选择每个<p> 元素的首行。 |
1 |
:first-child | p:first-child | 选择属于父元素的第一个子元素的每个 <p> 元素。 |
2 |
:before | p:before | 在每个 <p> 元素的内容之前插入内容。 |
2 |
:after | p:after | 在每个 元素的内容之后插入内容。 | 2 |
:lang(language) | p:lang(it) | 选择带有以 "it" 开头的 lang 属性值的每个 元素。 | 2 |
element1~element2 | p~ul | 选择前面有 <p> 元素的每个 <ul> 元素。 |
3 |
[attribute^=value] | a[src^="https"] | 选择其 src 属性值以 "https" 开头的每个 <a> 元素。 |
3 |
[attribute$=value] | a[src$=".pdf"] | 选择其 src 属性以 ".pdf" 结尾的所有 元素。 | 3 |
[attribute*=value] | a[src*="abc"] | 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。 |
3 |
:first-of-type | p:first-of-type | 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 |
3 |
:last-of-type | p:last-of-type | 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 |
3 |
:only-of-type | p:only-of-type | 选择属于其父元素唯一的 元素的每个 <p> 元素。 |
3 |
:only-child | p:only-child | 选择属于其父元素的唯一子元素的每个 <p> 元素。 |
3 |
:nth-child(n) | p:nth-child(2) | 选择属于其父元素的第二个子元素的每个 <p> 元素。 |
3 |
:nth-last-child(n) | p:nth-last-child(2) | 同上,从最后一个子元素开始计数。 | 3 |
:nth-of-type(n) | p:nth-of-type(2) | 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 |
3 |
:nth-last-of-type(n) | p:nth-last-of-type(2) | 同上,但是从最后一个子元素开始计数。 | 3 |
:last-child | p:last-child | 选择属于其父元素最后一个子元素每个 <p> 元素。 |
3 |
:root | :root | 选择文档的根元素。 | 3 |
:empty | p:empty | 选择没有子元素的每个 <p> 元素(包括文本节点)。 |
3 |
:target | #news:target | 选择当前活动的 #news 元素。 | 3 |
:enabled | input:enabled | 选择每个启用的 元素。 | 3 |
:disabled | input:disabled | 选择每个禁用的 元素 | 3 |
:checked | input:checked | 选择每个被选中的 元素。 | 3 |
:not(selector) | :not(p) | 选择非 <p> 元素的每个元素。 |
3 |
::selection | ::selection | 选择被用户选取的元素部分。 | 3 |
HTMLElement 接口表示所有的 HTML 元素。一些HTML元素直接实现了HTMLElement接口,其它的间接实现HTMLElement接口.
常用属性:id, classList, style, innerText, innerHTML.
常用方法:append(child), remove(),cloneNode(deep), addEventListener('event',function), removeEventListener('event',function)
window, document, HTMLElement 都具有事件属性,这些属性名称为“on”+事件名称,如:onclick, onmousedown, onkeypress ...
把一个函数赋给事件属性,则在这些对象上发生相应事件时,函数就会被执行。
自定义属性对应HTML标签中以“data-”开头的属性,引用时以dataset.属性名来引用。
如:
<div id="info" data-id="10">...</div>
let el = document.querySelector("#info")
console.log(el.dataset.id) // 打印出 10
有时我们需要从程序中创建一个HTMLElelment对象,对它的各种属性进行定义,并添加到某个节点中去。以下演示了如何创建一张图片,指定其各种属性后,添加到id为"gallery"的div中去。
let img = document.createElement("img")
img.src = "images/computer3.png"
img.style.width = "100px"
img.style.height = "100px"
img.classList.add("gallery-img")
document.querySelector("#gallery").append(img)
jQuery 是著名的第三方库,曾经为 JavaScript 的编程提供了极大便利。但随着近年来 JavaScript 编程API的日益丰富,以及大量前端编程框架的兴起,jQuery的采用日趋减少。但由于大量