前情提要: 這篇是偏向應用類的題目,關於涉及到的知識點,配合個人上一篇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));
}
複製代碼