大数据类型使用 bigInt
null 有数据位置但是没有数据,undefined 是完全没有数据位置
object{} 对象,array[]数组
if 中如果没有写判断语句则括号中的内容会被转换成布尔类型(隐式转换)
switch 的 key 和 val 的比较是===绝对相等
switch 中的 break 用来中断程序
&&与,||或,!非
语句和表达式的区别
&&有一个是 flash 就是 flash,前面成立将值付给后面
|| 有一个是 true 就是 true ,前面不成立将值给后面
使用 ID 属性获取元素标签,用 document.getElementById(“标签的 ID 属性名”)
使用 class 属性获取元素标签,使用 document.getElementsClassName(“标签的 Class 属性名”)[第几个标签元素]
使用元素标签选择器,使用 document.getElementsTagName(“元素标签名”)[第几个元素标签"]
使用 querySelector 选择标签,使用方法用 document.querySeletor(用 class 名称)
使用 querySelectorAll 选择标签,使用方法使用 document.querySeletorAll(用 class 名称),与没有 All 不同的是这个选择的是数组
获取元素内部结构,用选择器选择出来标签,在用 innerHtml 可以拿到标签内部的标签,获取的时候能够获取结构,设置的时候能够识别结构
获取元素内部的文本,用选择器选择出来标签,在用 innerText 可以拿到标签内部的文本
给元素标签设置样式:’选择的标签属性.style.需要设置的样式名称 ’
查看标签样式,使用方法 style 但是只能查找到行内设置的样式
设置标签的类名,使用 className 可以获取和谁知标签的类名
值类型的赋予相当于是拷贝,引用类型等于指向(地址)
classList 查看类名列表,插入类名使用:类名.classList.add (“类名”)
移除类名使用:类名.classList.remove (“类名”)
在类名中移除或者添加使用:获取的标签.classLista.toggle(“类名”)
点击实践用 onclick:使用方法:选中的元素.onclick = function(){}
使用鼠标滑入功能 onmouseenter,鼠标滑出功能 onmouseleve
function a(){}
,函数表达式方式var a = function(){}
(function (){})()
(function(){
alert("自执行函数");
})();
(()=>{
alert("自执行函数");
})();
var result = index => index + 1;
var result = function(index) {
return index + 1;
}
var result = function(index) {
inner();
console.log(this.celler)
//指向的宿主环境是document
return index + 1;
}
var inner = function(){
console.log(inner.caller);
//指向的是result函数
console.log(arguments.callee);
//指向形参列表所在的函数inner
}
result();
for(var i =0 ; i < array.length ; i++){
console.log("这是第"i"个数组:"li[i]);
//依次打印出来数组的下标及每个数组元素
}
array[array.length] = "需要添加的数值"
for(var key in arr){
console.log(arr[key]);
//依次输出数组arr的每一个元素
}
array = [['1','2','3'],
['1','2','3'],
['1','2','3']]
var colors = ['red', 'pink'];
var res = colors.push('blue');
// 原数组
console.log(colors);//['red', 'pink', 'blue']
// 返回值
console.log(res);//
var colors = ['red', 'pink'];
var res = colors.pop();
// 原数组
console.log(colors);//['red']
// 返回值
console.log(res);//pink
var colors = ['red', 'pink'];
var res = colors.shift();
// 原数组
console.log(colors);//['pink']
// 返回值
console.log(res);//red
var colors = ['red', 'pink'];
var res = colors.unshift('blue', 'green');
// 原数组
console.log(colors);//['blue', 'green', 'red', 'pink']
// 返回值
console.log(res);//
var ary=[1,2,3];
var res=ary.reverse();
console.log(res);//[3,2,1];
console.log(ary);//[3,2,1];
- 如果没有传参数,只能对 10 以内的数进行排序
- 需要在 sort()括号内传入一个函数(回调函数)进行判断排序
var oldAry = [3, 1, 5, 11, 20];
var returnValue = oldAry.sort((a,b)=>a-b)
console.log(oldAry, returnValue);
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(0, 2);
console.log(nums);// [3, 4, 5, 6]
console.log(res);// [1,2]
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(3, 0, 7, 8, 9);
console.log(nums);//[1, 2, 3, 7, 8, 9, 4, 5, 6]
console.log(res);// []
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(0, 3, 7, 8, 9);
console.log(nums);//[7, 8, 9, 4, 5, 6]
console.log(res);// [1, 2, 3]
如果不传参数或者参数只有一个(0),表示将原数组复制一遍
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(1);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5, 6]
2. 如果有两个参数,slice()返回从开始索引到结束索引对应的所有元素
> 两个参数 表示开始下标到结束下标,包含开始,不包含结束
> 如果开始的位置大于结束的位置,返回值是空数组没有返回值
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(1, 5);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5]
concat()
var ary1 = [1, 2, 3];
var ary2 = [4, 5, 6];
var res = ary1.concat(ary2, "学校", "同学");
console.log(ary1);//[1, 2, 3]
console.log(res);//[1, 2, 3, 4, 5, 6, '学校', '同学']
toString()
var ary1 = [1, { a: 1 }, null, undefined, 3];
var res = ary1.toString();
console.log(ary1);//[1, {a:1},null, undefined, 3]
console.log(res)//1,[object Object]
join()
var ary1 = [1, 2, undefined, 3, { a: 1 }];
var res = ary1.join("|");
console.log(ary1);//[1, 2, undefined, 3, { a: 1 }]
console.log(res)// 1|2||3|[object Object]
eval(res) //==> eval 执行计算
includes()
var ary = [1,2,3,1,1,2,3];
var returnVlue = ary.indexOf(1,2);
console.log(returnVlue,ary);//3,原数组
var ary = [1,2,3,1,1,2,3];
var returnVlue = ary.lastIndexOf(1,2);
console.log(returnVlue,ary);//4,原数组
var ary = [1,2,3,1,1,2,3];
ary.forEach(function(item,value){
console.log(item,value);
})
var ary = [1,2,3,1,1,2,3];
var res = ary.map(function(item,value){
return item + 1;
})
console.log(res)
//[2,3,4,2,2,3,4]
数组去重会出现下标塌陷问题
var ary = [1, 2, 3, 1, 1, 2, 3];
for (var i = 0; i < ary.length - 1; i++) {
for (var j = i + 1; j < ary.length; j++) {
if (ary[i] == ary[j]) {
ary.splice(j, 1);
j--;
//解决下标塌陷问题,删除重复数组后将下标前移
}
}
}
console.log(ary);
var ary = [1, 2, 3, 43, 2, 1, 2, 3, 4, 11, 1, 1, 1, 1, 1, 1];
var obj = {};
for (var i = 0; i < ary.length; i++) {
var key = ary[i];
if (typeof obj[key] == "undefined") {
obj[key] = ary[i];
} else {
ary.splice(i, 1);
i--;
}
}
console.log(ary);
var ary = [1, 2, 3, 43, 2, 1, 2, 3, 4,11,1,1,1,1,1,1];
var obj = {};
var ary1 = [];
for (var i = 0; i < ary.length; i++) {
var key = ary[i];
obj[key] = ary[i];
//对象的属性名不能重复的特性
}
for(var i in obj){
ary1.push(obj[i]);
}
console.log(ary1);
var ary = [1,2,3,4,2,1,3,4,5,6];
var newAry = [];
for(var i in ary){
var item = ary[i];
if(newAry.indexOf(item) == -1){
newAry.push(ary[i]);
}
}
console.log(newAry);
var ray = [1, 4, 3, 2, 6, 5, 7];
var npm;
for (var i = 0; i < ray.length - 1; i++) {
for (var j = 0; j < ray.length - 1 - i; j++){
if(ray[j] > ray[j+1]){
npm = ray[i];
ray[i] = ray[j];
ray[j] = npm;
}
}
}
console.log(ray);
function total(num) {
if (num > 100) return 0;
return num + total(num + 1);
}
console.log(total(1));
var sty = "aewewerrer";
console.log(sty.charAt(0)); //a
var sty = "aewewerrer";
console.log(sty.charCodeAt(0)); //97
var sty = "aewewerrer";
console.log(sty.indexOf("e"));//1
console.log(sty.lastIndexOf("e"));//8
var sty = "aewewerrer";
console.log(sty.slice(3, 5));
var sty = "aewewerrer";
console.log(sty.substr(3, 4));//ewer
var sty = "aewewerrer";
console.log(sty.replace("aew", "yyy")); //yyyewerrer
作用:用符号将字符串分割成数组
var sty = "aewewerrer";
console.log(sty.split(""));
//[a,e,w,e,w,e,r,r,e,r]
var str = "https://www.baidu.com/s?tn=44004473_41_oem_dg&ie=utf-8&wd=%E5%B0%8F%E7%B1%B3%E5%AE%98%E7%BD%91";
function preat(str) {
var strSlice = str.split("?");
var strArry = strSlice[1].split("&");
var obj = {};
for (var i = 0; i < strArry.length; i++) {
strArry[i] = strArry[i].split("=");
obj[strArry[i][0]] = strArry[i][1];
}
return obj;
}
console.log(preat(str));
Math.abs():绝对值
console.log(Math.abs(-1)); // 1
Math.floor()向下取整,无论是正数还是负数都取小的
console.log(Math.floor(1.7));// 1
Math.ceil()向上取整,无论是正数还是负数取的都是大的
console.log(Math.floor(1.7)); // 2
Math.round()对小数四舍五入
console.log(Math.round(1.6)); // 2
Math.sqrt()开平方
console.log(Math.sqrt(9)); // 3
Math.pow(n,m)取幂
Math.PI()圆周率 π
Math.min()取最小值
Math.max()取最大值
math.random()取 0 到 1 不包含 1 的随机数
输出水仙花数
for (var i = 101; i < 1000; i++) {
var a = i % 10;
var b = Math.floor(i / 10 % 10);
var c = Math.floor(i / 100);
if (i == a * a * a + b * b * b + c * c * c) {
console.log(i)
}
}
var str = "smonsigjagidngoaenaoenbognaehuraehuabeiaerbiuaeerbngaegnagnkanoiawnoawnegoagnoianoiangoanegioniognaewonoagawhgineaonboaernb";
obj = {};
for (var i = 0; i < str.length; i++) {
var key = str[i];
//判断数组中的属性名是否存在
if (typeof obj[key] === "undefined") {
obj[key] = 1;
//如果不存在就给属性值赋1
} else {
obj[key] += 1;
//如果存在就给属性值加一
}
}
var newMax = 0;
var code = '';
//遍历对象查找字符出现最多的数
for (var k in obj){
//判断如果出现辞职大于newMax就将这一项付给newMax
if(obj[k] > newMax){
newMax = obj[k];
code = k;
}
}
console.log(`字符串str中最大的字符是${code}一共有${newMax}个`);
var arr = [4, 3, 1, 7, 8, 5, 34, 56, 78, 98, 13];
function sory(arry) {
if (arry.length <= 1) return arry;
var lest = Math.floor(arry.length / 2);
var left = [];
var reight = [];
var itrm = arry[lest];
for (var i = 0; i < arry.length; i++) {
if (i != lest) {
if (arry[i] < arry[lest]) {
left.push(arry[i])
} else {
reight.push(arry[i]);
}
}
}
return sory(left).concat(itrm, sory(reight));
}
console.log(sory(arr));
重点:回流必定会触发重绘,重绘不一定会触发回流。重绘的开销较小,回流的代价较高。
var divName = document.getElementsByClassName("box1")[1];
console.log(divName.getAttribute("name"))
let arry = [2, 3, 4, 53, 4, 5, 4, 32, 43, 54, 46, 578, 667];
function sort(arr = []) {
for (let i = 0; i < arr.length; i++) {
//索引i之前的那些项都是排好序的
let temp = arr[i];
let j = i - 1;
while (j >= 0 && temp < arr[j]) {
//判断arr[j]是否到了第一位以及判断temp和arr[j]的大小
arr[j + 1] = arr[j];
//对arr[j]进行位置调换
j--;
}
arr[j + 1] = temp;
}
return arr;
}
console.log(sort(arry));
nodeType:能够分辨节点到底是什么节点,只读
获取行内属性节点:getAttributeNode()
节点类:
function previouSibing(ele) {
let h2 = document.getElementsByTagName("h2")[0];
let per = h2.nextSibling;
while (per && per.nodeType != 1) {
per = per.nextSibling;
}
return per;
}
console.log(previouSibing());
元素类:
…在函数形参中是剩余运算符,在其他地方时展开运算符
ele.appendChild(“需要插入的元素”):把创建的元素元素添加到 ele 内部的最后一项
如果添加一个已经存在的选中标签,那么不会增加,只是移动到子元素末尾
var ul = document.getElementsByTagName("ul")[0];
var div = document.createElement("div");
ul.appendChild(div);
console.log(ul.innerHTML)
ele.insertBefore(div,a):给 ele 内部的 a 前面插入一个 div 标签
<div id="id1">
<p class="p1" id="p1">这是P1p>
div>
<script>
var div = document.getElementById("id1");
var p1 = document.getElementById("p1");
var odiv = document.createElement("div");
var returnDom = div.insertBefore(odiv, p1);
console.log(div);
script>
createElement(“div”);创建一个 div 标签
createTextNode(“创建一个文本节点”):创建一个文本节点
cloneNode:把某一个节点进行克隆
cloneNode(true):(深克隆)把节点包含的所有内容进行克隆
<div id="id1">
<p class="p1" id="p1">这是P1p>
div>
<script>
var res = id1.cloneNode();
var res2 = id1.cloneNode(true);
console.log(res);
console.log(res2);
script>
removeChild:移除元素
<div id="id1">
1111
<p class="p1" id="p1">这是P1p>
div>
<script>
id1.removeChild(p1);
console.log(id1);
script>
ele.getAttibule(“xxx”):获取行内属性
ele.removeAttibule(“xxx”):删除行内属性
ele.setAttribute(“xxx”,“xxx”):设置行内属性
box.setAttribute("index", 1);
box.getAttribute("index");
box.removeAttribute("index");
console.log(box)
// 设置
// box["aa"] = 22;
// 获取
// box["aa"]
//移除
// delete box["aa"];
获取日期 new Date();
let time = new Date();
console.log(time);
console.log(time.getFullYear());
console.log(time.getMonth());
console.log(time.getDate());
console.log(time.getHours());
console.log(time.getMinutes());
console.log(time.getSeconds());
console.log(time.getDay());
//Sat Mar 26 2022 16:14:02 GMT+0800 (中国标准时间)
//2022
//2
//26
//16
//29
//55
//6
Date()括号中能够传入时间戳
time.getTime():是距离 1970 年 1 月 1 日的 00:00:00 的毫秒数
console.log(time.getTime(2022/12/3));
//1648283851978
new Date("时间戳");
就能转成公历日期setInterval(()=>{},1000)
//钟表函数
function times() {
var apan = document.getElementsByTagName("span")[0];
let arry = ["日", "一", "二", "三", "四", "五", "六"];
setInterval(function () {
let time = new Date();
let year = time.getFullYear();
let month = time.getMonth();
let date = time.getDate();
let hours = time.getHours();
let minutes = time.getMinutes();
let seconds = time.getSeconds();
let day = time.getDay();
apan.innerText = `现在是第${year}年${month + 1}月${date}日星期${arry[day]}${hours}时${minutes}分${seconds}秒`;
}, 1000);
}
times();
function num(max, min) {
return Math.floor(Math.random() * (max - min) + min);
}
function getCode() {
var str = "0123456789";
var strin = "";
for (var i = 0; i < 4; i++) {
strin += str[num(4, 0)];
}
let div = document.getElementsByTagName("div")[0];
return div.innerHTML = strin;
}
getCode();
let timer = setInterval(() => {
getCode();
}, 1000);
setTimeout(() => {
clearInterval(timer);
}, 1000 * 10);
function fn(){
console.log(a);
return function f1(){
}
var a=3;
}
fn();
function f2(){
console.log("f2");
}
// 自执行函数在此处不进行变量提升
(function (){
console.log(a);// undefined, 照常进行变量提升
var a=3;
})();
"d" in window//判断window中有没有d
;const 声明的变量指针是不能改的
const num = 300; num = 200;
会报错
const num//会报错,没有初始值
console.log(a, b);//undefined undefined
var a = 12,
b = 12;
function fn() { // undefined 12
console.log(a, b);
var a = b = 13;
console.log(a, b); // 13 13
}
fn();
console.log(a, b); // 12 13
全局栈内存页面关闭是会被释放,普通函数一般调用结束会被释放
闭包让你可以在一个内层函数中访问到其外层函数的作用域
闭包什么时候产生?
function fn(){
console.log(666);
setTimeout(()=>{
fn()
},1000)
}
fn();
$ ssh-keygen -t rsa -C "[email protected]"
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
在当前目录新建一个 Git 代码库
$ git init
新建一个目录,将其初始化为 Git 代码库
$ git init [project-name]
下载一个项目和它的整个代码历史
$ git clone [url]
添加指定文件到暂存区
$ git add [file1] [file2] ...
添加指定目录到暂存区,包括子目录
$ git add [dir]
添加当前目录的所有文件到暂存区
$ git add .
添加每个变化前,都会要求确认
对于同一个文件的多处变化,可以实现分次提交
$ git add -p
删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...
停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]
改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]
提交暂存区到仓库区
$ git commit -m [message]
提交工作区自上次 commit 之后的变化,直接到仓库区
$ git commit -a
提交时显示所有 diff 信息
$ git commit -v
使用一次新的 commit,替代上一次提交
如果代码没有任何新变化,则用来改写上一次 commit 的提交信息
$ git commit --amend -m [message]
重做上一次 commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...
显示有变更的文件
$ git status
显示当前分支的版本历史
$ git log
显示 commit 历史,以及每次 commit 发生变更的文件
$ git log --stat
搜索提交历史,根据关键词
$ git log -S [keyword]
显示某个 commit 之后的所有变动,每个 commit 占据一行
$ git log [tag] HEAD --pretty=format:%s
显示某个 commit 之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature
显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
显示指定文件相关的每一次 diff
$ git log -p [file]
显示过去 5 次提交
$ git log -5 --pretty --oneline
显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
显示指定文件是什么人在什么时间修改过
$ git blame [file]
显示暂存区和工作区的差异
$ git diff
显示暂存区和上一个 commit 的差异
$ git diff --cached [file]
显示工作区与当前分支最新 commit 之间的差异
$ git diff HEAD
显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]
显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"
显示某次提交的元数据和内容变化
$ git show [commit]
显示某次提交发生变化的文件
$ git show --name-only [commit]
显示某次提交时,某个文件的内容
$ git show [commit]:[filename]
显示当前分支的最近几次提交
$ git reflog
列出所有本地分支
$ git branch
列出所有远程分支
$ git branch -r
列出所有本地分支和远程分支
$ git branch -a
新建一个分支,但依然停留在当前分支
$ git branch [branch-name]
新建一个分支,并切换到该分支
$ git checkout -b [branch]
新建一个分支,指向指定 commit
$ git branch [branch] [commit]
新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]
切换到指定分支,并更新工作区
$ git checkout [branch-name]
切换到上一个分支
$ git checkout -
建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]
合并指定分支到当前分支
$ git merge [branch]
选择一个 commit,合并进当前分支
$ git cherry-pick [commit]
删除分支
$ git branch -d [branch-name]
删除远程分支
$ git push origin --delete [branch-name]
列出所有 tag
$ git tag
新建一个 tag 在当前 commit
$ git tag [tag]
新建一个 tag 在指定 commit
$ git tag [tag] [commit]
删除本地 tag
$ git tag -d [tag]
删除远程 tag
$ git push origin :refs/tags/[tagName]
查看 tag 信息
$ git show [tag]
提交指定 tag
$ git push [remote] [tag]
提交所有 tag
$ git push [remote] --tags
新建一个分支,指向某个 tag
$ git checkout -b [branch] [tag]
下载远程仓库的所有变动
$ git fetch [remote]
显示所有远程仓库
$ git remote -v
显示某个远程仓库的信息
$ git remote show [remote]
增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]
取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]
允许不相关历史提交,并强制合并
$ git pull origin master --allow-unrelated-histories
上传本地指定分支到远程仓库
$ git push [remote] [branch]
强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
推送所有分支到远程仓库
$ git push [remote] --all
恢复暂存区的指定文件到工作区
$ git checkout [file]
恢复某个 commit 的指定文件到暂存区和工作区
$ git checkout [commit] [file]
恢复暂存区的所有文件到工作区
$ git checkout .
重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变
$ git reset [file]
重置暂存区与工作区,与上一次 commit 保持一致
$ git reset --hard
重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变
$ git reset [commit]
重置当前分支的 HEAD 为指定 commit,同时重置暂存区和工作区,与指定 commit 一致
$ git reset --hard [commit]
重置当前 HEAD 为指定 commit,但保持暂存区和工作区不变
$ git reset --keep [commit]
新建一个 commit,用来撤销指定 commit
后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]
暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop
1、配置语法:
以斜杠“/”开头表示目录;
以星号“*”通配多个字符;
以问号“?”通配单个字符
以方括号“[]”包含单个字符的匹配列表;
以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;
此外,git 对于 .ignore 配置文件是按行从上到下进行规则匹配的,意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效;
2、示例:
(1)规则:fd1/*
说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
(2)规则:/fd1/*
说明:忽略根目录下的 /fd1/ 目录的全部内容;
(3)规则:
/*
!.gitignore
!/fw/bin/
!/fw/sf/
说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;
<script>
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
var person = new Person("小明",12,0);
console.log(person);
特殊:只能用于引用数据类型,值类型不适用;
p1.hasOwnproperty(k)
//封装一个函数判断元素是否在公有属性上与hasOwnProperty作用相同
function P1(name, age) {
this.name = name;
this.age = age;
}
let p1 = new P1("one", 24);
P1.prototype.tos = "12";
Object.prototype.hasPubProperty = function (key) {
return (key in this) && !this.hasOwnProperty(key);
}
new 返回值:不是引用的话就是默认返回 this
f.call(xxx,a,b,c)//a,b,c是传给f的实参
,call 中的第一个参数是用来修改函数中的 this 指向,call 从第二个参数开始就是传给函数的实参 function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function myName(C, ...ages) {
//new的特性是开辟一个新堆空间
let obj = {};
//让实例指向他的构造函数
obj.__proto__ = C.prototype;
//改变this指向指向他开辟的空间obj
let a = C.call(obj, ...ages);
//判断构造函数执行结构,如果是引用类型就返回它执行结构,如果是值类型就返回this
return typeof a == "object" ? a : obj;
}
let p1 = new Person("小康", 12, 1);
let p2 = myName(Person, "小康", 12, 1)
var ary = [];
function myInstance(a, b) {
//判断a.prototype是否存在并且a.__proto__ !== b.prototype
while (a.__proto__&&a.__proto__ !== b.prototype) {
a = a.__proto__;
if (a.__proto__ === null) {
return console.log("没有")
}
}
return true;
}
console.log(myInstance(ary, Array));
console.log(myInstance(ary, Object));
[...arguments]
[].slice.call(div1)
先通过数组找到 slice 方法,通过 call 让这个 slice 执行,并且把其中的 this 变成类数组try{要执行可能会报错的代码}catch(形参){catch小括号中的形参对应的是上面运行错误信息;上面运行出错,就会走到这个catch,但是不会影响主体代码执行}
执行 try 中的代码如果报错就执行 catch 大括号中的代码let res1 = fn.bind(obj,1,2,3,4,5)
;var obj = Object.create(Array);//obj的__proto__指向Array
class 创造原型使用 eat(){},class 中没法添加值类型
class Person {
//创造一个名为Person的类
constructor(name, age, sex) {
//constructor是class规定的属性
console.log(arguments);
//设置私有属性
this.name = name;
this.age = age;
this.sex = sex;
}
//私有属性height
height = 1;
//建立名为eat的原型,形参food
eat(food){
console.log(`${food}`)
}
//static声明的是静态属性,指的是Person自己的属性
static qqq = 888;
static ttt = 999;
static yyy = 666;
}
let p1 = new Person("小孔", 12, 0);
console.log(Person.qqq);//输出Person内置的静态属性qqq,它的实例是不能使用静态属性
//将obj私有属性都拼接起来
Object.prototype.qq = 123;
var obj = {
name: "大哥",
age: 13
}
function obje(one) {
var h1 = document.getElementById("h1");
var a = Object.keys(one);
var str = "";
a.forEach(itm => {
str += `${itm}是${one[itm]};`;
});
h1.innerText = str;
}
obje(obj)
对页面插入并且排序
var list = [{
name: "小红",
age: 10
},
{
name: "小红2",
age: 120
},
{
name: "小红3",
age: 140
},
{
name: "小红4",
age: 105
},
{
name: "小红5",
age: 106
}
];
var ul = document.getElementsByTagName("ul")[0];
var but = document.getElementsByTagName("button");
class Proson {
constructor(ul, but) {
this.ul = ul;
this.but = but;
}
butt(array) {
this.one(array);
this.but[0].onclick = () => {
this.one(this.srop(array));
}
this.but[1].onclick = () => {
this.one(this.srop1(array));
}
}
one(array) {
var str = "";
array.forEach(ele => {
str += `- 姓名是
${ele.name};年龄是${ele.age};
js 中的数据类型
原始值类型(基本数据类型&值类型 0)
对象类型(引用数据类型)
非标准特殊对象 例如:new Number(1) -> 原始值类型对应的"对象类型"实例
函数对象 function
创造一个数字
num2 是 Number 类的一个实例,可以直接调用 Number.prototype 上的方法,从严格意义上讲,num1 不是 Number 类的实例(因为实例都是对象类型的),按理 num1 应该是无法调用 Number.prototype 上方法的,但是实际操作中,是可以调用的,所以也可以称 num1 是 Number 类的实例;
- num1 Number(null)默认会把原始值转换为对象,然后再去调用 toFixed 方法,我们把这种操作(“把原始值准换问实例对象”)称之为“装箱”!!
- num2+10 ->20 游览器会默认把实例对象转换为对应的原始值,然后再进行数学运算,这个过程称之为“拆箱”
parseInt/parseFloat 都是用来把其他值转换为数字:从字符串(传递的不是字符串,也要先转换为字符串)左侧第一个字符串开始查找,把找到的有效数字字符转换为数字,遇到一个非有效的,则停止朝招!一个都找不到,结构就是 NaN!
i++ / i-- / ++i / +i 一定是数学运算;i = i + 1; 可能是字符串拼接
+val 就是将 val 转化为数字
函数的创建
函数执行:
让“=”左侧出现和右侧值相类似的结构,然后快速取出某一部分的值,赋值给对应的变量
let arr = [1,2,3,4];
let [a,b] = arr;
console.log(a,b);//取出第一项和第二项1,2
let [,a,b] = arr;
console.log(a,b);//取出第二项和第三项2,3
let [a,...b] = arr;
console.log(a,b);//取出第一项付给a,剩余全部付给b,a = 1, b =[2,3,4]
let arr1 = [10];
let [a,b = 0] = arr1;
console.log(a,b); //给b赋默认值
谷歌浏览器:blink(webkit分支)
火狐:Gecko
.....
==============
真实项目开发,我们使用ES6语法,如果需要兼容 IE(>=IE10),我们需要基于 babel 模块,把ES6的语法转换为ES5....
https://babeljs.io/
arr.forEach((item,index)={})
for(let i = 0 ; i < arr.length;i++){}
var reg = /1/ //字面量 /元字符/ 定义一个规则:字符串中得有1
var reg2 = new RegExp('1') //构造函数
reg.test('aadfawaewaewfe')
字符串中的转义,就是把字符串中有特殊含义的字符转成字符串本身(不代表任何含义)
特殊的元字符:
var reg = /d/ //定义一个规则:字符串中得有d
var reg1 = /^1/
var reg2 = /1$/
var reg11 = /21$/
规则是:字符串必须是 1 结尾而且还是得"这个"1 前面必须是 2在[]中的.代表.本身
/^(11|12)$/ //要不11要不12
正则的捕获:exec
str.replace(reg, function (a, b, c) {
//这个回调函数什么时候执行每当字符串中有匹配正则的时候,这个回调就会执行一次
//字符创中有多少匹配正则的部分这个回调函数就会执行多少次
//这个回调函数的参数第一项指的是大正则捕获的内容,后边都是小分组捕获的内容
obj[b] = c;
})
 4. js
js:
offset类
offsetTop offsetLeft offsetWidth offsetHeight offsetParent
--offsetWidth:width+左右padding+左右border
client类
clientTop clientLeft clientWidth clientHeight
--clientWidth:width+左右padding
scroll类
scrollTop scrollLeft scrollWidth scrollHeight
--scrollWidth:若内容不溢出等同于clientWidth
一旦溢出了 左padding+内容的实际宽度
console.log(box.style.xxx
获取写在元素"行内"上的样式[特点:样式只有写在行内上才能获取]body.offsetParent === null
/*
IntersectionObserver:ES6新增的一个内置类
+ 不兼容IE浏览器
+ new IntersectionObserver(callback) 创建它的一个实例:创建一个监听器,用来监听一个或者多个DOM元素和浏览器可视窗口的交叉状态和信息
+ 当交叉状态「出现在可视窗口中、离开可视窗口」发生改变,都会触发监听器的回调函数callback执行
+ 在回调函数中可以获取所有监听的DOM和可视窗口的交叉信息
*/
let box1 = document.querySelector('#box1'),
box2 = document.querySelector('#box2');
// 创建监听器
let ob = new IntersectionObserver((changes) => {
/*
回调函数执行:
+ 创建监听器、且监听了DOM元素会立即执行一次(连续监听多个DOM只触发一次,但是如果监听是分隔开的,每新监听一个元素都会触发执行一次)
+ 当监听的元素和可视窗口交叉状态改变,也会触发执行「默认是“一露头”或者“完全出去”,会触发;当然可以基于第二个Options配置项中的threshold来指定规则;」
+ threshold: [0] 一露头&完全出去
+ ...
+ threshold: [1] 完全出现&出去一点
----
changes:是一个数组,记录了每一个监听元素和可视窗口的交叉信息
+ boundingClientRect:记录当前监听元素的getBoundingClientRect获取的值
+ isIntersecting:true/false true代表出现在可视窗口中,false则反之
+ target:存储当前监听的这个DOM元素对象
+ ...
*/
console.log(changes);
}, { threshold: [1] });
// 监听某个DOM元素和可视窗口的交叉状态改变;unobserve移除监听;
ob.observe(box1);
ob.observe(box2);
游览器底层渲染机制:当我们从服务器获取代码后,浏览器是如何把代码渲染为页面及相关效果的
CRP(关键渲染路径)性能优化法则:了解浏览器底层处理的具体步骤,针对每一个步骤进行优化
JS 种的同步和异步编程
进程和线程:一个进程中可能包含多个线程
游览器是多线程,当基于游览器打开一个页面(开辟一个进程),会有不同的线程同时去做多件事情
游览器底层渲染机制