前端自省系列😆有些是掘友的一些专栏文章的摘录,如果有不对的地方,请大家指出
FormData
概念
FormData接口提供一种表示表单数据的键值对的构造方式.可以通过JavaScript模拟表单控件操作.可以通过XMLHttpRequest的send方法异步提交表单
使用
FormData
初始化表单对象,可以传入dom元素,可以为空
//创建一个空的FormData对象
let formData = new FormData();
//创建一个存在的form对象 这个对象包含这个表单的数据
const formOne = document.getElementById("myform");
let formData = new FormData(formOne);
append,set
append:添加一个新值对到FormData对象,键存在将新值添加到值的集合中,不存在则添加新的键值对
set: 通append,区别在于如果键存在情况下,新的值覆盖旧值
//formData.append(name,value)
//formData.append(name,value,[filename])--value为文件对象时,可以通过filename定义文件名字如果value是Blob对象,默认文件名是"blob"
formData.append("name","lily");
formData.appen("name","hello"); //此时name的值是 lily,hello的集合
formData.append("avatar",fileInput.files[0],'avatar1.jpg') //上传头像文件,指定文件名称
//formData.set(name,value);
//formData.set(name,value,filename) //同append
delete
删除键值对
formData.delete("name");
entries和keys
entries:返回FormData的键值对数据集合,是一个iterator对象
keys: 返回FormData的键集合,是一个iterator对象
const formOne = new FormData();
formData.entries(formOne);
formData.keys(formOne);
get和getAll
get: 返回指定key的第一个值
getAll: 返回指定key的所有值
formData.get("keyName");
formData.getAll("keyName");
has
检测某个key是否存在
formData.has("keyName")
values
返回一个允许遍历该对象中所有值的
迭代器
//创建一个FormData测试对象
var formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');
//显示值
for (var value of formData.values()) {
console.log(value);
}
//value1
//value2
base64场景
- 上传图片,可以转化为base64上传
- 可以在页面显示base64图片,适应于不是很大的图
- url加密
移动端点击事件延迟
移动端会延迟300ms,来判断是否还有下一次点击,以此来判定是点击还是双击
避免延迟
禁止缩放
<meta name="viewport" content="width=device-width user-scalable= 'no'">
fastclick.js
随机字符串
/**
* 随即字符串
* @param {Number} length
*/
function randomString(length) {
//如果转换的基数大于10,则会使用字母来表示大于9的数字,比如基数为16的情况,则使用a到f的字母来表示10到15
//如果radix是36,就会把数字表示为由0-9, a-z组成的的36进制字符串
let str = Math.random().toString(36).substr(2);
if(str.length >= length) {
return str.substr(0,length);
}
str += randomString((str.length) - length);
}
typeof null == "object"
不同的对象在底层都表示为二进制, 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0, 自然前三位也是 0, 所以执行 typeof 时会返回“object”
在 javascript 的最初版本中,使用的 32 位系统,为了性能考虑使用低位存储了变量的类型信息:
- 000:对象
- 1:整数
- 010:浮点数
- 100:字符串
- 110:布尔
九九乘法表
/**
* 九九乘法表
*/
function nine() {
let result = "";
for (let index = 1; index <= 9; index++) {
for (let i = 1; i <= index; i++) {
result += `${i} x ${index} = ${index * i} `;
}
result += `\t\n`;
}
return result;
}
console.log(nine());
/*
1 x 1 = 1
1 x 2 = 2 2 x 2 = 4
1 x 3 = 3 2 x 3 = 6 3 x 3 = 9
1 x 4 = 4 2 x 4 = 8 3 x 4 = 12 4 x 4 = 16
1 x 5 = 5 2 x 5 = 10 3 x 5 = 15 4 x 5 = 20 5 x 5 = 25
1 x 6 = 6 2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36
1 x 7 = 7 2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42 7 x 7 = 49
1 x 8 = 8 2 x 8 = 16 3 x 8 = 24 4 x 8 = 32 5 x 8 = 40 6 x 8 = 48 7 x 8 = 56 8 x 8 = 64
1 x 9 = 9 2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81
*/
浏览器同源策略
- 相同协议,host,端口才是同源
- 防止了
CSRF的安全问题 - 防止
DOM操作的安全问题
JS延迟加载
defer属性async属性body之后setTimeOut放到异步队列中
写一个暂停函数
/**
*
* @param {Number} wait 微秒
*/
function sleep(wait) {
return new Promise((resolve) => setTimeout(resolve, wait));
}
sleep(2000).then(() => {
console.log(1);
});
代码解析
function test(){
console.log(test.prototype);
console.log(Object.getPrototypeOf(test));
//如果函数返回的值是引用类型(对象)的值时,new运算符将返回这个值
return test;
}
new test() instanceof Object; //true
new test() instanceof test; //false
//等价于
test instanceof test; //false
//test是一个Function,原型链为 Function.prototype -> Object.prototype -> null
//原型链上没有 test.prototype 出现,所以 test 并不是 test 的一个实例
随即打乱一个数组
/**
* 洗牌算法-快速打乱数组顺序
* 倒序循环这个数组
* 取范围从1到n的随机数k
* k与n交换
* 直到循环至数组的首个元素
*/
function arrShuffle(arr) {
const length = arr.length - 1;
for (let n = length; n >= 0; n--) {
let randomIndex = Math.floor(Math.random() * (n + 1));
let randomArr = arr[randomIndex]; //随机数k
//k与n交换
arr[randomIndex] = arr[n];
arr[n] = randomArr;
}
return arr;
}`
为什么{}+[]===0
{}被当成一个独立的空代码块- 所以上述表达式等价于
+[] = 0 0 === 0
({}+[])等于什么
- 加上括号后会当做表达式计算
- {}和[]都不是字符串
- {}->valueOf->返回对象本身->非原始值->toString->[object Object]
- []->valueIOf->返回对象本身->非原始值->toString->""
- "[object Object]" + " " = "[object Object]"
数组的交集,差集,补集,并集
const arr1 = [1, 3, 4];
const arr2 = [1, 2, 4, 5];
const setArr1 = new Set(arr1);
const setArr2 = new Set(arr2);
//交集
let intersect = arr1.filter((item) => setArr2.has(item));
//差集
let minus = arr1.filter((item) => !setArr2.has(item));
//补集
let complement = [
...arr1.filter((item) => !setArr2.has(item)),
...arr2.filter((item) => !setArr1.has(item)),
];
//并集
let union = Array.from(new Set([...arr1, ...arr2]));
console.log(intersect, "交集");
console.log(minus, "差集");
console.log(complement, "补集");
console.log(union, "并集");
//[ 1, 4 ] 交集
//[ 3 ] 差集
//[ 3, 2, 5 ] 补集
//[ 1, 3, 4, 2, 5 ] 并集
如何给li绑定事件(ul下有1000+个li)
//通过事件冒泡,在父元素ul上绑定事件
document.getElementById("ul-id").addEventListener("click",(e) => {
if (e.target.tagName === "li") {
console.log(e);
}
})
"1,2,3,4"split()
split有两个参数,第一个参数是字符串或正则表达式,表明按照什么规则分隔字符串.如果为空,则将整个字符串返回.第二个参数规定分隔的数量
"1,2,3,4".split() -> ["1,2,3,4"]
"1234".split("",2) -> ["1,2"]
Ajax请求
/**
* ajax请求
* 不可跨域请求
*/
function ajax(params) {
params = params || {};
//要发送的数据
params.data = params.data || {};
//GET,POST
params.type = (params.type || "get").toUpperCase();
//格式化数据
params.data = formatParams(params.data);
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
//4已接收到全部响应数据
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
let response = "";
const responseType = xhr.getResponseHeader;
//获取响应数据格式
if (responseType === "application/json") {
response = JSON.parse(xhr.responseText);
} else if (responseType.indexOf("xml") !== -1 && xhr.responseXML) {
response = xhr.responseXML;
} else {
response = xhr.responseText;
}
//成功回调函数
params.success && params.success(response);
} else {
//失败回调函数
params.error && params.error(status);
}
}
};
//true异步 false同步
const asyncFlag = params.async || true;
if (params.type === "GET") {
xhr.open(params.type, params.url + "?" + params.data, true);
xhr.send();
} else {
xhr.open(params.type, params.url, asyncFlag);
xhr.setRequestHeader(
"Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
xhr.send(params.data);
}
}
/**
* 数据格式化
*/
function formatParams(data) {
let params = [];
for (let name in data) {
params.push(
encodeURIComponent(name) + "=" + encodeURIComponent(data[name])
);
}
//时间戳 防止缓存
params.push("v=" + new Date().getTime());
//name=a&pwd=1&v=时间戳微秒
return params.join("&");
}
//示例
ajax({
url: "http://www.baidu.com", //请求地址
type: "GET", //请求类型 GET|POST
data: { wd: "时间戳" }, //请求数据
success: function (response) {
// 成功回调
console.log(JSON.parse(response));
},
error: function () {
//失败回调
console.log("失败");
},
});
红绿灯循环
async function trafficLight(color, wait) {
await new Promise((resolve) => {
console.log(color);
setTimeout(resolve, wait);
});
}
async function runLight() {
let i = 0;
while (i < 3) {
await trafficLight("红灯", 1000);
await trafficLight("绿灯", 2000);
await trafficLight("黄灯", 3000);
}
}
runLight();