JavaScript
数据类型
typeof '3' // string
typeof [] // object
typeof null // object
用来判断一个实例是否属于它的父类型
[] instanceof Array // 判断是否是由Array构造函数构造出来的
null instanceof Object // false
[] instanceof Array // true
模板字符串
`${'变量'}` // 变量
${list.map(item => {
return {
`<li>${item.name}</li>`
}
})}
字符串基本函数
var name = "df";
name.toUpperCase(); // 转为大写
name.toLowerCase(); // 转为小写
name.trim().length; // 去除字符串前后空格
name[0]; // 第一个字符串的元素
案例: 
字符串截取
slice
slice(0) // 截取的位置
var name = "dfegegdf";
name.slice(1); // "fegegdf" 从指定的下表开始截取到最后, 第二个参数表示截取的最后下标, 不包含最后
name.slice(1, 6); // "fegeg"
substr
name.substr(1, 6); // "fegegd" 包含最后下标
substring
name.substring(1, 7);
("fegegd");
indexOf
第二个参数表示开始查找的下标
startWidth
是否以某一个字符开始
数组的 reduce
注意: return 返回的值将会作为第一个形参的值
const arr = [1, 2, 3, 4, 5];
// pre 表示上一个, item表示当前, index表示下表, arr表示所有的整个数组
const sum = arr.reduce((pre, item, index, arr) => {
return pre + item;
}, 0); // 0表示第一个数, 也就是第一个pre的值
console.log(sum); // 15 实现累加效果
案列: 实现加权成绩计算
const scores = [
{
subject: "math",
score: 88,
},
{
subject: "chinese",
score: 95,
},
{
subject: "english",
score: 80,
},
];
const dis = {
math: 0.5,
chinese: 0.3,
english: 0.2,
};
const sum = scores.reduce((pre, item) => {
return pre + item.score * dis[item.subject]; // 把所有的分数来乘以所占的比重
}, 0);
console.log(sum); // 88.5
将树形改为数组
var data = [
{
id: 1,
name: "办公管理",
pid: 0,
children: [
{
id: 2,
name: "请假申请",
pid: 1,
children: [{ id: 4, name: "请假记录", pid: 2 }],
},
{ id: 3, name: "出差申请", pid: 1 },
],
},
{
id: 5,
name: "系统设置",
pid: 0,
children: [
{
id: 6,
name: "权限管理",
pid: 5,
children: [
{ id: 7, name: "用户角色", pid: 6 },
{ id: 8, name: "菜单设置", pid: 6 },
],
},
],
},
];
const arr = data
.reduce(function (pre, item, index, all) {
const callee = arguments.callee; //将运行函数赋值给一个变量备用, callee就是该函数的调用函数,
pre.push(item);
if (item.children && item.children.length > 0)
item.children.reduce(callee, pre); //判断当前参数中是否存在children,有则递归处理
return pre;
}, [])
.map((item) => {
// map不用管, 就是给里面添加children属性而已
item.children = [];
return item;
});
console.log(arr);
reduce 来计算一个字符串中每个字母出现次数
const str = "jshdjsihh";
const obj = str.split("").reduce((pre, item) => {
console.log("item", item);
console.log("pre", pre);
pre[item] ? pre[item]++ : (pre[item] = 1);
return pre; // 返回想要的结果, 用于下一次当pre形参的值, 最后会返回pre给obj
}, {});
console.log(obj); // {j: 2, s: 2, h: 3, d: 1, i: 1}
比较类型和强转
注意: 只需要记住, 强转的时候(if(a))是通过 Boolean(a), 而 if(a==b) 是通过 Number(a) = = Number(b)
let a = Boolean([]); // 强制转换
console.log("=======>", a); // true
let b = Number([]);
console.log("=======>", b); // 0
if ([] == true) {
// 比较类型, 转为数字进行比较
console.log("=======>", "b"); // 不会进入
}
repeat
'*'.repeat(3) // 将会返回 ***
字符串和其他类型转换
'324'*10
Number('34')
parseInt('455cehis')
let arr = [];
if (arr) {
console.log("=======>", "jir"); // 会输出, 原因会执行一次 Boolean([])操作, 执行完就为true
}
// 但是使用比较的形式, 而不是上面的转换就没有问题, 数组[],对象{},转换为布尔型都为真
if (arr == true) {
console.log("=======>", "执行"); // 不会输出, 因为 [] == false
}
console.log("[] == false", [] == false); // true
continue 和 break 高级用法
标签的用法:
let c = 0;
houdunren: for (let i = 0; i < 10; i++) {
hdr: for (let b = 0; b < 3; b++) {
c++;
console.log("=======>", c);
if (c > 10) break houdunren; // 直接终止的外层循环
}
console.log("=======>", "执行");
}
for of 以及 for in
for of 循环值, for in 循环下标
显示转换布尔类型
!执行两部操作, 转为布尔类型, 并且取反
方法一:
let number = 0; number = !number // number转为布尔false, 并且取反为true
方法二:
Boolean(number)
判断是否是整数
Number.isInteger(number);
NaN !== NaN
Apply 和 Math
let arr = [3, 45, 4, 54, 6, 46];
let res = Math.max.apply(null, arr); // 把this的指向改为null, 并且以数组的形式传入参数
console.log("=======>", res);
日期对象
let date = new Date();
// console.log("=======>", date*1); // 返回时间戳 160454646...
// let date1 = Date.now(); // 如果要进行运算可以使用这种方法
console.time("for");
for (let i = 0; i < 2000000000; i++) {}
console.timeEnd("for"); // for: 2329.112ms
const date34 = new Date(2019, 1, 12, 2, 34);
console.log("date34.getMonth()", date34.getMonth());
console.log("date34", date34);
时间格式化封装
const date = new Date();
function dateFormat(date, format = "YYYY-MM-DD HH:mm:ss") {
/**
* 处理添加零的操作
*/
function handleAddZero(val) {
return val > 9 ? val : "0" + val;
}
const config = {
YYYY: date.getFullYear(),
MM: handleAddZero(date.getMonth()),
DD: handleAddZero(date.getDate()),
HH: handleAddZero(date.getHours()),
mm: handleAddZero(date.getMinutes()),
ss: handleAddZero(date.getSeconds()),
};
for (const key in config) {
format = format.replace(key, config[key]); // 通过字符串的replace去将里面的关键字MM DD 替换掉即可
}
return format;
}
let result = dateFormat(date, "YYYY年MM月DD日");
console.log("result", result);
数组挖掘
- 引用类型引用类型, 修改后其引用的也会发生改变
- 通过 const 定义的数组, 改变数组中的一个元素的时候, 是可以的, 但是对整个数组进行修改就会报错
数组创建的方式
-
let arr = new Array(6)创建具有 6 个空的数组 -
let arr = [4,65,7,6]通过字面量的方式 -
let arr = Array.of(6)创建成[6]
监测数组
Array.isArray([])
伪数组转换数组
Array.form(obj)
展开语法妙用
function sum(...arg) {
console.log(arg); // 这里将打印出来一个数组, 因为 传入的参数是多个, 对多个参数进行了一次逆运算
}
...arg
数组的填充语法
let res = [1,234,3,5].fill('HoudunRen', 1,3) // 将下标从1到3进行填充, 不包含3
[ 1, 'HoudunRen', 'HoudunRen', 5 ]
截取数组
-
slice截取数组时, 不会对元素组发生改变 -
splice会进行改变
整理清空数组的常用方法
hd = []hd.length = 0hd.splice(0, hd.length)
其中注意:
let arr = [3, 54, 6, 6];
let hd = arr;
hd = [];
console.log("=======>", hd); // =======> []
console.log("=======>", arr); // =======> [ 3, 54, 6, 6 ] // 之前的数组仍然存在, 并且没有发生改变
// ---------------------
let arr = [3, 54, 6, 6];
let hd = arr;
hd.length = 0;
console.log("=======>", hd); // =======> []
console.log("=======>", arr); // =======> [] // 原数组发生变化
数组的查找
// 查找数组
let arr = [3, 54, 5, 465, 3];
arr.indexOf(3); // 从左侧开始查找3的下标,
arr.lastIndexOf(3); // 从左侧开始查找3的下标, 其中3是全等匹配, 后面可以跟查找的起始点
arr.includes(3); // 返回布尔类型
// 查找数组中的某一个元素的时候, 使用find 和includes的区别
let lessons = [{ name: "js" }, { name: "css" }];
lessons.includes({ name: "css" }); // 返回fase,虽然看似一样, 但是这里使用includes是查找的引用数据类型的地址, 两个地址是不同的
// 这时候就要使用find
lessons.find((item) => {
return item.name === "css";
}); // 能够成功找到指定的元素
数组的排序
// 排序
let arr = [4, 4, 66];
arr = arr.sort(function (a, b) {
return a - b; // 从小到大, b-a从大到小
});
插曲: 原生切换样式
ele.addEventListener("click", function () {
this.classList.toggle("disable"); // 切换类名disable
});
数组的迭代
// 数组的迭代
let arr = [34, 34545, 6];
let entries = arr.entries();
let res = entries.next();
console.table(res); // {value: [0, 34], done: false}
// 迭代器
for (const [key, value] of arr.entries()) {
console.log("=======>", value);
}
every 和 some
let arr = [34, 4, 6464, 6, 6];
arr.every(function (val, index, arr) {
return val > 20; // 是否每一个都大于20, 是返回true, 不是返回false
});
map
// map映射的使用
let lesson = [{ name: "css" }, { name: "js" }];
let hd = lesson.map(function (value, index, arr) {
// value.name = 'ccccccc'; // 对于引用类型, 原来的会发生改变
return { name: "cccc" }; // 原来的数组不会发生改变
return Object.assign({ click: 100 }, value); // 同上, 不会发生改变
});
console.table(lesson);
reduce 的案例
// reduce案例, 获取超过一万的商品名称
let goods = [
{ name: "苹果", price: 23444 },
{ name: "西瓜", price: 34345645 },
{ name: "菠萝", price: 34 },
];
goods
.reduce((arr, cur) => {
// 传递进去一个空数组
if (cur.price > 10000) {
arr.push(cur); // arr 用于存放超过的
return arr;
}
}, [])
.map((item) => item.name);
30 炫酷的文字 LOGO 效果元素构建
JavaScript 是什么
由布莱登 艾奇 1995 年 10 天开发出来的
JavaScript 是动态的, 弱类型的, 解释型的脚步语言
动态: 只有执行的时候才确定数据类型
弱类型: 变量数据的类型不是确定的, 可以随意进行改变
解释型: 和编译型区别, c 语言电脑在执行之前会把它先编译, 编译完了再执行,
解释型, 不需要先编译, 执行的时候一行一行去解释执行
脚本语言: 改语言可以嵌入其他语言中, 比如 js 可以嵌入 html 中
为什么有 JavaScript
一开始用来进行表单验证, 网络慢的时候, 用户提交一个信息, 过很长时间返回错误
JavaScript 组成部分
- ECMAscript
负责 js 的语法部分, ECMA 是一个组织, 规定了 js 的规范
- DOM
document object model 文档对象模型 (操作元素)
- BOM
browser object model 浏览器对象模型 (操作浏览器)
怎么用 JavaScript
程序和进程区别
程序: 代码的集合, 一般指文件, 程序是静态的
进程: 运行的程序, 就称为进程, 进程是动态的
不使用 var 申明的变量必须要赋值, 不然会报错
案例:
- 交换两个变量的值
var num1 = 5;
var num2 = 10;
num1 = num1 + num2;
num2 = num1 - num2;
num1 = num1 - num2;
数据类型
分为基本数据类型和对象数据类型
- 基本数据类型:
- number
- string
- boolean
- undefined
- null
- 复杂数据类型
- object
- array
typeof 的使用
typeof 求基本数据类型的时候, 只有 null 的时候, 不一样, 会打印出 object
js 高级
函数作用域
变量所起作用的范围,
作用于的作用:
变量在作用域起作用
局部变量和全局变量
局部变量: 在全局中起作用的变量(函数当做定义的变量)
全局变量: 在全局作用域当中的变量(函数外部定义的变量)
作用域分类
全局作用域
局部作用域
块级作用域
if () {
// 这里面就是块级作用域
}
作用域链
首先作用域链, 他的存在是在查找变量的时候才有意义, 在查找变量的过程, 首先从自己的作用域当中去查找, 如果没有就往上一级作用域当中去查找, 如果找到直接输出, 如果没有查找到就会一直往上查, 直到查找到全局作用域, 如果没有就报错
预解析
console.log(a); // 由于与解析, 在函数名和变量名一样的情况下会保留函数
a++; // function + 1 变为NaN
console.log(a);
function a() {
console.log("------", a);
}
var a = "jiodsjg"; // 重新对a进行赋值
console.log("------", a); // 打印 jiodsjg
临时死区 TDZ
这是因为 JavaScript 引擎在扫描代码发现变量声明时,要么将他们提升到作用域顶部(遇到 var 声明),要么将声明放在 TDZ 中(遇到 let 和 const 声明)。访问 TDZ 中的变量会触发运行时错误。只有执行过变量声明语句后,变量才会从 TDZ 中移除,然后方可访问。
看似很好理解,但不保证不犯错:
var value = "global"(
// 例子1
(function () {
console.log(value); // value is not defined;
let value = "local";
})()
);
// 例子2
{
console.log(value);
const value = "local";
}
本文由博客一文多发平台 OpenWrite 发布!