前端知识点要概
1.基本类型和引用类型
基本类型:Number, String, Null, Undefined, Boolean, Symbol(ES6数据类型)
引用类型:Object、Array、RegExp、Date、Function、单体内置对象(Global、Math)
1.1 类型检测使用 typeof进行基本类型检测,使用instanceof检测对象还是数组类型结果Undefined"undefined"Null"object"Boolean"boolean"Number"number"String"string"Symbol(ECMAScript 6 新增)"symbol"函数对象"function"任何其他对象"object"检测数组和对象:(Array其实是Object 的子类)
var a = [];
console.log(a instanceof Array); // true
console.log(a instanceof Object); // true
var a = {};
console.log(a instanceof Array); // false
console.log(a instanceof Object); // true
1.2 String操作String <=> Number:字符串转数字:
parseInt(str, 进制) // 默认十进制, 转化为整数,小数点后默认不保留
parseFloat(str) // 转化为浮点数
+str // 屌屌的转化方法, 但字符串包含非数字会报错
数字转字符串:
let str1 = num.toString();
let str2 = String(num);
let str3 = num + ‘’;
String <=> Array:字符串转数组
let arr = str.split(’,’) // 一般是空格或者逗号
数组转字符串
let str = arr.join(’’);
模板字符串Hello, ${变量}
1.3 常用正则去逗号
let newStr = str.replace(/,/g,’’);
去空格(一般输入框输入都要做这个)
let newStr = str.replace(/(^\s*)|(\s*KaTeX parse error: Undefined control sequence: \s at position 47: …= str.replace(/\̲s̲+/g,""); // 去除…/; // 4到16位(字母,数字,下划线,减号)
userPattern.test(str);
电话号码
let mPattern = /^1[34578]\d{9}$/;
附:密码/身份证号/E-mail/URL就不上了,太长了背了没意义,用的时候查就好了
1.4 Array操作在阿里腾讯头条的笔试机试中,对数组的操作可以说是前端算法的核心,数组操作的基本方法全是必背的重中之重。
1.4.1 Array.from()
将伪数组对象和可迭代对象[见附录]转化为数组:
let arr = Array.from(str/new Set()/new map());
转化数组后对每项进行操作
let arr = Array.from(‘123’, item => parseInt(item) + 1); // 2, 3, 4
去重(可以说这是最精彩的地方了)
Array.from(new Set(arr));
1.4.2 拷贝数组
使用以下方法能复制数组保存在堆内存中的值,但不能深拷贝数组(数组中的数组或者对象依旧只是复制了引用没有复制到其在堆内存中的值)。[数组和对象的深浅拷贝以及for循环递归实现方式本文不涉及]
let arr2 = […arr1];
let arr2 = arr1.slice();
let arr2 = arr1.concat([]); // 此方法不常用
深拷贝(对象也是如此)
let arr2 = JSON.parse(JSON.stringify(arr1));
1.4.3 找出最大最小值
Math.max.apply(null, arr);
Math.min.apply(null, arr);
// ES6的写法
Math.max(…arr);
1.4.4 数组排序
sort()
1.数组排序
function compare(a, b) { return a-b; }
arr.sort(compare);
2.数组对象排序(开发中常用)
function compare(property) {
return (obj1, obj2) => {
return obj1[property] - obj2[property];
}
}
let students = [{name: “xx”, age: 20}, {name: “hh”, age: 19}];
students.sort(compare(‘age’));
1.4.5 其他方法
push(item) // 末尾添加
pop() // 删除末尾
shift() // 删除开头
unshift() // 开头添加
sort() // 排序
reverse() // 反转
slice(start, end) // 截断拷贝, 接收起始和结束位置两参数并返回相应的数组,不影响原数组
splice(index, num) // 切片,取出从index位置开始的num个值,原数组被截取
splice(index, 0, sth) // 插入sth
splice(index, 1, sth) // 替换为sth
▲ forEach(item, index, array) // 对每一项执行某些操作
▲ filter(item, index, array) // 返回满足条件(true)的项组成的数组
▲ map(item, index, array) // 返回对每一项执行某些操作组成的数组
every(item, index, array) // 如果该函数对每一项都返回true,则返回true
some(item, index, array) // 如果该函数对某一项返回true,则返回true
reduce() // 从头到尾逐个遍历,迭代数组中的所有项
includes(sth, index); // 检测数组中是否含有sth,index代表开始查找的位置,返回布尔值
另:二分查找1.4.5 对象数组根据对象某key值去重(日常工作常用)let arr = [{showId: ‘C’, age: ‘11’}, {showId: ‘A’, age: ‘11’ },
{ showId: ‘B’, age: ‘11’}, { showId: ‘B’, age: ‘11’},
{ showId: ‘B’, age: ‘12’},{ showId: ‘B’, age: ‘13’}];
// 根据showId去重到新数组newArr
const newArr = [];
arr.forEach(item => {
// 过滤,如果有重复项就添加到过滤数组,那么长度就不为0就不会推入新数组。
// 如果没有重复项长度就为0就推入新数组。
newArr.filter(m => m.showId === item.showId).length === 0 &&
newArr.push(item);
});
1.5 Object操作1.5.1 创建创建方式:工厂模式、构造函数模式、原型模式、动态原型模式、寄生构造函数模式、稳妥构造函数模式。工厂模式function createObj(key) {
const obj = new Object();
obj.key = key;
obj.sayKey = function(){ 方法 };
return obj;
}
// 使用:const xuqingfeng = createObj(‘xuqingfeng’);
构造函数(对象属性最好用构造函数) + 原型(对象方法最好用原型),这样的话每个实例都会有自己的一份实例属性的副本,同时又共享着对方法的引用,最大限度地节省了内存:// 构造函数模式用于定义实例属性
function Person(name) {
this.name = name;
}
// 原型模式用于定义方法和共享的属性
Person.prototype = {
/* 默认情况下,所有原型对象都会自动获得一个constructor属性,
这个属性是一个指向prototype属性所在函数的指针,
这里的Person.prototype.constructor指向Person */
constructor : Person,
sayName : function() { 方法 }
}
ES6的简写(简直不要太好用, 三大框架很多写法基于此):属性简写:
let keyVal = ‘xuqingfeng’;
const obj = {keyVal}; // obj: { keyVal: ‘xuqingfeng’ }
方法简写:
const obj = {
method() {}
};
获取对象属性:
const { keyVal } = obj; // React的const { data } = this.props; 就是这么个原理,前提是对象中也有对应属性(key)
1.5.2 继承继承方式:原型链、借用构造函数、组合继承、原型式继承、寄生式继承、寄生组合式继承。组合继承这种方式既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。function A_Obj(name) {
this.name = name;
}
A_Obj.prototype.sayName = function() { A_Obj的方法 };
function B_Obj(name, age) {
A_Obj.call(this, name); // 继承属性
this.age = age;
}
B_Obj.prototype = new A_Obj(); // 继承A_Obj的所有方法
B_Obj.prototype.constructor = B_Obj; // 改变指向非常关键
B_Obj.prototype.sayAge = function() { B_Obj的方法 };
object.create()实现对象继承 - 特别地提及下这个方法,它可以直接使用创建一个新对象// 实现继承 - 方法
let extend = (Child, Parent) => {
Child.prototype = Object.create(Parent.prototype); // 拷贝Parent原型对象
Child.prototype.constructor = Child; // 将Child构造函数赋值给Child的原型对象
}
// 实例
const Par = function () { this.name = ‘xuqingfeng’; }
Par.prototype.getName = function () { return this.name; }
// 继承
const Cld = function () { Par.call(this); }
extend(Cld, Par);
// 使用
let testChild = new Cld();
console.log(testChild.getName())
1.5.3 拷贝浅拷贝:const copyObj = Object.assign({}, obj);
const Obj2 = {…Obj1};
浅拷贝并修改key的value或添加key与value: const Obj2 = {…Obj1, [‘key’]: ‘newOrCover’},示例如下const firObj = { a: ‘1’, s: { ss: ‘sss’ } };
const secObj = { …firObj, [‘b’]: ‘2’ }
secObj.a = ‘777’;
firObj.a = ‘666’;
secObj.s.ss = ‘secObj-s’;
firObj.s.ss = ‘firObj-s’;
console.log(firObj, secObj); // { a: ‘666’, s: { ss: ‘firObj-s’ } } { a: ‘777’, s: { ss: ‘firObj-s’ }, b: ‘2’ }
并集-合并两个对象/数组,后者覆盖前者(深度覆盖),最终形成并集: const Obj3 = Object.assign({}, Obj1, Obj2);,示例如下const firObj = { a: ‘1’, b: ‘b’, s: { ss: ‘fir-s’ } };
const secObj = { a: ‘2’, c: ‘c’, s: { ss: ‘sec-s’ } }
const newObj = Object.assign({}, firObj, secObj);
console.log(newObj); // { a: ‘2’, b: ‘b’, s: { ss: ‘sec-s’ }, c: ‘c’ }
const firArr = [1, 2, 3, ‘a’, ‘b’];
const secArr = [1, 3, 5, 7];
const newArr = Object.assign([], firArr, secArr);
console.log(newArr); // [ 1, 3, 5, 7, ‘b’ ]
深拷贝[ for循环递归深拷贝见上面数组,Object.assign合并对象和深拷贝移步MDN ]:let obj2 = JSON.parse(JSON.stringify(obj1));
1.5.4 其他方法Object.freeze() // 冻结对象:其他代码不能删除或更改任何属性。
Object.keys() // 返回一个包含所有给定对象自身可枚举属性名称的数组。
Object.values() // 返回给定对象自身可枚举值的数组。
Object.entries() // 返回给定对象自身可枚举属性的[key, value]数组
Object.defineProperty() // vue数据双向绑定的核心方法,建议上 MDN 一观
1.6 Function操作1.6.1 参数转化为数组(不知参数个数)数组原型slice方法function fc() {
Array.prototype.slice.call(arguments) ; // 这个方法可以将只要具有length属性的对象转成数组
}
▲ rest 参数function fc(…arr) { console.log(arr); }
参数cancat为数组function fc() { return [].concat.apply([], arguments); }
1.6.2 检测函数参数是否含有某个值(sth)[].includes.call(arguments, sth)
1.6.3 函数设置可改的默认参数function func1(a, b=‘123123’,c={id: 1}){
console.log(a,b,c)
}
func1(‘徐清风’,‘xuqingfeng’, 44) // 徐清风, xuqingfeng, 44
1.7 Math 与 Date Math方法:Math.ceil() // 执行向上舍入
Math.floor() // 执行向下舍入
Math.round() // 执行标准舍入
▲ Math.random() // 返回大于等于0小于1的随机数
获取当前时间:let now = new Date();
console.log(now.toLocaleString()); // 2018-8-23 17:48:47
console.log([now.getFullYear(), now.getMonth()+1, now.getDate()].join(’-’)); // 2018-8-23
2.JS知识点总结
js知识点总结 组CMAscript 基础语法
变量 数据类型 运算符 数组 函数 对象
BOM 浏览器对象模型
window对象(获取浏览器宽高)
history对象
location对象
DOM 文档对象模型 轮播图
元素获取 操作属性 操作样式 节点 事件 时间对象作用:(运营在用户端浏览器)
- 数据验证
- 动态创建和删除元素
- 操作元素的内容和样式
- 模拟动画
- 创建cookie
- ajax 请求数据
。。。。。。 - JSON格式的数据处理 *特征:面向对象
- 基于[对象]和[事件驱动]的松散型 解释型语言
- 客户端脚本语言,实现用户交互
BOM: 浏览器对象模型完成窗口与窗口之间的通信,window对象是其核心对象,history【前进,后退,刷新】 是一个对象 使用【window.history】location【地址】DOM【】screen【屏幕】frames[真窗口]navigationwindow对象:属性1-1:获取浏览器宽高a.ie8及以上
window.innerWidth [获取浏览器宽度]
window.innerHeight [获取浏览器高度]
b.ie8以下
document.documentElement.ClientWidth [宽度]
document.documentElement.ClientHeight 【高度】1-2: 重新获取浏览器宽高
window.οnreset=function () {
NewW=window.innerWidth;
NewH=window.innerHeight;
}
1-3:重新设置浏览器大小 window.οnresize=function(){ }1-4:浏览器滚动事件 window.οnscrοll=function (){ }2.浏览器左上角距离屏幕左上角的偏移量
window.screenTop [垂直偏移量]
window.screenLeft [水平偏移量]注意:因为window是核心,可以省略window不写方法alert() 弹出框prompt() 输入框confirm() 提示框,返回true或flaseclose() 关闭页面open(“url”) 打开页面(“打开的页面的路径【根据本html位置的相对路径】”)
open(“url”,"",“width=300,height=200”);setInterval(fn,毫秒数):隔毫秒数重复不断的执行一个函数fn方法1
let t =setInterval(fn,3000)
function fn(){
}
方法2
setInterval(function(){
},1000)clearInterval(t):清除setInterval的时间函数
let t =setInterval(fn,3000)
function fn(){
}
clearInterval(t)setTimeout(fn,1000) 隔一定的时间只执行一次函数cleanTimeout(t) 清除时间函数 【用法同上】获取表单的值
对象.value=
清空=“”history对象属性:
history.length 用来显示历史记录的长度方法history.forward() 前进history.back()后退history.go(0) 刷新 【1 前进,-1后退;不常用】location对象属性:设计获取当前页面的地址location.href=“ ” 设置或获取页面地址 设置新值location.host:主机名+端口号location.hostname:主机名location.port:端口号location.protocol:协议location.pathname: 路径location.search: ?后面的查询【搜索】字段方法location.reload( ) 重新加载location.replace(“网页.html”) 页面替换,不会增加历史记录location.assign(“网页.html”) 页面替换, 能够增加历史记录
DOM(文档对象模型)
document object model获取元素获取body:document.body获取html:document.documentElement1. 获取id名的元素:let 变量=document.getElementById(“id名”)
例子: let box=document.getElementById(“id名”)2.获取class名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByClassName(“class名”)
通过遍历改变样式
集合通过单个下表改变,不能全部用class名同时改变3. 获取标签名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByTagName(“标签名”)4.给对象加类
标签加1个类名
对象.className=“类名”
div加多个类名
对象.className=“类名1 类名2 ”5.指定范围的多层级获取【集合】
- 放在事件后
文字等或事件
注意:
~js的几种引入方式是相互关联的,可以相互操作与访问
~外部js中不能添加srcipt标签对
~嵌入式的js中不能添加src属性引入js的执行
1. 将srcipt标签对放最最后
2.在.js文档中加入
window.onload=function(){
需要执行的js代码块
}输出工具
弹出框:alter(’ ‘); 数字可加可不加’ ';
输出到控制台:console.log(‘输出到控制台’);
输出到html页面中[可以识别html的标签对,即解释为html语言]:document.write('
输出到html页面中
');输入工具弹出框输入:var num=prompt(“提示文本”,[默认值]);提示工具
confirm(“提示内容”);
confirm返回值为true和false注释
单行注释: ctrl+?或者/ //
块注释: ctrl+shift+/或者? /* 块 */ 拼接
- 用“+”拼接
- 模板字符串(es6):
<td>${i}-${j}</td>
; 拼接部分用``括起来,变量用 ${变量}
识别空格,换行等变量一个容器,存储数据变量的声明:var:let:let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效 - 适用于for循环
- 先声明,在使用
- 不允许在相同作用域内重复声明同一个变量。
- let可以识别块级作用域
- 不存在变量提升(先访问后声明) 报错:没有定义const声明一个只读的常量。一旦声明,常量的值就不能改变。声明常量的同时进行赋值,不赋值就会报错可以识别块级作用域不能重复声明不存在变量提升【先访问在声明】
PI;命名规范:数字。字母。下划线组成不能以数字开头区分大小写不能以关键字(js中已经用到的)命名不能以保留字(js中将来会用到的)命名有意义遵循的规则:首字母大写 (Array String Obiect) ;驼峰命名法 (getElementByld)赋值先声明再赋值
var num;
num=10;声明的同时赋值
var num=10;一次性声明多个变量,再赋值
var a,b,c;
a=1,b=2;
c=3;一次性声明多个变量同时复制
var a=1,b=2,c=3;注意事项:变量要先声明再访问,变量的默认值是undefined 新值可以覆盖旧值变量可以用var关键字重新声明不用var关键字声明时必须给变量赋值,并且为全局变量,先访问后声明变量,值为undefined:js执行时先预解析(即识别var 和function声明的变量,不赋值),在解析,一句一句执行。 数据类型根据在内存中的存储位置划分。基本数据类型存放在栈中,引用数据类型存放在堆中(指针存放在栈中,内容存放在堆中 )基本数据类型undefinednull 【空占位符】string 【也是对象】模板字符串 字符编码 ASCII utf-8 unicode【万国码】 gb2312 转义字符: \ \n[换行] \r \t[制表符] ’ \ “”
let 对象=new String(“ ”);
编码
对象.charCodeAt(2) 返回第2个位置的字符编码
String.fromCharCode(字符编码) 解码
查找元素
对象.charAt(0) 字符串的第0个位置的元素【查找字符】
查找下标
对象.indexOf(“ ”) 查找对应字符的下标,如果有返回下标,如果没有,返回-1【第一个字符开始的下标】
对象.lastIndexOf(“”) 倒着看查找,倒序看如果有返回下标,如果没有,返回-1【第一个字符开始的下标】
对象.search(“”) 正则:有返回0;没有返回-1;
对象.match(“”) 有的话,返回数组【返回值,下标,包含返回值的数组,】
没有 返回null
字符串的截取:【返回新值,不改变原内容】
对象.substr(开始下标,【截取的长度】)
对象.substring(开始下标,结束的下标),从开始下标开始到结束下标之前,不取到结束的下标
对象.slice(开始下标,结束的下标),从开始下标开始到结束下标之前,不取到结束的下标【数组的方法】
字符串大小写【转换】
let str=“AbCdEf”;
str.toLowerCase() 转换为小写
str.toUpperCase() 转换为大写
替换:
str.replace(“山”,“闪”);
转换【字符串转换数组】
let str=“1,2,3,4,5,6”;
arr2=str.split(“,”);booleannumber 2e3=2*10^3
二进制: 0b开头
八进制:以0o{0+字母o}开头,后跟0-7的数
十六进制:以0x开头,后跟0-9或者a-f
NaN:not a number 本来期望返回数值的操作,但并未返回数值的操作引用数据类型object(属性与方法的集合)数组,函数,对象深拷贝
let arr=【1,2,3,4】
let arr1;
arr1=arr; :传址
arr1 和 arr具有相同地址浅拷贝:
let arr=【1,2,3,4】
let arr1=【】
arr.foreach(function(value){
arr1.push(value)
})
判断变量的数据类型 ,其结果为字符串
typeof用法:
var num=“5555”;
typeof num;数据类型值情况typeof 的结果【看返回0 1代码的前三位】undefinedundefined undefinednullnull(空占位符) objectboolean 布尔型true false booleanstring 字符串型带" "或者’ ’ stringnumber 数值型整数,小数,八进制,十六进制,十进制 object 运算符表达式:能够求值的语句算术运算符
-
-
- / % ++var var++ --var var – +的特殊性
计算:操作对象是数值型
拼接:操作对象含有字符串,字符串中进行运算时,用()括起来自增与自减
++var: ++在前,先算++,在执行本行的其他语句
var++:++在后,先执行本行的其他语句,在算++关系运算符返回值为布尔值 ,即true或者false
- / % ++var var++ --var var – +的特殊性
-
< >= <= [等于] =[全等于]–> 数值和数据类型相同 !=[不等于] ![不全等] 如果比较的两个对象都是字符串[数字型,字符],按照ASCII表对应的ASCII码比较,逐位相比如果比较的两个对象都是数值,直接比大小如果一个操作对象是字符串,另一个是操作对象是数值,先尝试将字符串转换为数字,如果转换成功,按照数字比较大小;如果转换不成,则返回false1true; 0==false ; 数值相同= 数值和数据类型相同undefined=null赋值运算符
= +=[num+=10 等价于 num=num+10] -= *= /= %= 逻辑运算符[与或非]测量值与变量之间的逻辑关系假:0、false undefined null NaN “ ”【空字符串】真:其余为真&&与||或!非【用来取反】ABA && BA || B!Atruetruetruetruefalsetruefalsefalsetruefalsefalsetruefalsetruetruefalsefalsefalsefalsetrue返回值:第一步:先看与或非两边的真假第二步:在看返回的真假的内容&& 同真为真,返回第一个假值 【遵循短路原则:看到假值,后边的不看了】;全为真,返回最后一个真值|| 同假为假,返回第一个真值 【遵循短路原则:看到真值,后边的不看了】;全为假,返回最后一个假值 ! 取反;返回值只有ture或false运算符的优先级算术>关系运算符>逻辑运算符 三元运算符:
表达式?为真的执行语句:为假的执行语句 【类似if else】一元运算符: typeof + - new特殊运算符: () .流程控制代码按照指定条件的执行顺序顺序结构分支结构循环结构顺序结构语句按照从上到下的顺序进行执行循环结构当满足条件时,重复不断的执行一段代码for循环:明确知道次数
for(初始条件;终止条件;步进值){
}swith循环
switch(表达式【能够求值的语句】){
case 值1【表达式能取到的值】:语句1;break;
case 值2【表达式能取到的值】:语句2;break;
…
default: 语句;
}while循环
while(条件){
满足条件时,执行语句;
}
例子:
var j=0;
while(j<5){
console.log(1);
j++;
}do while循环执行顺序先执行循环体,在执行判断语句
do{
循环体;
}while(条件)
例子:
var i=0;
do{
console.log(1);
i++;
}(i<5)
循环结束continue满足条件终止本次循环
break满足条件,终止整个循环
分支结构当条件成立时执行相应的语句单分支结构
if条件:
if(表达式){
为真的执行语句【返回值为true执行的语句】
}双分支
if条件:
if(表达式){
为真的执行语句
}
else{
为假的执行语句
}多分支
if条件:
if(表达式1){
表达式1成立时执行语句
}
else if(表达式2){
表达式1不成立 但 表达式2成立时执行语句
}
else if(表达式3){
表达式1不成立且表达式2不成立【但】表达式3成立时执行语句
}
else{
以上表达式都不成立时执行的语句
}嵌套分支
if(){
if(){
}
else{
}
}
else{
}数学方法取随机数
Math.random() ; (0-1)取整
向下取整【向左取整】: rgb=Math.floor(Math.random());
向上取整【向右取整】: rgb=Math.ceil(Math.random());次幂[x的y次幂]
Math.pow(x,y)一维数组按照顺序排列的一组相关数据。特点:每一个数组元素都有一个特定的键名(即俗称的下标)[字符串类型]数组元素的默认值时undefined数组的声明[初始化数组]先声明后赋值
var arr=[];
arr[0]=89,arr[0]=“adc”,…;声明的同时赋值
var arr=[90,89,88,76,56];数组下标的范围访问数组元素,范围【0,n-1】数组的长度数组名.length; 例子: arr.length注意:数组的长度可变
arr=[90,89,88,76,56];
可以随时添加元素,可跳着添加。如:
arr[6]=“aaa”;数组元素可以时任意的数据类型
arr=[true,null,{name:},[1,2,3]]遍历数组元素访问数组的每一个元素1. 用for循环遍历数组
for(var i=0;i<arr.length;i++){
arr.[i]; 即可访问arr的每个元素
}2. 用for in循环遍历数组
for(var i in arr){
i; //代表arr的键名(下标)
arr[i]; //元素
}3.for of遍历元素
for(item of arr1){
arr2.push(item)
}4.foreach遍历数组
用法:
arr.forEach(function (value,index){
})
value[名字随便起]:数组中的当前元素【必须有】
index[名字随便起]:数组当前元素的下标【键名】【可选】清空数组arr.length=0二维数组声明:
var arr=[[1,2.3],[“a”,“b”],[78,89];访问:
arr[行][列]遍历
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
arr[i][j]
}
}数组身上的方法向数组的后面插入一个或多个元素(.push)
arr.push(需要插入的内容);删除数组最后一位:.pop
arr.pop()在数组之前插入: .unshift
arr.unshift("")在数组之前删除一位:.shift
arr.shift()万能的插入和删除:.splice()
arr.splice(开始的位置,长度,“再删除的位置加入的元素1”,“再删除的位置加入的元素2”,…);
不想删除,让其长度为0;
可以返回删除的值:arr.splice()是否包含某个元素: .includes
arr.includes(“被包含的内容”);截取元素: .slice
arr.slice(2,5):截取第2位开始的。第5位之前的连接多个数组:.concat
arr.concat([数组1],[数组2])数组的取反:.reverse
arr.reverse()把数组转换为字符串: .join
arr.join(“连接符(-/,/;/…)”)排序:.sort
arr.sort((x,y)=> x-y); 升序
arr.sort((x,y)=> y-x); 降序
arr.sort(function(x,y){
return x-y
})
查找: .find()
arr.find(item=>item>7) 找到第一个比7大的数
arr.find(item=>item%20) 找第一个偶数
arr.find(function(item){
return item%20;
})查找第一个符合条件的下标: .findIndex()
let index= arr.findIndex(function(item){
return item > top //返回布尔值,为真时返回下标
})返回符合条件的真假值:.some()
arr.some(item=>item>8);返回每一个符合条件的元素:.every()
arr.every(item=>item<10);筛选符合条件的:.filter()
arr.filter(item=>item%2==0); 返回新数组遍历数组(.forEach)arr.forEach
用法:
arr.forEach(function (value,index){
})
value[名字随便起]:数组中的当前元素【必须有】
index[名字随便起]:数组当前元素的下标【键名】【可选】处理每个元素:.map
arr.map(item=>{return item*10}) //让数组中的每个元素都执行一个函数,返回一个新数组全部方法concat()连接两个或更多的数组,并返回结果。copyWithin()从数组的指定位置拷贝元素到数组的另一个指定位置中。every()检测数值元素的每个元素是否都符合条件。fill()使用一个固定值来填充数组。filter()检测数值元素,并返回符合条件所有元素的数组。find()返回符合传入测试(函数)条件的数组元素。findIndex()返回符合传入测试(函数)条件的数组元素索引。forEach()数组每个元素都执行一次回调函数。indexOf()搜索数组中的元素,并返回它所在的位置。join()把数组的所有元素放入一个字符串。lastIndexOf()返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。map()通过指定函数处理数组的每个元素,并返回处理后的数组。pop()删除数组的最后一个元素并返回删除的元素。push()向数组的末尾添加一个或更多元素,并返回新的长度。reduce()将数组元素计算为一个值(从左到右)。reduceRight()将数组元素计算为一个值(从右到左)。reverse()反转数组的元素顺序。shift()删除并返回数组的第一个元素。slice()选取数组的的一部分,并返回一个新数组。some()检测数组元素中是否有元素符合指定条件。sort()对数组的元素进行排序。splice()从数组中添加或删除元素。toString()把数组转换为字符串,并返回结果。unshift()向数组的开头添加一个或更多元素,并返回新的长度。valueOf()返回数组对象的原始值。函数把实现某一特定功能的代码块封装起来,并能够重复调用定义函数1. 基本语法(function关键字)【调用可以在声明前,也可以在声明后】
function 函数名(形参1,形参2,…){
函数体;
return 返回值;【可有可无】 《并不向用户显示,仅是调用的数的值》
}2. 字面量,自变量【必须先声明在调用】【预解析】
var 变量=function (参数){
函数体;
}
调用 变量()3. 对象的方式【实例化对象】
let aa=new Function(“a”,“b”,“alter(a+b)”)
调用 aa(10,20)匿名函数定义与调用
(function (){
})()
定义:(function (){
}
调用【一般在定义的时候就调用】:
(function (){
})()箭头函数
定义:
let aa=()=>console.log(123);
let aa=(参数)=>{
多行函数体;
}
调用:
aa(实参) 函数的调用1. 函数名(实参1,实参2,….)2. 自变量()3.自变量(参数1,参数2)参数能够动态改变函数体的变量,使函数更加灵活形参:定义函数使写在括号里的量。其作用为接收实参形参默认值的传递
-
if else分支结构
if(flag==undefined){}
else{
} -
三元运算符【用的多】
flag=flag==underfined?"<":flag -
逻辑或||返回第一个真值【用的多】
flag=flag||"<" -
定义形参的时候直接赋值:当形参为undefined时给形参默认值
flag=25555;实参:函数调用时写在括号中的值。其作用为给形参传值全部的实参由arguments接收参数传递参数可以是任意的数据类型参数的传递按顺序传递:从左到右形参=实参 :一一对应的传递形参>实参:多余的形参赋值为undefined形参<实参:实参由arguments对象来接收剩余参数声明: …rest【为数组】
function 函数名(形参1,…rest){
函数体;
}rest和arguments对象的区别 -
rest接收多余的参数,arguments接收全部的实参
-
rest是数组,能够使用数组的方法,键名从0开始;
arguments对象类似数组,不能使用数组的方法函数的返回值:returnreturn 终止函数。遇到return,后面都不执行返回值可以是任意的数据类型一个函数内部可以有多条return分支语句,但最终只执行一条return语句只能返回一个值回调函数把一个函数的指针(函数名)作为参数传递给另一个函数,当指针调用函数时,这个函数叫做回调函数【高阶函数】:形参高阶函数和 返回值高阶函数指针类型
function math(num1,num2,callback) {
return callback(num1,num2);
}
function add(num1,num2) {
return num1+num2;
}
function sub(num1,num2) {
return num1-num2;
}
function mult(num1,num2) {
return num1*num2;
}
function div(num1,num2) {
return num1/num2;
}
document.write(math(1,2,div));函数类型
foreacharguments对象用来接收参数的详细信息每声明一个函数,在其内部自动生成arguments对象arguments对象只在函数内部起作用不是数组类似数组,可以用键名遍历数组(arguments[i]),其长度为arguments.length不能用数组身上的方法闭包函数内部的函数调用外部的函数的【变量】;
function fn1(){
let a=“456”;
function fn2(){
console.log(a)
}
return fn2;
}
let fn2=fn1();
fn2()// js中没有函数的重载:传的参数不同,执行不同的函数 作用域变量起作用的范围局部作用域优先于全局作用域[作用域链]全局作用域 -
在整个js中都能访问的变量,凡是进行修改,变量的值就会改变
-
类型【情况】
在函数外部用var声明的变量,即拥有全局作用域
不用var声明,但是赋值的变量就是全局变量,即拥有全局作用域;局部作用域
类型【情况】
形参是局部变量,即拥有局部作用域
在函数内部用var关键字声明的变量,也是局部变量,即拥有局部的作用域。块级作用域
{
括起来的就是块级作用域;
}内置顶层函数内置:ECMAscript自带的函数,本身就有;只要求知道如何让使用,不用关心如何封装顶层:在js代码中的任何位置都可以使用;escape():将传进来的字符串进行编码
escape(“编码的内容”); 编码内容一般为中文unescape():对编码的字符串进行解码
unescape(“字符串的编码”)Boolean():将其余数据类型转换为布尔型String():将任意数据类型转换为字符串型Number():将其余数据类型转换为数值型情况 -
null:0 “”:0 “ ”:0
-
false:0 true:1
-
undefined:NaN
-
进制数转换为十进制
-
去掉没有意义的后导0和前导0
-
字符串: 规范的浮点数,数值型字符串parseInt():将字符串转换为整数第一个位置为字母 (+、-)号 空格转换不成功,转换为NaNparseFloat():将字符串转换为小数只能转换规范的浮点数转换不成功,返回NaNisNaN():值是否够转换为数值型能转换为数值型返回false不能转换为数值型返回true作用:数据类型转换强制类型转换隐式数据类型转换:算数运算符,逻辑运算符,条件语句(if,while等)对象 类概念类:一群具有相同特征的对象集合的描述对象:具体存在的类个体属性:对象基础信息的描述方法:对象功能的描述定义对象构造函数(类),实例化对象
-
构造类
function 类名(color,price等其他形参){
this.color=color;
this.price=price; //实例化时,this指向实例化的对象
this.play=function(){}
}
-
实例化对象
let 对象=new 类名(实参); -
对象的属性【对象属性的添加】
对象.属性名=“属性值”; 访问:对象.属性名 / 对象【‘属性名’】 -
对象的方法【对象方法的添加】【方法是特殊的属性】
对象.方法名=function(){}; 访问:对象.方法名() -
遍历【i代表的是属性名】
for(let i in 对象){
i;//属性名,方法
对象【i】;//属性值
} -
对象属性的增删改查:
增加: 对象.属性名=“属性值”;
删除: delete 对象.属性名
修改: 对象.属性名=“属性值”
查讯: 对象.属性名 ; 对象【‘属性名’】JSON [注意格式] 【可直接定义对象】
1.定义
let 对象={
属性名:属性值, //属性名可以加引号,也可以不加引号
属性名:属性值,
方法名:function(){
},
方法名:function(){
}
}
2.增删改查
增加: 对象.属性名=“属性值”;
删除: delete 对象.属性名
修改: 对象.属性名=“属性值”
查找: 对象.属性名 ; 对象【‘属性名’】
3.遍历
for(let i in 对象){
i;//属性名,方法
对象【i】;//属性值
}
4.对象.constructor 返回 objectclass定义类,实例化对象重要的关键字[方法]constructor: 返回该对象的构造函数
使用: 对象.constructorinstanceof:判断函数是否为对象的构造函数?true:false;
使用 : 对象 instanceof 构造函数原型,原型链
最大的类:object:[prototype proto]
生成人类:person:【proto prototype】 proto继承父类的prototype
生成对象:xb【proto,prototype】 proto继承人类的prototypesing改变函数的指针
sing.call(xb,10,20)
sing.apply(sb,【10,20】)
sing.
将小白的say方法传给小红
say=xh.say
say.call(xh)递归函数自己调用自己,必须有一个 出口
function fn(num){
if(num0){
return 1;
}
else{
return num*fn(num-1)
}
}
function fnn(arr){
let arr1=[]
for(let i=0;i<arr.length;i++){
if(typeof arr[i]“object”){
arr1.push(fnn(arr[i]))
}
else{
arr1.push(arr[i])
}
}
return arr1;
}
console.log(fnn([0,[1,2],[2,3]]))节点:整个文档 元素【标签】 属性 文本 注释【节点】文档的节点
document.nodeName #document
document.nodeValue null
document.nodeType 9元素的节点
let box=documentquerySelector(“box”)
box.nodeName 大写的标签名
box.nodeValue null
box.nodeType 1节点nodeName(名字)nodeValue(值)nodeType(节点类型)文档节点#documentnull9元素节点大写的标签名null1属性节点大写的属性名属性值2文本节点#text文本3注释节点#comment注释内容8节点的获取1.childNodes:子节点
document.childNodes[1].childNodes2.parendNode:父节点
let box=document.querySelector(“box”) ;
3.上一个兄弟节点:previousSibling
box.previousSibling3.下一个兄弟节点:nextSibling
box.nextSibling4.上一个兄弟元素节点:previousElementSibling
box.previousElementSibling5.下一个兄弟元素节点:nextElementSibling
box.nextElementSibling节点的方法创建元素节点let div=document.createElement(“div”)在最后插入节点let box=document.querySelector(“.box”);box.appendChild(div)在之前插入节点.insertBefore(要插入的元素,插入位置之后的元素)let span=document.querySelector(“span”)box.insertBefore(span,div)创建文本节点let text=document.createTextNode(“必须有参数”)text.nodeValue=“这是span标签”span.appendChild(text)创建注释节点let comment1=document.createComment(“这是注释节点”);box.appendChild(comment1);创建属性节点let attr=document.createAttribute(“id”);添加/设置属性节点.setAttribute(“name”,“value”);//添加属性box.setAttributeNode(attr)添加:append 删除:remove删除标签节点 : box.removeChild(div)删除属性节点: box.removeChild(“属性名”)DOM(文档对象模型)document object model获取元素获取body:document.body获取html:document.documentElementDom对象1. 获取id名的元素:
let 变量=document.getElementById(“id名”)
例子: let box=document.getElementById(“id名”)2.获取class名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByClassName(“class名”)
通过遍历改变样式
集合通过单个下表改变,不能全部用class名同时改变3. 获取标签名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByTagName(“标签名”)4.给对象加类
标签加1个类名
对象.className=“类名”
div加多个类名
对象.className=“类名1 类名2 ”5.指定范围的多层级获取【集合】
1-3:重新设置浏览器大小window.οnresize=function(){
}
1-4:浏览器滚动事件window.οnscrοll=function (){
}
2.浏览器左上角距离屏幕左上角的偏移量
window.screenTop [垂直偏移量]
window.screenLeft [水平偏移量]注意:因为window是核心,可以省略window不写方法alert() 弹出框prompt() 输入框confirm() 提示框,返回true或flaseclose() 关闭页面open(“url”) 打开页面(“打开的页面的路径【根据本html位置的相对路径】”)
open(“url”,"",“width=300,height=200”);setInterval(fn,毫秒数):隔毫秒数重复不断的执行一个函数fn
方法1
let t =setInterval(fn,3000)
function fn(){
}
方法2
setInterval(function(){
},1000)clearInterval(t):清除setInterval的时间函数
let t =setInterval(fn,3000)
function fn(){
}
clearInterval(t)setTimeout(fn,1000) 隔一定的时间只执行一次函数cleanTimeout(t) 清除时间函数 【用法同上】获取表单的值
对象.value=
清空=“”history对象属性:history.length 用来显示历史记录的长度方法history.forward() 前进history.back()后退history.go(0) 刷新 【1 前进,-1后退;不常用】location对象属性:设计获取当前页面的地址location.href=“ ” 设置或获取页面地址 设置新值location.host:主机名+端口号location.hostname:主机名location.port:端口号location.protocol:协议location.pathname: 路径location.search: ?后面的查询【搜索】字段方法location.reload( ) 重新加载location.replace(“网页.html”) 页面替换,不会增加历史记录location.assign(“网页.html”) 页面替换, 能够增加历史记录 事件事件的添加方式
节点.οnclick=function(e){
}
只能添加一个
节点.addEventListener(“事件【click】”,事件处理程序,事件类型【布尔值】【可以不给】)
可以添加多个事件
将事件加在元素身上, 在js中定义事件的函数
阻止事件流
w3c浏览器
box.addeventListener(“click”,function(event){
let event=event|| window.event
event.stopPropagation()
},false)
ie浏览器
box.addeventListener(“click”,function(event){
let event=event|| window.event
event.stopPropagation()
event.returnValue=true;
},false)事件委派event.target:目标事件源【记录】获取到的是元素/属性:类型:节点;点谁获取到谁event.target.className 事件源的类名 正则定义用来描述或者匹配一系列符合某种规则的字符串,规则可以自己定义作用数据验证内容检索内容替换内容过滤正则对象创建正则对象实例化对象
let reg = new RegExp(“正则表达式[即规则]”,“模式修正符”)
必须传入字符串自变量,字面量
let reg=/正则表达式/模式修正符 ; (//代表定界符)正则对象常用的方法test(str) 检测正则对象是否能够匹配str , 返回值 true || falseexec( str ) 检测正则对象是否能够匹配str,如果能够匹配,返回一个拥有特殊属性的数组,如果不能匹配,返回null
let reg = new RegExp(“uek”,“gi”);
let bool=reg.test(“www.sxuek.com”); //bool=true
正则表达式原子原子:正则表达式最小的内容【只能匹配一位】\d 匹配 0-9 ;\D 匹配:除了0-9意外的字符\w 匹配:数字、字母、下划线\W 匹配:除了数字字母下划线以外的字符\s 匹配:空白 \n换行 \r回车 \t 制表符\S 匹配:除了空白以外的字符\b 单词的边界\B 非单词边界
let str=“abc1”
let reg=/\w/g;
reg.test(str)原子表【只匹配一个】定义: [ ]
匹配a-c
let str=“abcdef1”
let reg=/[a-c]/g;
reg.test(str)
匹配 [a-z] 匹配a-z
匹配 [a-zA-Z] 匹配a-z和A-Z
匹配 [a-zA-Z0-9] 匹配a-z和A-Z和0-9
匹配 [a-zA-Z\s] 匹配a-z和A-Z和空格元字符
. 代表所有的字符
| 或者原子组相当于变量默认保存在内存中;可以使用\1 \2等方式依次引用()中的内容(?: )可以使原子组不在内存中存储,不可以调用
let str1=“山西优逸客”
let str2=“陕西优逸客”
let reg=/(山西|陕西)优逸客/g;
reg.exec(str1)
let str=“
let reg=/<(div)>hello</\1>/g
reg.exec(str);
let str=“
let reg=/<(div)>\1</\1>/g
reg.exec(str);
let str=“
let reg=/<(div)>(山西|陕西)优逸客-\2</\1>/g
let reg=/<(div)>(?:山西|陕西)优逸客-\2</\1>/g \2不会被引用数量[手机号/身份证号]
- 0个或者多个 》=0 贪婪
let phone=“18335219360”;
let reg=/\d*/g
reg.exec(phone)
- 1个或者多个 》=1
? 0个或者一个 吝啬
{11}限制长度为11
{15,18} 长度为 15-18
{6,} 长度为6以及以上
贪婪吝啬 +? 变成吝啬
?
+?
{11,}?
{11,20}?
边界判断【限制长度】
^ 以…开始
$ 以…结束
let reg=/^(0351)-\d{7}KaTeX parse error: Undefined control sequence: \b at position 39: …ord" let reg=/o\̲b̲/ 模式修正符可以搭配使用 …/
密码 /1{6,18}KaTeX parse error: Expected group after '^' at position 12: / 十六进制值 /^̲#?([a-f0-9]{6}|…/
电子邮箱 /^([a-z0-9_.-]+)@([\da-z.-]+).([a-z.]{2,6})KaTeX parse error: Undefined control sequence: \d at position 9: / /^[a-z\̲d̲]+(\.[a-z\d]+)*…/
URL /^(https?😕/)?([\da-z.-]+).([a-z.]{2,6})([/\w .-])/?KaTeX parse error: Undefined control sequence: \d at position 20: … 地址 /((2[0-4]\̲d̲|25[0-5]|[01]?\…/
HTML 标签 /<([a-z]+)([<]+)(?:>(.)</\1>|\s+/>)KaTeX parse error: Undefined control sequence: \S at position 25: …释 (?<!http:|\̲S̲)//.*
Unicode编码中的汉字范围 /2+$/ 日期对象/函数
自定义时间
let ay=new Date(“2018/8/8 12:00:00”)
let ay1=new Date(“12:00:00 2018/8/8”)
let ay2=new Date(“2018,0,8”) //月份从0开始
获取当前格林尼治时间
let now=new Date() //获取当前格林尼治时间
now.setFullYear(2020) 设置年份
now.setMonth(5) 6月份
now.setDate(26) 26号
now.setHours(12) 12时
now.setMinutes(0) 分
now.setSeconds(0) 秒
now.setMilliseconds(0) 毫秒
获取世界协调时间【用法同上】
now.setUTCFullYear()
now.setUTCMonth()
now.setUTCDate()
now.setUTCHours(12) 12时
now.setUTCMinutes(0) 分
now.setUTCSeconds(0) 秒
now.setUTCMilliseconds(0) 毫秒
//获取时间
now.getFullYear() //now.getUTCFullYear()
now.getMonth()+1
now.getDate()
now.getDay() 星期
now.getHours()
now.getMinutes()
now.getSeconds()
now.getMilliseconds(0)
//获取毫秒数
now.getTime() 1970.1.1.0的毫秒数时间案例
倒计时
jishi()
setInterval(jishi,2000);
function jishi(){
let arr=daoJiShi();
span9.forEach(function (value,index) {
value.innerText=arr[index];
})
}
function daoJiShi() {
let arr=[];
let now=new Date();
let future=new Date(2018,6,26,18);
let times=future.getTime(); //未来的毫秒数
let time=now.getTime();//现在的毫秒数
let juXianZai=Math.floor((times-time)/1000); //2018.9.1到现在时间的秒数
let Month=Math.floor(juXianZai/(30246060));
arr.push(Month);
juXianZai=juXianZai%(30246060);
let Day=Math.floor(juXianZai/(246060));
arr.push(Day);
juXianZai=juXianZai%(246060);
let shi=Math.floor(juXianZai/(6060));
if(shi>0 & shi<9){
shi=“0”+shi;
}
arr.push(shi);
juXianZai=juXianZai%(60*60);
let fen=Math.floor(juXianZai/(60));
if(fen>0 & fen<9){
fen =“0”+fen;
}
arr.push(fen);
let miao=Math.floor(juXianZai%60);
if(miao>0 & miao<9){
miao=“0”+miao;
}
arr.push(miao);
return arr;
}
}
轮播图双下标
window.οnlοad=function () {
let Box1=document.querySelectorAll(“div.box .box1”); //5个小盒子盒子
let box=document.querySelector(“div.box”); //大盒子
let Width=parseInt(getComputedStyle(box,null).width); //小盒子的宽度
let Left=document.querySelector(“div.box .left”); //左右两个盒子
let Right=document.querySelector(“div.box .right”);
let circle=document.querySelector(“div.box .circle”); //小圆圈
let Son=document.querySelectorAll(“div.box .circle .son”);//小点
console.log(Box1,Width,Left,Right,Son);
let now=0;
let next=0;
flag=true;
let t=setInterval(move2,2000);
//右向左
function move2() {
next++;
if(nextBox1.length){
next=0;
}
// 就绪
Son[next].classList.add(“son1”);
Son[now].classList.remove(“son1”);
Box1[next].style.left=Width+“px”;
//动画
animate(Box1[next],{left:0});
animate(Box1[now],{left:-Width},function () {
flag=true;
});
now=next;
}
//左向右
function move3() {
next–;
if(next<0){
next=Box1.length-1;
}
//就绪
Box1[next].style.left=-Width+“px”;
Son[next].classList.add(“son1”);
Son[now].classList.remove(“son1”);
//动画
animate(Box1[next],{left:0});
animate(Box1[now],{left:Width},function () {
flag=true;
});
now=next;
}
box.οnmοuseenter=function () {
clearInterval(t);
}
box.οnmοuseleave=function () {
t=setInterval(move2,2000)
}
Left.οnclick=function () {
if(flagfalse){
return;
}
if(next0){
return;
}
flag=false;
move3();
}
Right.οnclick=function () {
if(flagfalse){
return;
}
if(nextBox1.length-1){
return;
}
flag=false;
move2();
}
Son.forEach(function(value,index){
value.οnclick=function(){
if(indexnow){
return;
}
else if(index>now){
Son[index].classList.add(“son1”);
Son[now].classList.remove(“son1”);
//就绪
Box1[now].style.left=-Width+“px”;
Box1[index].style.left=0;
}
else if(index<now){
Son[index].classList.add(“son1”);
Son[now].classList.remove(“son1”);
//就绪
Box1[now].style.left=Width+“px”;
Box1[index].style.left=0+“px”;
}
now=next=index;
}
})
}单下标
tupian下包含 a a下包含img
tupian x y 同级
let tupian = daohang.getElementsByClassName(“tupian”)[0];
let a1 = tupian.getElementsByTagName(“a”);
let img = tupian.getElementsByTagName(“img”);
let z = daohang.getElementsByClassName(“z”)[0];
let y = daohang.getElementsByClassName(“y”)[0];
let x = daohang.getElementsByClassName(“x”)[0];
let Son = x.getElementsByClassName(“son”);
num = 0;
let t = setInterval(move, 2000);
function move() {
num++;
if (num == img.length) {
num = 0;
}
for (let i = 0; i < img.length; i++) {
a1[i].style.zIndex = 20;
Son[i].className = “son”;
}
Son[num].className = “son son1”;
a1[num].style.zIndex = “30”
}
img.onmouseenter = function () {
clearInterval(t)
}
img.onmouseleave = function () {
t = setInterval(move, 2000)
}
tupian.onmouseenter = function () {
clearInterval(t);
}
tupian.onmouseleave = function () {
t = setInterval(move, 2000);
}
z.onclick = function () {
a1[num].style.zIndex = 20;
}
y.onclick = function () {
move();
}
for (let i = 0; i < Son.length; i++) {
Son[i].onclick = function () {
for (let j = 0; j < Son.length; j++) {
Son[j].className = “son”;
}
a1[i].style.zIndex = “40”;
Son[i].className = “son son1”;
num = i;
}
}
function move1() {
num–;
if (num < 0) {
num = a1.length - 1;
}
for (let j = 0; j < a1.length; j++) {
a1[j].style.zIndex = 20;
Son[j].className = “son”
}
Son[num].className = “son son1”
a1[num].style.zIndex = 30;
}
z.onclick = function () {
move1();
}透明度轮播