前情提要: 这篇是偏向应用类的题目,关于涉及到的知识点,配合个人上一篇JavaScript知识点整理实用更佳喔~javascript
中间元素 position:absolute;left:300px;right:300phtml
容器 display:flex; 中间元素 flex:1;java
容器 display:table; 中间元素 display: table-cell;node
容器 display:grid;grid-template-rows:300px;// 行高 中间元素 grid-template-columns:300px auto 300px;android
五种方案的优缺点git
div{
display: flex;
justify-content: center; // 水平居中
align-items: center; // 垂直居中
}
复制代码
div{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
复制代码
div{
position: absolute;
top: 50%;
left: 50%;
margin-left: -0.5*宽度;
margin-top: -0.5*高度;
}
复制代码
div{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
复制代码
若是使用margin-left/margin-top须要固定元素宽/高,而transform不须要,100%就是元素自身的宽高。github
display: flex;
// 主轴方向
flex-direction: row|row-reverse|column|column-reverse;
// 换行:wrap 不换行:nowrap
flex-wrap:nowrap|wrap|wrap-reverse;
// 主轴对齐方式
justify-content:flex-start|flex-end|center|space-between|space-around;
// 副轴对齐方式
align-items:flex-start|flex-end|center|baseline|stretch;
// 多根轴线对齐方式
align-content:flex-start|flex-end|center|space-between|space-around|stretch;
复制代码
// display: grid;
// grid-template-rows // 定义行轨道
// grid-template-columns // 定义列轨道
// grid-column-gap和grid-row-gap定义网格间隙
// 实现上下网格高度为50px,100px,中间自适应
grid{
display:grid;
grid-template-columns:50px auto 100px;
}
//实现第一列,第二列,第三列宽度为90px,50px,150px
grid{
display:grid;
grid-template-rows:90px 50px 150px;
}
// 实现项目1占1/4,项目2占1/4宽度,项目3占1/2宽度
grid{
display: grid;
grid-template-rows: 1fr 1fr 2fr;
}
复制代码
每一个HTML元素均可以叫盒模型,盒模型包括margin,border,padding,content。web
box-sizing:content-box;
box-sizing:border-box
获取盒模型宽高dom.style.width/height
dom.currentStyle.width/height
window.getComputedStyle(dom).width/height
dom.getBoundingClientRect().width/height
dom.offsetWidth/offsetHeight
BFC块级格式化上下文,是一种边距解决方案算法
两个box都设置了边距,垂直方向上两个box的边距会重叠,以绝对值大的为最终结果显示chrome
BFC元素不会与float的元素重叠,BFC上下的边距不会重叠,BFC是一个独立的容器和外面的容器互不干扰,计算BFC高度的时候浮动子元素也会参与运算
考察点:animation
<style>
.ani{
width:100px;
heigth:100px;
background-size:cover;
background-position:center;
animation: loop 20s infinite;
-webkit-animation: loop 20s infinite;
}
@keyframes "loop"{
0%{background-image: url('1.jpg')}
25%{background-image: url('2.jpg')}
50%{background-image: url('3.jpg')}
75%{background-image: url('4.jpg')}
100%{background-image: url('5.jpg')}
}
@-webkit-keyframes "loop"{
0%{background-image: url('1.jpg')}
25%{background-image: url('2.jpg')}
50%{background-image: url('3.jpg')}
75%{background-image: url('4.jpg')}
100%{background-image: url('5.jpg')}
}
</style>
<div class="ani"></div>
复制代码
<style>
#table tr:nth-child(odd){
background: red;
}
#table tr:nth-child(even){
background: yellow;
}
#table tr:hover{
background: orange
}
</style>
<table id="table">
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr><td>4</td></tr>
<tr><td>5</td></tr>
</table>
复制代码
.scale-1px{
position:relative;
border:none;
}
// 下边框
.scale-1px:after{
content:'';
position:absolute;
left:0;
bottom:0;
background:#000;
width:100%;
height:1px;
-webkit-tranform:scaleY(0.5);
transform:scaleY(0.5);
-webkit-transform-origin:0 0;
transform-origin:0 0;
}
复制代码
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<input type="checkbox" />
<script type="text/javascript">
var arr=[]''
var inputs = document.getElementsByName('input');
for(var i=0; i<inputs.length;i++){
if(inputs[i].type="checkbox"){
arr.push(inputs[i])
}
}
</script>
复制代码
使用document.querySelectorAll('#id')
var inp = document.getElementById('id');
console.log(inp.value)
复制代码
var ele=document.getElementById('id');
ele.innerHTML="xxxx"
ele.style.color="#000"
复制代码
<div class="root">
<div class="container">
<section class="sidebar">
<ul class="menu"></ul>
</section>
<section class="main">
<article id="post"></article>
<p class="copyright"></p>
</section>
</div>
</div>
<script type="text/javascript">
var node = document.getElementsByClassName('root')[0];
var arr=[showNode(node)];
function mapNode(node){
var nodeList=node.children;
// console.log(node,nodeList)
for(var i=0;i<nodeList.length;i++){
var childNode=nodeList[i];
console.log(childNode)
arr.push(showNode(childNode))
if(childNode.children.length>0){
mapNode(childNode)
}
}
return arr;
}
function showNode(node){
if(node.className){
return node.nodeName+" ."+node.className
}else{
return node.nodeName+" #"+node.id;
}
}
</script>
复制代码
<select name="changeImg" id="select">
<option value="1.jpg">1</option>
<option value="2.jpg">2</option>
<option value="3.jpg">3</option>
</select>
<script>
var select=document.getElementById('select')
var img=document.getElementById('img')
img.src=select.value;
select.onchange=function(){
img.src=select.value;
}
</script>
复制代码
考察点:window方法
<button onclick="closeWin()">关闭</button>
<script>
function closeWin(){
if(confirm('是否退出当前页面?'){
window.close()
}
}
</script>
复制代码
考察点:事件类型 鼠标的移入移出: mouseover和mouseout(会冒泡);mouseenter和mouseleave(不冒泡)
考察:对事件的了解
var EventUtil={
addEvent:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler)
}else if(element.attachEvent){
element.attachEvent('on'+type,handler)
}else{
element['on'+type]=handler
}
},
removeEvent:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler)
}else if(element.detachEvent){
element.detachEvent('on'+type,handler)
}else{
element['on'+type]=null
}
},
getEvent:function(event){
return event||window.event
},
getTarget:function(event){
return event.target||event.srcElement
},
preventDefault:function(event){
if(event.preventDefault){
event.preventDefault()
}else{
event.returnValue=false
}
},
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation()
}else{
event.cancelBubble=true
}
}
}
复制代码
观察者模式简单说就是当一个对象被修改时,会自动通知它的依赖对象,发布-订阅模式。
var Event={
// 经过on接口监听事件eventName
// on至关于订阅
on: function(eventName, handler){
if(!this.handler){
this.handler={}
}
if(!this.handler[eventName]){
this.handler[eventName]=[]
}
this.handler[eventName].push(handler)
},
// 触发事件eventName
// emit至关于发布
emit: function(eventName){
// 若存在eventName,则调用全部事件处理函数
if(this.handler[eventName]){
for(var i=0;i<this.handler[eventName].length;i++){
this.handler[eventName][i](arguments[1])
}
}
}
}
Event.on('test', function(a){
console.log(a)
})
Event.emit('test',78) //78
Event.on("test", function(a){
console.log("个人数字是"+a)
});
Event.emit("test", 88);
// 88
//个人数字是88
复制代码
<div id="tip">提示</div>
<div id="know">我知道了</div>
<script type="text/javascript">
var tip=document.getElementById('tip');
var storage=window.localStorage;
// 存储的日期
var date=storage.getItem('date');
// 用户是否点击过我知道了
var ifKnow=storage.getItem('know');
// 今天日期
var today=new Date();
today=today.getFullYear()+'-'+today.getMonth()+'-'+today.getDate();
// 点击我知道了再也不显示
var know=document.getElementById('know');
know.onclick=function(){
storage.setItem('know', true)
tip.style.display="none";
}
// 若是点击过我知道了,则不显示
if(ifKnow){
tip.style.display="none";
}else{
if(date!=null){
if(date==today){
// 今日已登陆过,不显示
tip.style.display="none"
}else{
// 今日还没有登陆过
storage.setItem('date',today)
}
}else{
// 第一次访问网站,尚未存储日期
storage.setItem('date', today)
}
}
</script>
复制代码
var a;
alert(typeof a);
alert(b);
b=10;
alert(typeof b);
复制代码
a使用了var声明变量未赋值因此为undefined,b因为未声明将报错。 若b=10改成var b=0;则返回undefined由于var会提高声明。
var foo=1;
function test(){
console.log(foo);
var foo=2;
console.log(foo);
}
test();
复制代码
缘由:函数内部var声明会提高到函数内部顶部,因此就至关于
var foo=1;
function test(){
var foo;
console.log(foo);
foo=2;
console.log(foo)
}
复制代码
if(!("a" in window)){
var a=1
}
console.log(a)
复制代码
由于var存在声明提高,因此"a" in window为true,就不执行if语句中的赋值了,因而为undefined
var foo=1;
function bar(){
if(!foo){
var foo=10
}
console.log(foo)
}
bar(); // 10
复制代码
var存在声明提高,因此if(!foo)中的foo为undefined,会被执行,结果为10
var a=10,b=11,c=12;
function test(a){
a=1;
var b=2;
c=3;
}
test(14);
console.log(a); // 10
console.log(b); // 11
console.log(c); // 3
复制代码
我的认为,test(a)传入的参数a,会被解析成var a=14,因此a也是局部变量
function fn(){
f=ff()
return f;
function ff(){
return 'f' in window;
}
var f;
}
console.log(fn());
复制代码
函数会被整个提高到最上方,因此ff()中会执行,但因为函数做用域,window下没有f属性,返回false;
console.log(a);
var a=13;
function fn(){
console.log(a);
var a=1;
}
fn();
console.log(a);
复制代码
输出undefined,undefined,13。缘由:js引擎会先把var声明提到顶部,而后再把函数声明整个函数提到var的前面,以上代码等于
function fn(){
var a;
console.log(a);
a=1;
}
var a;
console.log(a);
a=13;
fn();
console.log(a)
复制代码
console.log(a);
var a=13;
function fn(){
console.log(a);
a=1;
}
fn()
console.log(a)
复制代码
输出undefined,13,1。由于fn中的a=1没有var,因此不存在变量提高,因此fn()中console.log(a)
能够访问到外部的,等fn()
以后,a=1
没有var,不是全局变量改变了原先a的值,因此最后一个输出1
console.log(a);
a=13;
function fn(){
console.log(a);
a=1;
}
fn()
console.log(a)
复制代码
报错,13,1
var a=new Object();
a.value=1;
b=a;
b.value=2
console.log(a.value)
复制代码
对象参数是按引用传递的
var a=[1];
var b=a;
b=[2];
console.log(a);
复制代码
b=[2]指向了其余的地址,不是原引用了
function changeObj(o){
o.name="first";
o = new Object();
o.name="second";
}
var obj=new Object();
changeObj(obj);
console.log(obj.name);
复制代码
o=new Object()切断了原先的引用,此时obj.name还是指向原来的,新的就只是一个另外的对象
var a=b=c=[1,2,3,4];
b=9;
a[1]=0;
console.log(b[0])
a=[1,2,3,4]
c=[1,2,3,4]
a[0]=b;
console.log(c);
console.log(a);
复制代码
b=9
时已经被切断引用了,a,c也是被切断了,a[0]=b=9,因此a=[9,2,3,4]
function clone(obj){
var o;
switch (typeof obj){
case "undefined":
break;
case "string":
o=obj+"";
break;
case "number":
o=obj-0;
break;
case "boolean":
o=obj;
break;
case "object":
if(obj===null){
o=null
}else{
if(Object.prototype.toString.call(obj)==="[object Array]"){
o=[];
for(var i=0;i<obj.length;i++){
o.push(clone(obj[i]))
}
}else{
o={};
for(var k in obj){
o[k]=clone(obj[k])
}
}
}
break;
default:
o=obj;
break;
}
return o;
}
复制代码
function show(){
var b=1;
a=++b;
}
show();
alert(a);
复制代码
a为2,++b就是b=b+1而后返回b,b++就是先返回b,而后b=b+1
var str='get-element-by-id';
function formatString(str){
var arr=str.split('-');
var newStr=arr[0]
for(var i=1;i<arr.length;i++){
var first=arr[i].slice(0,1).toUpperCase();
var other=arr[i].slice(1)
newStr=newStr+first+other
}
return newStr
}
formatString(str)
复制代码
function myTrim(str){
if(String.prototype.trim){
return str.trim()
}else{
return str.replace(/^\s+/, "").replace(/\s+$/,"")
}
}
console.log(myTrim(" hello "))
复制代码
function test(str){
var obj={};
// 先将出现过的字符和次数记录下来
for(var i=0; i<str.length;i++){
var key = str[i]
if(!obj[key]){
obj[key]=1
}else{
obj[key]++;
}
}
var max=0;
var idx=0;
// idx为字符,max为出现次数
for(var i in obj){
if(obj[i]>max){
max=obj[i]
idx=i;
}
}
console.log(idx,max)
}
var str="abcdefgaddda";
test(str);
复制代码
function test(str){
var newStr="";
for(var i=0;i<str.length;i++){
if(str.indexOf(str[i])!==i){
newStr=newStr+""
}else{
newStr=newStr+str[i]
}
}
return newStr;
}
复制代码
假设中文字符占两个字节,英文字符占一个字节
function getByteLen(str){
var reg=/[\u4e00-\u9fa5]/;
var len=0;
for(var i=0;i<str.length;i++){
if(reg.test(str.charAt(i))){
len+=2
}else{
len++
}
}
return len;
}
复制代码
var url='http://test.com?a=1&b=2&cd=344'
function formatUrl(url){
var urlArr=url.split('?');
url=urlArr[1];
var arr=url.split('&')
var obj={}
for(var i=0;i<arr.length;i++){
var res=arr[i].split('=');
var key=res[0];
var val=res[1];
obj[key]=val;
}
return obj;
}
formatUrl(url)
复制代码
function formatNum(num){
var newStr="";
var count=0;
var str=num.toString();
for(var i=str.indexOf('.')-1;i>=0;i--){
if(count%3==0 && count!=0){
newStr=str.charAt(i)+','+newStr;
}else{
newStr=str.charAt(i)+newStr;
}
count++;
}
str=newStr+str.substr((str).indexOf('.'));
return str;
}
formatNum(123456566.222)
复制代码
function phone(str){
var reg=/^1[3|4|5|7|8|9]\d{9}$/;
if(reg.test(str)){
console.log('yes')
}else{
console.log('no')
}
}
function email(str){
var reg=/^[0-9a-zA-Z_\.\-]+\@+[0-9a-zA-Z_\.\-]+\.(com|com.cn|edn|hk|cn|net)$/;
if(reg.test(str)){
console.log('yes')
}else{
console.log('no')
}
}
复制代码
function replace(str){
var newStr=str.replace(/<\/?\w+>/gi, "")
console.log(newStr)
}
复制代码
function test(str){
return str.replace(/[<>"&]/g, function(match){ switch(match){ case "<": return '<' case ">": return ">" case "&": return "&" case "\"":
return """;
}
})
}
复制代码
"<tr><td>{$id}</td><td>{$name}</td></tr>"
中的{$id}
替换成10,${name}
替换成chenfunction test(str){
return str.replace(/{\$id}/g,'10').replace(/{\$name}/g, "chen")
}
复制代码
function testStr(str){
var reg=/^[a-zA-Z_]+[0-9a-zA-Z_]{5,20}/;
if(reg.test(str)){
console.log('yes')
}else{
console.log('no')
}
}
复制代码
<div id="content">
我真的要丢脸死了,我今天在课堂上放屁了并且很大声,这是我18年来最丢脸的一次。
</div>
<script type="text/javascript">
function testStr(id){
var node=document.getElementById(id);
var content=node.innerHTML;
var reg=/死了|18|放屁/g;
var res=content.replace(reg, function(match){
return "<span style='color:red'>"+match+"</span>"
})
node.innerHTML=res;
}
testStr('content')
</script>
复制代码
// 获取随机两位整数
var random=Math.random();
random=Math.floor(random*100);
// 获取随机三位小数
var random=Math.random()+'00000';
random=random.slice(0,5);
复制代码
// 方法1
function randomArr(arr){
for(var i=0;i<arr.length;i++){
var random=Math.floor(Math.random()*arr.length);
var val=arr[random];
arr[random]=arr[i];
arr[i]=val;
}
return arr;
}
// 方法2
arr.sort(function(){
return Math.random-0.5;
})
复制代码
function randomArr(){
var arr=[]
for(var i=0;i<5;i++){
var random=Math.floor(Math.random()*(100-10)+10);
arr.push(random)
}
return arr.sort();
}
复制代码
// 方法1
arr.reverse()
// 方法2
function test(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
newArr.unshift(arr[i])
}
}
复制代码
// 方法1
function test(arr){
arr.sort(function(x,y){
return y-x;
})
}
// 方法2
var arr=[1,2,34,40,56]
function test(arr){
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-1-i;j++){
if(arr[j]<arr[j+1]){
var val=arr[j]
arr[j]=arr[j+1];
arr[j+1]=val
}
}
}
return arr;
}
复制代码
// 方法1 利用indexOf
function test(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
if(arr.indexOf(arr[i])===i){
newArr.push(arr[i])
}
}
console.log(newArr)
}
// 方法2 利用indexOf
function test1(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
if(newArr.indexOf(arr[i])===-1){
newArr.push(arr[i])
}
}
console.log(newArr)
}
// 方法3 利用splice和indexOf
function test(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
if(arr.indexOf(arr[i])!==i){
arr.splice(i,1);
i--;
}
}
console.log(arr)
}
// 方法4 利用ES6的set
function test1(arr){
return Array.from(new Set(arr))
}
复制代码
// 方法1
var arr=[5,1,18,4,1,3,4,3];
function test(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]===arr[j] && newArr.indexOf(arr[i])==-1){
newArr.push(arr[i])
}
}
}
console.log(newArr)
}
复制代码
// 方法1
[...new Array(100).keys()]
// 方法2
Array.from(new Array(100),(item,idx)=>idx)
复制代码
function test(arr){
return arr.map(function(item,index,array){
return item*2;
})
}
function test1(arr){
var newArr=[];
arr.forEach(function(item,index,array){
newArr.push(item*2)
})
return newArr;
}
function test2(arr){
for(var i=0;i<arr.length;i++){
arr[i]=arr[i]*2;
}
return arr;
}
复制代码
var arr=new Array(1,3,5);
arr[4] = 'z';
arr2=arr.reverse();
arr3=arr.concat(arr2);
console.log(arr3)
复制代码
["z", undefined, 5, 3, 1, "z", undefined, 5, 3, 1] 由于reverse()会改变原数组
function forEach(obj,fn){
// 判断是否为数组
if(obj instanceof Array){
obj.forEach(function(item,index){
fn(index,item)
})
}else{
for(var key in obj){
fn(key, obj[key])
}
}
}
复制代码
function test(str){
var reg=str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/);
if(!reg){
console.log('日期格式错误');
return;
}
var d=str.split('-');
var year=parseInt(d[0]);
var month=parseInt(d[1]);
var date=parseInt(d[2]);
if(year<=0){
console.log('日期错误')
return;
}
if(month>12||month<=0){
console.log('日期错误')
return;
}
if((year%4===0&&year%100!==0)||year%400===0||year%500==0){
// 为闰年
if(month==2&&(date>29||date<=0)){
console.log('日期错误')
return;
}
}else{
if(month==2&&(date>28||date<=0)){
console.log('日期错误')
return;
}
}
if(month==4||month==6||month==9||month==11){
if(date>30||date<=0){
console.log('日期错误')
return;
}
}else{
if(date>31||date<=0){
console.log('日期错误')
return;
}
}
return str;
}
复制代码
// 第二步执行
var test=(function(a){
// a=1,可是b尚未定义由于函数做用域
this.a=a;
return function(b){
// 第三步执行,接收test(4)的参数,因此b=4,this.=1
return this.a+b;
}
}
// 第一步执行
(function(a,b){
// a=1,b=2
return a;
}(1,2))
)
console.log(test(4))
复制代码
返回5
function foo(){
foo.a=function(){
console.log(1);
}
this.a=function(){
console.log(2)
}
a=function(){
console.log(3)
}
var a=function(){
console.log(4)
}
}
foo.prototype.a=function(){console.log(5)}
foo.a=function(){console.log(6)}
// 此时foo还没真正执行,因此只有上面这个属性a,因此返回6
foo.a(); // 执行了foo()
var obj=new foo();
// new方法调用以后this就是指向obj的,因此obj.a就至关于this.a
obj.a()
// 上面执行了foo()以后,foo.a改变了,因此输出1
foo.a()
复制代码
6,2,1
var a=5
function test(){
a=0;
console.log(a)
console.log(this.a);
var a;
console.log(a);
}
test();
new test();
复制代码
第一个test()是直接调用的因此this指向window,第二个new test()中this会被绑定一个空对象上,因此this.a为undefined
var myObj={
foo: 'bar',
func: function(){
var self=this;
console.log(this.foo)
console.log(self.foo)
(function(){
console.log(this.foo)
console.log(self.foo)
}())
}
}
myObj.func()
复制代码
bar,bar,undefined,bar
myObj.func()因此this绑定在myObj上,而后在func()里的函数this就会指向func,因此返回undefined。
关于this绑定不太清楚的,能够看木易杨说的JavaScript深刻之史上最全--5种this绑定全面解析
var log=console.log.bind(console)
复制代码
能够用...或arguments获取参数
function sum(...arr){
var sum=0;
arr.forEach(function(item){
sum=sum+item;
})
return sum;
}
复制代码
只列举一种,方法有不少。
var foo="hello"
(function(){
var bar="world"
console.log(foo+bar)
})()
console.log(foo+bar)
复制代码
"helloworld", 报错,缘由:函数做用域
var z=10;
function foo(){
console.log(z);
}
(function(funArg){
var z=20;
funArg()
})(foo);
复制代码
函数自动执行,函数参数是值传递,funArg引用外部foo函数,而foo函数做用域没有z变量,因此找到全局变量z,输出结果10
(function(){
var a=b=3
})();
console.log("a defined?"+(typeof a !== 'undefined'))
console.log("b defined?"+(typeof b !== 'undefined'))
复制代码
var a=b=3能够解析出var a=b,b=3;因此b是全局变量,因此typeof b为number,typeof对于不存在的变量a返回undefined
function fun(n, o){
console.log(o)
return{
fun: function(m){
return fun(m,n)
}
}
}
var a=fun(0); a.fun(1); a.fun(2); a.fun(3);
var b=fun(0).fun(1).fun(2).fun(3);
var c=fun(0).fun(1); c.fun(2); c.fun(3);
复制代码
这里是一个闭包的概念,保存变量的值 第一行
var a=fun(0); // 这里o是undefined,n=0,会保存在a中
a.fun(1); // m=1,n=0 => n=1,o=0
a.fun(2); // m=2,n=0 => n=2,o=0
a.fun(3); // m=3,n=0 => n=3,o=0
复制代码
从第二行开始,var b=fun(0).fun(1).fun(2).fun(3),能够转化为
var b=fun(0); // 在这里面o是undefined,n=0会保存在b中
var b1=b.fun(1); // o=undefined,m=1,n=0 => n=1,o=0保存到b1中
var b2=b1.fun(2); // o=0,m=2,n=1 => n=2,o=1 保存到b2中
var b3=b2.fun(3); // o=1,m=3,n=2 => n=3,o=2
复制代码
第三行,转化为
var c=fun(0); // 在这里面o是undefined,n=0会保存在c中
var c1=c.fun(1); // o=undefined,m=1,n=0 => n=1,o=0保存到c1中
c1.fun(2); // o=0,m=2,n=1 => n=2,o=1
c1.fun(3); // o=0,m=3,n=1 => n=3,o=1
复制代码
for(var i=0;i<5;i++){
setTimeout(function(){
console.log(i)
},100*i)
}
复制代码
会输出5个5
// 方法1
for(let i=0;i<5;i++){
setTimeout(function(){
console.log(i)
},100*i)
}
// 方法2
for(let i=0;i<5;i++){
(function(i){
setTimeout(function(){
console.log(i)
},100*i)
})(i)
}
复制代码
考察点:闭包
<style>
.hidden{
display: none;
}
</style>
<ul id="tabs">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div id="content">
<div>第一</div>
<div>第二</div>
<div>第三</div>
</div>
<script>
var tabs=document.getElementById('tabs');
var tabList=tabs.children;
var content=document.getElementById('content');
var conList=content.children;
// 方式1
for(var i=0;i<tabList.length;i++){
tabList[i].index=i;
tabList[i].onclick=function(){
for(var j=0;j<conList.length;j++){
conList[j].style.display="none"
}
conList[this.index].style.display="block"
}
}
// 方式2 用闭包
for(var i=0;i<tabList.length;i++){
tabList[i].onclick=function(i){
return function(){
for(var j=0;j<conList.length;j++){
conList[j].style.display="none"
}
conList[i].style.display="block"
}
}(i)
}
</script>
复制代码
// 1
for(let i=0;i<10;i++){
var a=document.createElement('a');
a.innerHTML=i+"<br>";
a.onclick=function(){
console.log(i)
}
document.body.appendChild(a)
}
// 2
for(var i=0;i<10;i++){
(function(i){
var a=document.createElement('a');
a.innerHTML=i+"<br>";
a.onclick=function(){
console.log(i)
}
document.body.appendChild(a)
})(i)
}
复制代码
(function(){
console.log(1);
setTimeout(function(){
console.log(2)
},1000)
setTimeout(function(){
console.log(3)
},0);
console.log(4)
})()
复制代码
1,4,3,2 缘由:会先将同步代码执行完毕,再执行异步代码
var a=6
setTimeout(function(){
console.log(a);
a=666
}, 1000)
a=66;
复制代码
66 缘由:会先执行同步代码,再执行异步代码
//请写出输出内容
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end')
复制代码
async function a1(){
console.log('a1 start')
await a2() // 执行,执行完毕才会回来执行a1 end
cosnole.log('a1 end') // 会被注册为microtask
}
复制代码
const PENDING='pending'
const RESOLVED='resolved'
const REJECTED='rejected'
function myPromise(fn){
const that=this;
that.state=PENDING; // Promise当前状态
that.value=null; // Promise的值
that.resolvedCallbacks=[]
that.rejectedCallbacks=[]
function resolve(value){
if(value instancof myPromise){
return value.then(resolve, reject)
}
setTimeout(() => {
if(that.state===PENDING){
that.state===RESOLVED;
that.value===value
// 依次执行成功以后的函数栈
that.resolvedCallbacks.map(cb => cb(that.value))
}
},0)
}
function reject(error){
setTimeout(() => {
if(that.state===PENDING){
that.state===REJECTED
that.value=error;
// 依次执行失败以后的函数栈
that.rejectedCallbacks.map(cb => cb(that.error))
}
},0)
}
try{
fn(resolve, reject)
}catch(e){
reject(e)
}
}
myPromise.prototype.then = function(onFulfilled, onjected){
const that=this;
onFulfilled=typeof onFulfilled === 'function' ? onFulfilled: v => v;
onRejected=typeof onRejected === 'function' ? onRejected : r => {throw r}
if(that.state === PENDING){
that.resolvedCallbacks.push(onFulfilled)
that.rejectedCallback.push(onRejected)
}
if(that.state === RESOLVED){
onFulfilled(that.value)
}
if(that.state === REJECTED){
onRejected(that.value)
}
}
new myPromise((resolve,reject) => {
setTimeout(() => {
resolve(1)
}, 0)
}).then(value => {
console.log(value)
})
复制代码
监控图片是否加载完成,加载完再加载下一张
<img src="">
<img src="">
<img src="">
<img src="">
var imgList=document.getElementsByTagName('img');
var urlList=[
'http://pica.nipic.com/2007-07-15/200771515512480_2.jpg',
'http://www.zyzw.com/sjms/sjmst/sjmsdg021.jpg',
'http://pic11.nipic.com/20100803/4038389_093502059852_2.jpg',
'https://img03.sogoucdn.com/app/a/100520093/ac75323d6b6de243-6a8470ba18ff4002-5f37053dc99bdc42f6f306e09de5e133.jpg'
]
// 加载图片
function loadImg(i){
var obj=new Image();
obj.src=urlList[i];
obj.onload=function(){
imgList[i].src=urlList[i];
i=i+1;
if(i<imgList.length){
loadImg(i)
}
}
}
loadImg(0);
复制代码
// func是用户传入须要防抖的函数
// wait是等待时间
const debounce = (func, wait=50) => {
// 缓存一个定时器id
let timer=0
// 返回的参数就是每次用户实际调用的防抖函数
return function(...args){
// 清空上一次的定时器
if(timer) clearTimeout(timer)
timer=setTimeout(() => {
func.apply(this,args)
}, wait)
}
}
function sayHi(){
console.log('防抖成功')
}
var inp=document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi, 500));
复制代码
const throttle(fn, wait=500) => {
let canRun=true;
return function(...args){
if(!canRun) return;
canRun=false;
setTimeout(()=>{
fn.apply(this, args)
canRun=true
}, wait)
}
}
function resizeWindow(e){
console.log(e.target.innerWidth, e.target.innerHeight)
}
window.addEventListener('resize', throttle(resizeWindow))
复制代码
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; 编写一个程序将数组扁平化去并除其中重复部分数据,最终获得一个升序且不重复的数组
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
// 方法1
// 扁平化数组
function flat(arr){
var newArr=[];
arr.forEach(function(item){
if(Array.isArray(item)){
newArr=newArr.concat(flat(item))
}else{
newArr.push(item)
}
})
return newArr;
}
// 去重和排序
function formatArr(arr) {
var newArr=flat(arr);
newArr.sort(function(a,b){
return a-b;
});
for(var i=0;i<newArr.length;i++){
if(newArr.indexOf(newArr[i])!==i){
newArr.splice(i,1)
}
}
return newArr;
}
formatArr(arr);
// 方法2
function flat(arr){
arr=arr.toString().split(',') // 扁平化数组
arr=arr.sort(function(a,b){
return a-b;
})
arr=arr.map(Number) // 逐个将每一个元素转为数字类型
arr=Array.from(new Set(arr)) // 数组去重
return arr;
}
复制代码
相邻的两个数进行比较,若是前者大于后者就交换位置,这样一来,第一轮就能够选出一个最大的数放在最后面;那么通过n-1轮,就会完成全部数的排序。
function bubbleSort(arr){
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;
}
复制代码
function selectSort(arr){
for(var i=0; i<arr.length-1;i++){
var minIdx=i;
// 找到未排序序列中的最小值
for(var j=i+1;j<arr.length;j++){
if(arr[j]<arr[minIdx]){
minIdx=j;
}
}
// 将最小值放到已排序序列的后面
var temp=arr[i];
arr[i]=arr[minIdx];
arr[minIdx]=temp;
}
return arr;
}
复制代码
function insertSort(arr){
for(var i=1;i<arr.length;i++){
// 将要插入的数
let temp=arr[i];
// 有序数列
for(var j=i-1;j>=0;j--){
// 要插入的数与有序数列一一比较
if(temp<arr[j]){
arr[i]=arr[j]
arr[j]=temp;
}
}
}
return arr;
}
复制代码
function shellSort(arr){
var gap=Math.floor(arr.length/2);
while(gap>0){
for(var i=gap; i<arr.length;i++){
var temp=arr[i];
for(var j=i; j-gap>=0 && arr[j-gap]>temp; j=j-gap){
arr[j]=arr[j-gap];
}
arr[j]=temp;
}
gap=Math.floor(gap/2);
}
return arr;
}
复制代码
先递归分解数列再合并数列,将一个数组拆分红A,B两个小组,一直拆到每一个小组只有一个元素为止。 看小册
function quickSort(arr){
if(arr.length<=1){
return arr;
}
// 基准位置(理论上可任意选取)
var idx=arr.length-1;
// 基准值
var num=arr[idx];
var left=[];
var right=[];
for(var i=0;i<arr.length-1;i++){
if(arr[i]<=num){
left.push(arr[i])
}else{
right.push(arr[i])
}
}
// 会先将左边的排序好再开始对右边进行排序
return quickSort(left).concat([num],quickSort(right));
}
复制代码