js (主要为ES6) 的学习笔记
1.let/const/var都可声明变量,但各有不同,建议少用var。
const常量是保证映射不变,有需要要加上object.freeze()。
基本量传值,对象传址。
2.模式字符串 ${stringA},${stringB}
模式字符串中可以是JS表达式/函数调用等等。
3.标签模板
标签模板tag (可以不以tag来命名)
function tag(strings, …vars){
console.log(strings);
console.log(vars)
return ‘returnData’;
}
console.log(tag`name:${n},web:${web}`);
4. 字符串截取与检索
截取:
slice substring substr
slice(start,end) 支持负数下标
substring(start,end) 负数下标转为0
substr(start,num) 支持负数下标
检索:
indexOf(string, startIndex)
includes 参数相同,返回布尔值
lastIndexOf 后向前查找
startsWith(string) 区分大小写 endsWith()
5.Number
Number.isNaN(…) NaN != NaN
Msth.floor() Math.random()
min+Math.floor(Math.random() * (max-min + 1)) 实现 int:[min,max]
6.Array
toString() isArray() join()
Array.from() 可将其他类型转化成数组,可以方便操作dom元素
如Array.from(document.querySelectorAll(‘div’),
function(item){item.style.color = ‘red’;})
增删改查:
push() , unshift() 直接改变原数组。可以结合展开语法使用。
pop() , shift() 直接改变原数组。
fill() 填充,改变原数组。let arr = [0,1,2,3,4,5].fill(‘hd’,1,5);let arr = Array(5).fill(‘a’);
slice(start,end),实现截取,不改变原数组。
splice(start,num),实现从原数组中提取,改变原数组。
往后加参数可以实现填充。如 arr.splice(3,0,…[9,8,7])【结合…语法】
includes() 进行查找,返回布尔值,但对于对象无法得到结果,对象比较的是地址。 即a=[],b=[],但不论是a 2= b还是a 3= b,都为false,因为不是同一内存地址。
find() 返回值 findIndex() 返回下标 参数为函数
arr.find(item=>{ return item.n == 2; });
osort 自定义实现sort
function osort(array,fac){
let n = array.length;
for(let i=n-1-1; i>=0; i--)
for(let j=0; j<=i; j++)
if(fac(array[j],array[j+1]) > 0)
array.splice(j,2,array[j+1],array[j]);
}
遍历 for(const value of array) for(const key in array)
其中 for-of 语法是迭代器语法
array 的 keys entries values函数均返回迭代器,next向下取值,done可查看是否完成
some,every,filter使用
map reduce运用。
arr.map((value,index,arr)=>{return `${value}`;})
arr.reduce((pre,value,index,arr)=>{
return pre += value == 2? 1:0;},0)
7.展开语法
合并两个数组: […array1,…array2]相当于直接展开两个数组
函数参数可用长度未知的数组。function show(…args){}
ES6中函数式编程特性:
args.reduce(function(a,b){return a + b;})
args.reduce((s,v)=>{return s+v;})
对select的dom元素使用数组方法(如map),使用Array.from()进行转化
或者使用原型链:Array.prototype.map.call(divs,function(){})
还可以使用点语法直接转化
const divs = document.querySelectorAll('div');
// three methods
Array.from(divs).map(item=>console.log(item));
Array.prototype.map.call(divs,function(i){console.log(i)});
[...divs].map(item=>{console.log(item)});
8.解构语法
let [a,b] = [1,2]; // a=1,b=2
const [...arr] = "hello"; //arr = ["h", "e", "l", "l", "o"]
const [name,...arr] = ['david',20,'male']; //name="david",arr=[20,'male']
let [name,year=2020] = ['hello']; //name=“hello",year=2020
9.JQuery 简单学习
a. 使用CDN库
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
b. window.onload = function(){***} 会覆盖,等待全部元素加载完毕后执行代码
$(document).ready(function(){***}) 不会覆盖,DOM树加载完就执行
简写:$(function(){***})
c. 选择器 注意$(this)是选中当前元素
d. 获取元素属性 修改元素内容:
$('p').text('set Text'); $('p').html(); $('a').attr('href');
$('<p></p>').text('add element); $('div').html(<p>set Text</p>);
添加元素:
document.createElement('p');
$('body').append('sdsfs'); $('div').prepend('sdfsf');
before() 和 after() 也能插入元素,但是是插入一行元素,不是在元素前添加
移除元素:
$('#mydiv').remove() 移除id为mydiv的元素
$('p').remove('.myclass') 移除类为myclass的p元素
$('#mydiv').empty() 清除mydiv中所有子元素
e. css操作
$("body div:first").addClass("important blue"); 增加css类
$('li').toggleClass('itext'); $('li').removeClass('itext');
$('p').css('color');
$('p').css('color','red');
$('p').css({'backgroundColor':'blue','fontSize':'30px'});
f. 获取长宽
height() width() 获取元素宽高 不含内外边距与边框
innerHeight() innerWidth() 包含内边距
outerHeight() outerWidth() 包含内边距与边框
width: 100px; height: 100px; margin: 10px; padding: 20px; border: 2px;
height = width = 100
innerHeight = innerWidth = 140
outerHeight = outerWidth = 144
g. jQuery 遍历
$(..).parent() => 返回父元素
$(..).parents() => 返回祖先元素
$(..).parent("div") => 返回其祖先的div元素
$(..).parentUntil("body") => 返回其在body标签内的祖先元素
$(..).children() => 返回直接子元素
$(..).find('*') => 返回所有后代元素
$(..).find('div') => 返回后代中所有div元素
$(..).siblings() => 返回所有兄弟元素
$(..).siblings('p') => 返回兄弟元素中的p元素
$(..).next() => 返回下一个兄弟元素
$(..).nextAll() => 返回往后的所有兄弟元素
$(..).nextUntil('h3') => 返回往后的兄弟元素,直到兄弟中的h3元素
prev和next互为对称,方向相反
first() last() eq(index) 在选中的一组元素中通过位置进行选择
filter() 过滤 $('p').filter('.pclass')
not() 和filter()相反 $('p').not('.pclass')
h. AJAX + JQuery
$(’#mydiv’).load(‘本地url’) 在元素中加载url中内容
$("#div1").load(“test.txt #p1”); 也可以指定txt中某元素内容
可选callback函数 参数为(reaponseTxt,statusTXT,xhr);
$("#div1").load("/try/ajax/demo_test.txt",
function(responseTxt,statusTxt,xhr){
if(statusTxt=="success")
alert("外部内容加载成功!" + xhr.status+": "+xhr.statusText);
if(statusTxt=="error")
alert("Error: "+xhr.status+": "+xhr.statusText);
});
i. JSONP学习
目的,避免同源策略
Jquery用回调函数。
$.getJSON("url?callback=",function(data){
process to return data;
})
$.get("url",function(data,status){...})
$.post("url",{...(json)},function(data,status){...})
先前不了解传输过程,每次请求同目录下本地php,echo都返回整个php代码。
为什么之前有问题?
首先,jQuery 的 get 与 post 采用http协议传输,如果采用本地的php文件,
使用FTP协议,php文件被当成txt文件。所以会打印所有代码。
采用本地服务器,用的wampSever,如果从文件系统中进入html,则路径还是本地
文件系统路径,不是localhost目录下。必须从浏览器进入。
如果本地通过vscode的chrome server访问localhost下的文件,因为同源协议(端口不同),访问不到数据。
此时必须使用JSONP。JSONP是动态创建<script>标签,此时不会受到同源协议
的限制(JS下)。而用JQuery一样的道理,传输路径时带上后缀?callback=;
后端调用callback函数,echo时,调用该函数,将返回值以参数形式传入。
JSONP:
$.getJSON("http://localhost/forest/test.php?callback=?",
function (data) {
console.log(data);
$('#diva').html(data);
});
test.php中要加入请求头。并$_REQUEST['callback']获得函数名。
<?php
header('Content-type: application/json');
//获取回调函数名
$jsoncallback = htmlspecialchars($_REQUEST ['callback']);
//json数据
$json_data = '"name"';
//输出jsonp格式的数据
echo $jsoncallback . "(" . $json_data . ")";
?>
另一种方式,将test.html和php一同放在www目录下。用浏览器打开
$.get('t1.php',function(data){console.log(data)})
$.post('t2.php',{name:'Joe'},function(data){console.log(data)})
php中简单echo就可以了
10. 异步学习
callback 回调函数 setTImeOut setInterval
定时器封装,存储定时器id
function interval(callback, delay){
let id = setInterval(()=>{
callback(id);
},delay);
}
删除定时器: clearInterval(id)
任务时FIFO的,但异步加载的文件执行顺序就不一定了,必要时需要嵌套
promise pending准备阶段 fulfilled成功状态 rejected拒绝状态
new Promise((resolve,reject)=>{ promise process })
Promise的then方法包含两个参数,一个成功后调用,一个失败后调用。
原理:主线任务 > 微任务队列 > 宏任务队列
promise中的代码同步执行 (promise process)
resolve() reject() 改变promise的状态(不可逆)
p1 = new Promise((resolve,reject){
reject('fail');
})
new Promise((resolve,reject){
resolve(p1)
}).then(()=>{},()=>{})
后一个Promise的状态由p1的状态决定
系统中抛出异常(人为或是系统抛出),promise状态会变成reject,并返回一个error对象,可通过error.message获得信息。
如不想定义reject函数,可以在最后加上.catch处理错误。
结合jquery与promise的使用
$(function () {
function loadImage(src) {
return new Promise((resolve, reject) => {
let img = new Image();
img.src = src;
img.onload = () => {
resolve(img);
}
img.onerror = () => {
reject('加载不了');
}
})
}
loadImage('1.jpeg').then((value) => {
$('#divv').append(value);
},(msg)=>{$('#divv').text(msg);})
})
await async 语法糖
多个异步一起执行不延迟:
let res = await Promise.all([p1(),p2()])
11. Vue 简单学习
new Vue(el:'',data:{},methods:{},components:{},computed:{})
Vue对象的el属性绑定DOM元素,其中有数据,方法,对象内组件,计算属性
数据双向绑定 语法糖v-bind: -> : v-on: -> @
自定义组件:在组件内部用props接收父元素给的数据。
组件内部的data是function,数据以对象形式返回。
Vue.component('my-component',{
template: "<div>{{message}}</div>",
props:['message']
})
<my-component message="component message"></my-component>
12. 网络简单复习
tcp 网络层中第四层,传输层。
http是基于tcp/ip实现的,应用层。
ip是网络层的协议。
三次握手(C请求 S确认请求,建立连接 C确认确认)
四次挥手 (C发送FIN,S确认并进入关闭等待,S发送FIN并关闭连接等待ACK,C发送ACK)
13. 模块化
有容器来管理模块,可以添加模块,模块可以相互依赖。
首先,自定义模块,理解模块原理。
定义立即执行函数.
let module = (function(){
const moduleList = {};
//moduleList 负责模块存储管理
function define(name,modules,action){
//name:模块名 modules:本模块依赖的模块 action:模块动作
//module 中的 define 用于定义模块,添加模块
//将依赖的模块从存储的模块列表中导出,作为参数传入。
modules.map((m,i)=>{
modules[i] = moduleList[m];
})
moduleList[name] = action.apply(null, modules);
//模块名绑定上模块函数,apply参数为依赖模块列表,相当于在本模块导入了依赖模块
//apply中,前一个绑定要应用函数的对象,后一个传入参数列表,参数名称对应参数列表
}
return {define}
})()
//实现模块定义。添加TOOLS模块,无依赖,定义action
module.define("TOOLS",[],function(){
let action = {
first(arr){return arr[0]},
max(arr,fac){return arr.sort(fac)[0]}
}
retunr action;
})
//添加GetArr模块,不返回,只运算
module.define("getArr", ["TOOLS"], function (TOOLS) {
let data = [{ name: 'java', price: 200 },
{ name: 'js', price: 205 }];
console.log(TOOLS.max(data, (a, b) => {
return b['price'] - a['price'];
}))
})
//添加数据共享模块(或者说,模块内数据可共享)
module.define("A", [], function () {
return {
url: 'https://www.A.com',
site: 'A.com'
}
})
module.define("B", ["A"], function (A) {
A.site = 'AB.com'
})
module.define("C", ["A"], function (A) {
console.log(A.site)
// AB.com
})
导入外部js中的某一部分接口。
<script type="module">
import {show,url} from "./t1.js";
//必须要是路径,./不能省略 除非在一些打包环境中
console.log(url);
show();
</script>
在 t1.js 中,需要开放接口
export {show, url};
如果不用别名会报错。(具名导出)
模块加载解析会延迟。模块中默认使用严格模式。模块有独立作用域。
模块预解析,只解析一次。不论是在本模块多次引入还是引入模块中引入了其他模块。
import * as api from "./t1.js" 打包全部功能。
别名:import {url as u} from "./t1.js"
export {site as hd} 则 import {hd} ......
默认导出只能导出一个。
模块合并导出:使用某个js文件把所有模块导入,再导出
按需加载模块 比如点击后再加载,要使用到Promise对象。
直接放在判断语句中会有问题。因为包含在{}内部
必须通过import().then()的方式操作
import("./t1.js").then(({ show, url }) => {show();})
模块管理是ES6的语法,需要编译成ES5的语法才能在老的浏览器上使用。
再vscode中使用 WEBPACK 打包。
仅为学习中的一些笔记。