javascript学习
js的调用及执行顺序:
调用方式:
(1)直接作为标签使用,放在任意位置处;
按照从上到下,依次执行。
<script type="module">js代码</script>
(2)作为文件引入:
<script type="module" src="xxxx.js"></script>
(3)将代码通过import关键字引入:
在js文件中:
#定义两个变量
let name = "ayas"
let age = "18"#定义一个函数
function print(){console.log(name)
}#通过export传达想要暴露给外部的内容:
export{nameprint
}在html文件中:#通过import引入变量
import {name, print} from"xxx1.js,xx2.js"; #可以同时调用多个js文件
console.log(name);
print();
<script>与<script type="module">的区别:
可以将<script>理解为全局变量,加上关键字"module"后,可以将某一变量的值限定在该区域之中。
执行顺序:
按照页面从上往下执行。
更多按照事件驱动的方式执行。
变量与运算符:
let与const-----声明变量:
let声明变量; const声明常量;
变量类型:
与python类似,无需显式声明;
· number:数值变量。不区分整数与浮点数;
· string:字符串。不区分单双引号;与c++字符串的区别在于:每一个字符都是只读变量,无法修改。
· boolen:字符变量;true与false
· object:对象,类似与c++中的指针;null表示空对象;
· undefined:未定义的变量;
#例如只规定:
let t;
#此时t的类型即为undefined
运算符:
与c++和python基本一致;
特殊:
#取整:
parseInt(小数);#乘方运算:
2 ** 10 ----- 2的10次方#位运算:
2 << 1#判断相等:
A === B ----需要使用三个等号
A !== B
输入与输出:
输入:
从输入中获取内容,引入库document:
· document.querySelector("目标对象") 返回第一个匹配到的内容。
· document.querySelectorAll("目标对象") 返回匹配到的所有目标对象的内容。
注意:这里可以像css选择器一样获取标签作为目标对象:
如,一个textarea标签的class = “input”。
可以选择:let input = document.querySelector(" .input ")
赋值:
存在list解析赋值的形式:
let [a, b] = [1, 2]
如此可实现:
let [a, b] = input.value.split(' ')
//以特定字符分开,以列表形式返回a = parseInt(a);
b = parseInt(b);
//转换为整数/*特别注意:
textarea 初始有换行和缩进,所以要使用:let [a, b] = input.value.trim().split(' ');
trim函数清除首尾空白
*/
添加事件监听:
例如代码:
# 赋值给input变量textarea元素
let input = document.querySelector("textarea")
# 赋值给run变量button元素
let run = document.querySelector("button")
# 赋值给output变量pre元素
let output = document.querySelector("pre")#语法格式:元素.addEventListener("监听的时间类型", 事件相应时执行的函数)function main() {run.addEventListener("click", function () {let s = input.value;output.innerHTML = s;});
}
输出:
(1)使用console.log 输出指定内容;
console.log()自带换行效果;
(2)直接改变html和css内容:
形如: output.innerHTML = s;
格式化字符串:
(1)字符串中填入数值;
let name = 'a', age = 18;
/ 1, js中的标注字符串使用的是`
let s = `my name is ${name}. I'm ${age} years old;`
(2)定义多行字符串:
let s = <div><h2>标题</h2><p>段落</p></div>
(3)保留两位小数如何输出:
let a = 1.2344;
let s = ${a.toFixed(2)}
取整函数:
let x = 1.234;
向上取整:
let y = Math.ceil(x);
向下:
let y = Math.floor(x);
向零取整:
parseInt
判断语句:
与c++完全一致。if--else语句。
循环语句:
同样具有for循环,while循环,do-while循环。
(1)for循环:
for( let i = 0; i <= 10; ++i){console.log(i);
}
枚举对象或数组时:
· for-in循环:可以枚举数组的下标或者对象的key;
· for-of循环:可以枚举数组中的值或者对象的value;
js独立书写处理数据流输入输出的格式:
读写多行单个的数据:
let buf = "";// stdin为标准输入;readable事件:有数据可读时触发;
// process.stdin.read(): 读取当前可用的数据块(chunk)。
// 如果 chunk 存在(非 null),将其转为字符串(此时包括换行符)并追加到 buf 中;process.stdin.on("readable", function() {let chunk = process.stdin.read();if (chunk) buf += chunk.toString();
});得到结果:buf即为用户所输入的数据流。注意:换行符处理
◦ buf 末尾的 \n 会被 parseInt 自动忽略,因此不影响数字解析。
process.stdin.on("end", function(){xxxxxx
});
读写多行多个的数据:
处理形如数据:
1 2
3 4process.stdin.on("end", function(){let lines = buf.split('\n');let [x1, y1] = lines[0].split(' ').map(x => {return parseFloat(x);});let [x2, y2] = lines[1].split(' ').map(x => {return parseFloat(x);});
对象:
由key: value组成。
value可以是变量,对象,数组,函数等。
函数中的this意义与c++中一致。
let person{name: "aa",age: 18,money: 0,add_money: function(x){this.money += x;}
}
两种调用方式:
person.name = person["name"] ;
person.add_money() = person["add_money"]() ;
数组:
元素类型:
数组中的元素类型可以不同。
例如:
let a = [1, 2, "a", "yxc"];let b = [1, // 变量"yxc", // 变量['a', 'b', 3], // 数组function () { // 函数console.log("Hello World");},{ name: "yxc", age: 18 } // 对象
];
访问元素:
同样通过下标访问: a[0] = 1;
注意js的数组下标,可以不连续,且可以为负数:
如:a[10] = 1; (前者为1, 2,3,4)或a[-10] = 4均可;
数组的常用属性及函数:
· 属性length:返回数组长度。【注意此处的length是属性不是函数】
· push函数:数组末尾添加元素;
· pop函数: 删除末尾元素;
· splice函数:splice(a, b) 删除从a开始的b个元素;
· sort函数:数组排序;
自定义排序方式:
sort(cmp)cmp函数返回负数,表示第一个数小于第二个数。
例如:
let a = [1, 2, 3, 8, 4];a.sort(function(a,b){ return b - a; }); //从大到小排序;a.sort(function(a, b){ return a - b; }); //从小到大排序;
n维空数组的设置:
一维数组:
let a = [];
补充:
空字典的定义:
let a = {};
判断某key是否在字典中:
if(key in dir){}
多维数组不能简单定义,需要进行初始化:
let ju = [];for(let i = 0; i < n; ++i){let now = [];for(let j = 0; j < m; ++j){now.push(0);}ju.push(now);}
//用0初始化一二维数组;
函数:
两种定义方式:
一般:
function(a, b){return a + b;
}例如:
let add = function(a, b){return a + b;
};
相当于lambda方式:
let a = (a, b) =>{return a + b;
}
若未定义返回值,则返回undefined;
js实现递归函数:
let buf = "";
process.stdin.on("readable", function(){let punk = process.stdin.read();if(punk) buf += punk.toString();
});
let used = [];
let path = [];
let dfs = (n, total) =>{if(total === n){console.log(path.join(' '));}else{for(let i = 1; i <= n; ++i){if(used[i]) continue;used[i] = true;path.push(i);fs(n, total + 1);used[i] = undefined;path.pop();}}
}
process.stdin.on("end", function(){let n = parseInt(buf);dfs(n, 0);
})
类:
js类中的成员全部公开,无私有成员;
定义:
class point(x, y){//构造函数:constructor(x, y{this.x = x;this.y = y;}//定义成员函数:toString(){return `(${x}, ${y})`;}
}
类的创建:
.....let a = new point(1, 2);
继承:
// class 子类 extends 父类
class ColorPoint extends Point {constructor(x, y, color) {super(x, y); // 这里的super表示父类的构造函数(引用父类的构造函数)this.color = color;}toString() {return this.color + ' ' + super.toString(); // 调用父类的toString()}
}
注意:
(1)super关键字作为函数使用时,代表父类的构造函数,且只能使用在子类的构造函数中;
super关键字作为对象使用时,指向父类的原型对象;
(2)子类的构造函数中,只有使用了父类的super后,才能使用this关键字;
(3)成员重名时,子类函数覆盖父类函数,类似于c++中的多态;
静态方法:
在类的成员函数前加上static关键字,这个函数则不能被实例调用,只能通过类本身调用;
class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return '(' + this.x + ', ' + this.y + ')';}static print_class_name() {console.log("Point");}
}let p = new Point(1, 2);
Point.print_class_name();
p.print_class_name(); // 会报错
静态变量:
只能通过class.propname定义和访问。
class Point {constructor(x, y) {this.x = x;this.y = y;Point.cnt++; //静态变量的调用}toString() {return '(' + this.x + ', ' + this.y + ')';}
}Point.cnt = 0; // 静态变量的定义let p = new Point(1, 2);
let q = new Point(3, 4);console.log(Point.cnt);
事件:
事件通过addEventListener函数来绑定触发。
鼠标相关事件:
· click:鼠标左键点击
· dblclick:鼠标左键双击
· contextmenu:鼠标右键点击
· mousedown:鼠标按下,包括左键、滚轮、右键
· event.button:0表示左键,1表示中键,2表示右键
· mouseup:鼠标弹起,包括左键、滚轮、右键· event.button:0表示左键,1表示中键,2表示右键
键盘相关事件:
keydown:某个键是否被按住,事件会连续触发
event.code:返回按的是哪个键
event.altKey、event.ctrlKey、event.shiftKey分别表示是否同时按下了alt、ctrl、shift键。
keyup:某个按键是否被释放
event常用属性同上
keypress:紧跟在keydown事件后触发,只有按下字符键时触发。适用于判定用户输入的字符。
event常用属性同上
表单相关事件:
focus:聚焦某个元素
blur:取消聚焦某个元素
change:某个元素的内容发生了改变(改变内容后,再取消聚焦,触发)
窗口相关事件:
resize:当窗口大小放生变化
scroll:滚动指定的元素
load:当元素被加载完成
需要作用到window元素上。
如:
window.addEventListener('scroll', function(){
})
常用API:
了解大概语法即可,具体边用边查;
jQuery:
引入方式:
(1)在<head>元素中添加:
<script src="https://cdn.acwing.com/static/jquery/js/jquery-3.3.1.min.js"></script>;
(2) 按jQuery官网提示下载;
选择器:
选取标签的优化写法:
$(selector);如:
$('div')
$('.big-div');
类似于css选择器。
取代了
let div = ducument.querySelector('div');
改变为:
let div = $('div');
且可以选择所有div标签;而不是仅返回第一个。
事件:
绑定事件:
格式:$(selector).on(event, func)
例如:
$('div').on('click', function(){console.log("click div");
});
删除事件:
格式:$(selector).off(event, func)
$('div').of('click', function(){console.log('click div');$('div').off('click');
})
区分相同类型的事件:
例如对于两个click事件加以区分,
采用:事件.特殊名称
$('div').of('click.name1', function(){console.log('click div');$('div').off('click.name1');
})$('div').of('click.name2', function(){console.log('click div too');
})
事件触发的函数中,return false等价于同时执行:
· e.stopPropagation():阻止事件向上传递
· e.preventDefault():阻止事件的默认行为
事件的向上传递:
即子标签的事件触发同时会影响到父节点:
如
<div><a href = "www.acwing.com" target = "_blank"></a>
</div>
若点击链接a,同时也会触发div的click效果。
阻止事件的默认行为:
在本例中则体现为:阻止a打开新链接,但不阻止向div标签的传递。
两者同时执行即表示:
本标签的不被触发,同时不会向上传递。
即函数 return false;等价于两者同时书写。
元素的隐藏与展现:
· $A.hide():隐藏,可以添加参数,表示消失时间:如A.hide(1000),用时1000ms
· $A.show():展现,可以添加参数,表示出现时间
· $A.fadeOut():慢慢消失,可以添加参数,表示消失时间:颜色逐渐变透明
· $A.fadeIn():慢慢出现,可以添加参数,表示出现时间
元素的添加删除:
$('<div class="mydiv"><span>Hello World</span></div>'):构造一个jQuery对象
$div.on('click', function () {let $a = $(`<a href = "www.acwing.com" >ACWing</a>`)$div.append($a);}) }
$A.append($B):将$B添加到$A的末尾
$A.prepend($B):将$B添加到$A的开头
$A.remove():删除元素$A
$A.empty():清空元素$A的所有儿子
对类的操作:
$A.addClass(class_name):添加某个类
$A.removeClass(class_name):删除某个类
$A.hasClass(class_name):判断某个类是否存在
对CSS的操作:
$("div").css("background-color"):获取某个CSS的属性;
$("div").css("background-color","yellow"):有两个参数,代表设置某个CSS的属性;同时设置多个CSS的属性:
$('div').css({width: "200px",height: "200px","background-color": "orange", });
对标签属性的操作:
$('div').attr('id'):获取属性
$('div').attr('id', 'ID'):设置属性
对HTML内容文本的操作:
$A.html():获取(无参)、修改HTML内容(内置参数)
$A.text():获取(无参)、修改文本信息(内置修改的字符串)
$A.val():获取、修改文本的值【通常运用在input和textarea中】
查找(快速定位标签):
$(selector).parent(filter):查找父元素
$(selector).parents(filter):查找所有祖先元素
$(selector).children(filter):在所有子元素中查找
$(selector).find(filter):在所有后代元素中查找
与后端的通信方式:ajex
ajax:不刷新整个页面的情况下,从服务器端获取某些数据;
Get方法:
从服务器端获取内容;
$.ajax({url: url, //目标链接type: "GET", //获取方式data: { },dataType: "json",success: function (resp) {},
});
Post方法:
$.ajax({url: url,type: "POST",data: {},dataType: "json",success: function (resp) {},
});
setTimeout与setInterval
实现延迟执行的效果
setTimeout(func, delay)// delay毫秒后,执行函数func()。
实现循环执行效果:
setInterval(func, delay)//每delay毫秒执行一次函数func
clearTimeout():
取消计时效果。
let timeout_id = setTimeout(() => {console.log("Hello World!")
}, 2000); // 2秒后在控制台输出"Hello World"clearTimeout(timeout_id); // 清除定时器
clearInterval():
取消循环效果:
let interval_id = setInterval(() => {console.log("Hello World!")
}, 2000); // 每隔2秒,输出一次"Hello World"clearInterval(interval_id); // 清除周期执行的函数
requestAnimationFrame:
主要用于动画的实现。
该函数实现在下次页面刷新时,执行一次。(与时间无关,与页面的刷新频率有关)
大多数页面刷新频率为1秒60次,故常将其采用递归的形式,每秒执行60次;
例如:
let $div = $('div');let step = () => {$div.width($('div').width() + 1);requestAnimationFrame(step);};requestAnimationFrame(step);
当页面在后台时,因为页面不再渲染,因此requestAnimationFrame不再执行。但setTimeout与setInterval函数会继续执行。
Map与Set:
Map:
1, 定义方式;
let map = new map();2, 插入键值对:
map.set(key, value);3, 查找关键字:
map.get(key)
//不存在,返回undefined4,是否包含关键字;
map.has(key)5, 删除关键字:
delete(key)6, 返回长度:
map.size
遍历方式:
(1)for of 方式遍历:
for(let [key, value] of map){console.log(key, value);
}
(2)forEach方式遍历:
map.forEach(function() (key, value) {console.log(key, value);
})
Set:
大致相似:
添加方式为:
set.add()
以上两者键值可以为任意值,包括函数、对象或任意基本类型。
localStorage:
在用户的浏览器上存储键值对;
· setItem(key, value):插入
• getItem(key):查找
• removeItem(key):删除
• clear():清空
JSON:
JSON对象用于序列化对象、数组、数值、字符串、布尔值和null
JSON.parse() //将字符串解析为JSON对象JSON.stringify() // 将某一对象解析为字符串
日期:
返回值为整数的API:
数值为1970-1-1 00:00:00 UTC(世界标准时间)到某个时刻所经过的毫秒数:
Date.now(); //现在的时刻Date.parse("2022-04-15T15:30:00.000+08:00")://返回北京时间2022年4月15日 15:30:00的时刻。// +08:00 表示所处于东八区
与Date对象相关的API:
let starttime = new Date(); //什么参数都没有,表示当前时刻。
console.log(new Date() - starttime); //表示当前时刻距离starttime的毫秒数。console.log(starttime.getDay()); //返回星期console.log(starttime.getDate()); //返回日期console.log(starttime.getMonth()); //返回月份(0到11,注意转换)console.log(starttime.getFullYear()); //返回年份console.log(starttime.getHours()); //返回小时console.log(starttime.getMinutes()); //返回分钟console.log(starttime.getSeconds()); //返回秒数console.log(starttime.getMilliseconds()); //返回毫秒数
Websocket:
ajex属于http协议,只能由用户主动向后端发送请求;
websocket为全双工通信,两边均可主动发送请求;
window:
window.open("https://www.acwing.com") 在新标签栏中打开页面。
location.reload() 刷新页面。
location.href = "https://www.acwing.com":在当前标签栏中打开页面。
canvas:
Canvas 教程 - Web API | MDN