super
關鍵字使得子類調用了父類中的構造函數,父類可使用子類傳進來的屬性進行各類運算,super
關鍵字 還能夠調用父類的方法class Father{ constructor(x,y){ this.x=x; this.y=y; } sum(){ console.log(this.x+this.y) } say(){ return "我是爸爸" } } class Son extends Father{ constructor(x,y){ //調用了父類中的構造函數 super(x,y) //子類獨有的屬性 this.x=x; this.y=y } say(){ console.log(super.say()) } //子類獨有方法 subtract(){ console.log(this.x-this.y) } } let son=new Son(5,3); son.subtract(); son.sum();
tips: 繼承中的屬性或者方法查找原則:就近原則
super
,必須放到this前面(必須先調用父類的構造方法,再使用子類構造方法)es6
中類沒有變量提高,必須先定義類,才能經過類實例化對象\this
使用this
指向的是 建立的實例對象var that //等於構造函數裏this 即ldh這個對象 class Star{ constructor(name,age){ that=this this.name=name this.age=age this.btn=document.querySelector('button'); this.btn.onclick=this.sing } } sing(){ /* 這個sing方法裏的this,指向的是btn 這個按鈕,由於這個按鈕調用了這個函數 */ console.log(this) console.log(this.name) //輸出undenfind console.log(that.name) //輸出ldh } dance(){ /* 這個dance裏面的this 指向的是實例對象 ldh 由於是ldh調用了這個函數 */ console.log(this) } let ldh= new Star(ldh,18) ldh.dance()
es5
不使用prototype
原型對象function Star(name,age){ this.name=name; this.age=age; this.sing=funtion(){ console.log(我會唱歌) } } var ldh=new Star('劉德華',18); var zxy=new Star('張學友',19); /* new多個,基本屬性不會,但sing方法會開闢多個不一樣的內存空間,存在內存浪費的現象 */。
es5
使用構造函數prototype
原型對象function Star(name,age){ this.name=name; this.age=age; Star.prototype.sing=funtion(){ console.log(我會唱歌) } } Star.prototype ={ /*若是咱們修改了原來的原型對象,給原型對象賦值的是一個對象,則必須手動的利用constructor指回原來的構造函數*/ constructor:Star } var ldh=new Star('劉德華',18); var zxy=new Star('張學友',19); ldh.sing() /* new多個,基本屬性不會,但sing方法會開闢多個不一樣的內存空間,存在內存浪費的現象 */。
原型對象html
prototype
爲原型對象構造函數
經過原型
分配的函數是全部對象所共享的。構造函數
都有一個prototype
屬性,指向另外一個對象,注意這個prototype
就是一個對象,這個對象
的全部屬性
和方法
,都會被構造函數
所擁有。prototype
對象上,這樣全部對象的實例就能夠共享這些方法__proto__和 prototype 的區別ios
__proto__
是new
出來的實例的的原型對象prototype
是構造函數的原型對象git
tips:
es5
的構造函數方法很好用,可是存在浪費內存的問題,能夠經過構造函數的原型對象來存放方法,使得方法在不一樣對象中共享,起到節約內存的做用。
js成員的查找機制es6
function Star(name,age){ this.name=name; this.age=age; } Star.prototype.sing=function(){ console.log("我會唱歌"); } Star.prototype.sex='女' //構造函數原型成員 ,優先級中等 Object.prototype.sex="男"//object對象的原型成員 ,優先級最低 var ldh =new Star('劉德華',18) ldh.sex="男" //實例對象的原型成員 優先級最高 console.log(ldh.sex) //打印這個實例向上找,能夠找到Object
tips: 每一個對象裏都有 __proto__這個屬性
console.log(Array.prototype) 能夠打印js的一些關於數組的api //在Array對象上添加自定義方法 Array.prototype.sum=function(){ var sum=0; for(var i=0;i<thsi.length;i++){ sum+=this[i]; } return sum; } var arr=[1,2,3]; console.log(arr.sum()) var arr =new Array(11,22,33) arr.sum(); //不可採用如下方法加入方法 Array.prototype= { sum: function(){ var sum=0; for(var i=0;i<thsi.length;i++){ sum+=this[i]; } return sum; } }
tips: 本身加的原型
方法會高亮,不可採用對象
的方式去添加原型方法,會覆蓋原先就存在的方法。
call
方法call
能夠調用函數。this
指向。this
的指向要被改變到這個參數的。function fn(x,y){ console.log('我想喝手磨咖啡'); console.log(this); console.log(x,y); } var o={ name:'andy' } fn.call() /* 此時這個函數的this,就指向了o這個對象,指向哪一個對象根據第一個參數決定*/ fn.call(o,1,2) 1. 父構造函數 function Father(name,age){ //this 指向父構造函數的對象實例 this.name=name; this.age=age; } 2. 子構造函數 //這個score用的son本身的屬性 function Son(name,age,score){ //this 指向子構造函數的對象實例, //用call來調用Father這個構造函數,並把指向改爲子類的構造函數的this,就實現了繼承 Father.call(this,name,age) this.score=score } var son=new Son('劉德華',18,200) console.log(son)
prototype
繼承方法原型對象(prototype)繼承方法,經過原型鏈向上找規則,
Father實例(找不到向上找)->Father的原型對象的方法
就能夠繼承方法了,且子son方法定義本身的方法時不會影響到父github
//Father 是es5的構造函數 son.prototype=new Father() son.prototype.constructor=son
類的本質其實仍是一個函數 咱們也能夠簡單的認爲類就是構造函數的另一種寫法面試
es5 經過構造函數+原型實現面向對象 編程有如下特色ajax
es6正則表達式
forEach 迭代遍歷數組,break和retrun不會終止編程
var arr= [1,2,3]; arr.forEach((value,index,array)=>{ console.log("每一個數組元素"+value) console.log("每一個數組元素的索引號"+index) console.log("數組自己"+array) })
filter 主要用於篩選數組json
var arr=[12.66,4,88] var newArr=arr.filter((value,index,array)=>{ return value>=2 //知足條件就把值放到新數組裏 })
tips:返回的是一個新數組,不會影響原來的數組
some
主要用於檢測數組中的元素是否知足指定條件,通俗點查找數組中是否有知足條件的元素
var arr=[12.66,4,88] var flag=arr.some((value,index,array)=>{ return value>=2 //知足條件就是true }) arr=[12.66,4,88] var flag=arr.some((value,index,array)=>{ if(value>30){ return true } })
tips:返回的是一個布爾值,若是查找到這個元素就返回true,再也不進行循環,效率更高。
trim 去除左右兩邊的空格,但不會去除中間的空格
str.trim()
定義對象中新屬性或修改原有的屬性
object.defineProperty(obj,prop,descriptor)
object.defineProperty
的參數
參數 | 是否必需 | 類型 | 說明 |
---|---|---|---|
obj | true | Object | 目標對象 |
prop | true | String | 需新定義或修改的屬性的名字 |
descriptor | true | Object | 目標屬性所擁有的的特性 |
var obj={ id:1, pname:"小米", price:1999 } //對對象定義新屬性並賦值,之前的寫法 obj.num=1000; obj.price=99; //如今的寫法 Object.defineProperty(obj,'num',{ })
第三個參數descriptor的參數
參數 | 是否必需 | 類型 | 說明 |
---|---|---|---|
value | false | mixed | 設置屬性的值 默認undefined |
writable | false | boolean | 是否能夠重寫 默認false |
ebumerable | false | boolean | 目標是否能夠被枚舉(遍歷),默認false |
configurable | false | boolean | 目標屬性是否能夠被刪除或是否能夠再次修改特性true/false 默認爲false |
tips: 注意新定義的descriptor 都是默認爲false 用obj={} 來定義的由於沒有定義是否能夠被XX操做因此都是true
全部的函數都是Function的實例(對象),函數也是個對象,萬物皆對象
1、 函數的定義方式
1.自定義函數(命名函數)
function fn(){};
2.函數表達式(匿名函數)
var fun =function(){ }
3.利用new Function (不推薦,效率低)
new Function('參數1','參數2','函數體')
參數 | 是否必需 | 類型 | 說明 |
---|---|---|---|
參數1 | false | String | 第一個參數 |
參數2 | false | String | 第二個參數 |
函數體 | false | String | 第三個參數 |
tips:若是隻有一個參數那麼就是函數體
二 、 函數的調用方式
1.普通函數
this
指向window
function fn(){ console.log('人生的巔峯') } fn() (window.fn()) fn.call()
2.對象的方法
this
指向o
var o ={ sayHi:function(){ console.log('人生的巔峯') } } o.sayHi();
3.構造函數
this
指向實例對象
function Star(){}; new Star();
4.綁定事件函數
this
指向是函數的調用者btn
這個按鈕對象
//點擊了按鈕就能夠調用這個函數 btn.onclick=function(){};
5.定時器函數
this
指向的是window
這個函數式定時器自動1秒鐘調用一次
setInterval(function(){ },1000);
6.當即執行函數
this
指向window
(function(){ console.log('人生的巔峯') })()
tips: 當即執行函數是自動調用
調用方式 | this指向 |
---|---|
普通函數調用 | window |
構造函數調用 | 實例對象,原型對象裏面的方法也指向實例對象 |
對象方法調用 | 該方法所屬對象 |
事件綁定方法 | 事件綁定對 |
定時器函數 | window |
當即執行函數 | window |
call
var o={ name:"1" } functon fn(a,b){ console.log(a+b) } fn.call(o,1,2)
tips: 後兩個參數是形參 用於參與fn的一些對象,主要用於在es5中實現繼承
apply
var o={ name:"1" } functon fn(a,b){ console.log(a+b) } fn.apply(o,[1,2]) var arr=[1,66,4] //若是不想改變this(指定對象)就寫個null,但不合適寫Math就好了 Math.max.apply(Math,arr)
tips:參數必須是數組,但打印後倒是字符串或是數字(根據數組裏的數據類型,斷定)
bind
var o={ name:"1" } functon fn(a,b){ console.log(a+b) } var f= fn.bind(o); f(); //亦或者是 functon fn(a,b){ console.log(a+b) }.bind(this)
區別點:
主要應用場景:
做用:
js
語法的一些不合理、不嚴謹、減小了一些怪異行爲。es
的將來版本中可能會定義的一些語法,爲將來新版本的js
作好鋪墊。好比一些保留字如:class
,enum
,export
,extends
,import
,super
不能作變量名變化
先聲明
再使用隨意刪除
已經聲明好
的變量this
是undefined
而不是window
new
也能夠調用,當前普通函數,this
指向全局,在嚴格模式下不能使用了,this指向undefined
。//爲整個腳本開啓嚴格模式 <script> 'use strict'; </script> <script> (function()){ 'use strict'; }() </script> //爲某個函數開啓嚴格模式 <script> function fn(){ 'use strict'; /*裏面的代碼按照嚴格模式執行*/ } function fun(){ /*裏面的仍是按照普通模式執行*/ } </script>
tips:兼容ie10以上,ie10如下會忽略這個模式
高階函數- 函數能夠做爲參數傳遞,參數的接收方就是高階函數,即 fn
function fn (a,b,callback){ console.log(a+b); callback && callback() } fn(1,2,function(){ console.log(我是最後調用的); })
function fn (){ var num=10; function fun(){ console.log(num) } fun () } fn
function fn(){ var num=10; return function(){ console.log(num) } } //這裏f保存的是個函數 var f=fn() //這裏輸出的是num f()
for (var i=0;i<lis.length;i++){ /*利用for循環建立了4個當即函數*/ /*當即執行函數也成爲小閉包由於當即執行函數裏面的任何一個函數,均可以使用它的i這個變量*/ /*這裏的i是從底下的那個i傳進來的*/ (function(i){ lis[i].onclick=function() { console.log(i) } })(i)
tips:閉包的主要做用:延伸變量的做用範圍。但閉包容易照成內存泄漏,它一直不釋放資源,閉包總結:閉包是一個函數,閉包延伸了做用域範圍
function fn(n){ if(n==1) return 1; return n*fn(n-1); } console.log(fn(3)) 執行過程 return 3*fn(2) return 3*(2*fn(1)) return 3*(2*1) return 6
function fb(n){ if(n===1 || n===2){ return 1 } return fn(n-1)+fb(n+2); } console.log(fb(3)) console.log(fb(3))
var data=[ { id :1, name:'家電' goods':[ { id :11, name:'家電11' }, { id :12, name:'家電12' } ] } { id :2, name:'家電2' goods':[ { id :13, name:'家電13' } ] } ] function getID(json,id){ var o ={}; json.forEach(function(item)) { if(item.id==id){ console.log(item); o=item; }else if(item.goods&&item.goods.learth>0){ o= getID(item.goods,id) } } } console.log(getID(data,1))
tips: 開闢內存空間,容易照成死遞歸,出現棧溢出。在forEach裏面執行遞歸,不加退出條件,循環已經幫你加了。
var obj={ id:1, name:"andy", msg:{ //這個對象是深層次對象會被淺拷貝,會被拷貝地址,修改o同時會修改obj,這個就是淺拷貝 age:18 } } var o={} for(var k in obj){ //k 是屬性名 // obj[k] 屬性名 o[k]=obj[k]; } console.log(o); o.msg.age=20; console.log(obj)
2.es6的語法糖實現淺拷貝
Object.assign(o) /*主要用來對,對象賦值, key值相同的會覆蓋 其餘沒進行賦值的不會處理,由於是淺拷貝因此會影響原數組 */
function deepCopy(newobj,oldobj){ for(var k in oldobj){ var item=oldobj[k]; if(item instanceof Array){ newobj[k]=[]; //判斷是不是數組 deepCopy(newobj[k],item) }else if(item instanceof Object){ //判斷是不是對象 newobj[k]={}; deepCopy(newobj[k],item) }else{ // 簡單數據類型 newobj[k]=item; } } }
2.用JSON.stringify()和 jSON.parse() 來實現 深拷貝
tips: 數組也屬於Object 因此要把Array判斷寫在object的前面。總結:淺拷貝,深層次的數據如數組和對象只會拷貝引用,修改拷貝後的數據會同時修改原來的被拷貝的的數據,深拷貝,是對數組和對象開闢不一樣的空間,被拷貝的的數據。
靈活性、邏輯性和功能性很是的強,
能夠迅速地用極簡單的方式達到字符串的複雜控制
RegExp
對象來建立 正則表達式var regexp=new RegExp(/123/) console.log(regexp)
2.利用字面量
,建立正則表達式,即用//即註釋的中間寫上規則匹配就是正則表達式了
var rg=/123/; /* 可用test 方法來檢測是否符合正則表 返回true或false */ var rg=/123/; console.log(rg.test(123));
var rg=/^abc/ ^匹配的是開頭,這裏的是abc var rg=/^abc$/ 精確匹配 只有輸入abc 纔會匹配
/* 只要包含a,或者b,或c,其中一個就能夠了 */ var rg=/[abc]/ /* 只能選擇一個a或者b或者c其中的一個 三選一 */ var rg=/^[abc]$/ /* 只能選擇一個a-z,26字符中其中的一個字符,26選一 表示到a到z的範圍 能夠在[]中添加各類字符組合 */ var rg=/^[a-zA-z]$/ /* 若是中括號裏 ^ 表示取反的意思 不要和邊界符 ^ 混淆 取反即 如下就不能是 a-z和A-z */ var rg=/^[^a-zA-z]$/
//* 至關於>=0 能夠出現0次或者不少次 var rg=/^a*$/; console.log(rg.test('')) console.log(rg.test('aaa')) //+ 至關於>=1 能夠出現1次或者不少次,不能不出現,即0次 var rg=/^a+$/; console.log(rg.test('')) console.log(rg.test('aaa')) //? 至關於 1 || 0 能夠出現1次或者0次 var rg=/^a?$/; console.log(rg.test('')) console.log(rg.test('a')) console.log(rg.test('aaa')) //{3}就是重複出現3次 var rg=/^a{3}$/; console.log(rg.test('')) console.log(rg.test('aa')) console.log(rg.test('aaa')) //{3,}出現大於等於3 console.log(rg.test('')) console.log(rg.test('aaa')) //{3,16}出現大於等於3而且小於等於16 var rg=/^a{3,16}$/; console.log(rg.test('')) console.log(rg.test('a'))
模式是 :[a-zA-z] 某個規則 量詞符:{6,16} 這個規則的裏字符可出現的次數 即只能出現6-16個a-zA-z 裏的字符 且所有合起來只能有6-16個。 var rg=/^[a-zA-z]{6,16}$/
//這裏有小括號因此表示 abc 重複3次 var rg=/^(abc){3}/ //這裏沒有小括號 c 重複3次 var rg=/^abc{3}/
預約類 | 說明 |
---|---|
d | 匹配0-9之間的任一數字,至關於[0-9] |
D | 匹配0-9之外的字符,至關於1 |
w | 匹配任意的字母、數字、和下劃線,至關於[A-Za-z0-9_] |
W | 匹配任意的字母、數字和下劃線之外的字符,至關於2 |
s | 匹配空格(包括換行符、製表符、空格符等),至關於[trnvf] |
S | 匹配非空格(至關於3 |
//座機號碼驗證 010-12345678 0591-1234567 //第一種 var reg=/^\d{3}-\d{8}|\d{4}-\d{7}$/ //第二種 var reg=/^\d{3,4}-\d{7,8}$/
//手機號碼的正則表達式 var rg=/^1[3|4|5|7|8]\d{9}$/;
//qq號的正則 10000開始 var rg=/^[1-9]\d{4,}$/
var str=str.replace(/andy/,bady)
參數 | 說明 |
---|---|
第一個參數 | 被替換的字符串或者正則表達式 |
第二個參數 | 替換爲的字符串 |
返回值 是一個替換完畢的新字符串
tips: 正則表達式裏面不須要加引號, 無論是數字型仍是字符串型,正則表達式的中間不要有空格即//裏添加的內容不要用空格來間隔
es六、es7
的知識點let
關鍵字if(true){ let a=1; var b=3 } console.log(a) //訪問不到 undefined console.log(b) //訪問的到,輸出3
var num =10 if(true){ console.log(num) undefined let num=1 } /* num輸出在塊級做用域裏,使用的是塊級的做用域定義的變量,並且是在未定義前輸出因此是undefined */
for (var i=0;i<10;i++){ console.log(i) setTimeOut(function(){ console.log(`i:${i}`) }) } 在var定義的變量下,定時器裏輸出的都是10 由於此時循環已經結束了,i是最後的一個值。 用let 能夠正常循環輸出
const
關鍵字常量賦值後,內存地址(值)不能修改,分兩種狀況
const a =1 a=3 //報錯,值不能更改 const arr=[1,2] arr[0]=3 //可更改,只是更改結構內部的值 arr=[3,2] arr=[34,44] //不可更改總體都更改,是地址的更改,不容許
tips: 若是讓對象裏的屬性不可進行修改可使用es5的方法 Object.freeze(arr) 此時 arr內部的屬性也不能更改
let [a,b,c]=[1,2,3] || []; console.log(a,b,c,d,e) a 、b、c 輸出 1,2,3 d,e是undefined
let person ={name:'zhangsan',age:20} let {name,age}=person || {} console.log(name) //zhangsan console.log(age) // 20 let {name:myName,ages:myAge}=person console.log(myName,myAge) //也能夠輸出
//第一種狀況,把整個的對象賦值給另外一個讀寫 let user = { a: 1,b: 2,c: 3,d: 4,e: 5} let { aa = { a: user.a, b: user.b }, bb = { ...user } } = {} /* 第二種狀況,能夠把對象的值分配到不一樣的對象 */ let users = {}, userDetails = {}; ({ a: users.a, b: users.b, ...userDetails } = user); console.log(users, userDetails) //users {a:1,b:2} userDetails {c:3,d:4,e:5}
const Tom={ name: 'Tom jones', age:25, family:{ mother: 'Norah Jones', father: 'Richard Jones', brother: 'Howard Jones' } } //只有在變量是underfine時,才能使用默認值 null false 0 都是有值的 const { father:f,mother:m,brother='sss' } = Tom.family || {} ; //以上的f、m 是別名 輸出用別名
let a=10 let b=20 [a,b]=[b,a] console.log(a,b) //a輸出 20 b輸出10
tips: 第二種狀況,必定要加上括號。
function sum(num1,num2){ return num1+num2 } const sum=(n1,n2)=>{ return n1+n2 } //以上代碼只有一行,且return這行代碼就能夠簡寫爲 const sum=(n1,n2) => n1+n2
var num=10 let obj={ num:1 say:(){ console.log(this.num) } } obj.say() //這裏輸出的是10
const gg=()=>{ console.log(1) }
不適用箭頭函數的狀況
1.做爲構造函數,一個方法須要綁定到對象 const Person=function(name,points){ this.name=name this.points=points; } const jelly=new Person('jelly',5); 2.原型添加方法 Person.prototype.updatePoints=function(){ this.points++ console.log(this.points) } 3.事件 const button=document.querySelector('.zoom'); button.addEventListener('click',function(){ }) 4.須要使用arguments const sum =function(arguments){ /*arguments不是個真正的數組 須要用Array.from 轉換 或用擴展運算符[...arguments]來轉換*/ return Array.from(arguments).reduce((prevSum,value)=>pervSum+value,0 ) }
tips: 對象是不產生做用域,指向的s是全局window,因此箭頭函數的this,指向的是window,因此這裏輸出的是10
//定義個方法 const sum =(...args)=>{ let total=0; args.forEach(item=>{ total+=itme }) return total } sum(10,20) //args裏保存着10和20 sum(10,20,30)//args裏保存10,20,30
let ary1=['張三','李四','王五'] let [s1,...s2]=ary1 s1 //存着張三 s2 //接收剩餘參數成爲個新數組,存着李四和王五
擴展運算符
能夠將數組或者對象轉爲用逗號分隔的參數序列let ary=[1,2,3]; ...ary //1,2,3 轉爲去掉括號的用逗號分隔的參數序列 console.log(...ary) 1 2 3
擴展運算符
可用於合併數組,生成的是新數組let ary1=[1,2,3] let ary2=[4,5,6] ...ary1 //1,2,4 ...ary2 //4,5,6 //第一種 let ary3=[...ary1,...ary2] //第二種 -- push方法能夠有多個參數 ary3=ary1.push(...ary2)
擴展運算符
可將僞數組轉爲真正的數組,就可使用數組的一些方法var Odivs=document.getElementsByTagName('div') console.log(Odivs) //僞數組 可迭代遍歷但沒有數組方法 var ary=[...Odivs] ary.push('a') console.log(ary);
擴展運算符
是深拷貝,修改使用新生成的數組,不影響原來數組的值擴展運算符
的應用實踐1. //把二維數組擴展成對象數組 [...array[1],...Array[1]] 輸出 [object,object] 2. //可用來代替apply方法 const fruit=['apple','bananas','pear'] const newFruit=['orange','mongo'] //用apply合併數組,apply後面跟着的參數是數組 fruit.push.apply(fruit,newFruit) //用擴展運算符來合併 fruit.push(...newFruit)
擴展運算符
適用於函數的傳參例子1 var arrayLike={ "0":"1", "1":"2", "length":2 } Array.from(arrayLike,item=>item*2) 例子2 const todos=document.querySelectorAll('li'); const names=Array.from(todos,todo=>todo.textContent); console.log(names)
const str='abc' console.log(Array.from(str)) [a,b,c]
let ary=[{ id:1, name:'張三' },{ id:2, name:'李四' } ] let target= ary.find(item=> item.id==2 )
let ary=[10,20,50] const index= ary.findIndex((item,index)=>itme>15) console.log(index)
let ary=["a","b",c] ary.includes("a")
當前方法能夠彌補 new Array 構造方法返回結果不一致問題。
/*當參數只有一位的時候,返回的是長度爲1的數組 [undefined*1],而不是[1] 只有當參數是多個的狀況下才會返回正確的數據*/ new Array(1) array.of(1) 輸出的是[1]
當遍歷時遇到false時,就不執行了,返回false
let name=`帳上` let sayHello =`hello${name}`
let result={ name:"Zhangsan", age:20 } let html=` <div> <span>${result.name}</span> <span>${result.age}</span> </div> `
const fn=(){ return '我是fn函數' } let html=`我是模板字符${fn()}` const template=` <div class="greet"> <p> Hello </p> </div> `.trim() //模板字符串自己就是字符串,因此可使用字符串方法
function renderTodos(todos){ return ( `<ul> ${todos.map(todo=>` <li> ${todo.name} ${todo.completed?'√':'X'} </li>`).join('')} </ul> ` ) } //map 返回的是數組 循環渲染有,因此用join 去除
const user='Mary'; const topic='learn to use markdown' //模板字符串加方法 function highLight(strings,...values){ //strings 輸出的是:has commented on your topic //values 輸出的是:user和topic } const sentence= hightlight `${user} has commented on your topic ${topic} `
--String的擴展方法
let str='hello world'; str.startsWith('Hello') //true str.endsWith('!') 、//true //可傳遞第二個參數, 從第幾個參數開始 str.startsWith('Hello',6)
repeat
方法表示將原字符串重複n
次,返回一個新字符串'x'.repeat(3) // "xxx" 'hello'.repeat(2) //hellohello
const id ='510300198007300366x' const fan ='I love Laravist.' function padder(string,length=25){ return `${'',repeat(Math.max(length-string.length,0))}${string}` } console.log(padder(id)) console.log(padder(fan))
支持數組、字符串等 但目前版本不支取對象的循環
Array.protype.frist=function() { return this[0] } const fruits=['Apple','Bannana','Orange','Mango']; fruits.describe='My favorite fruits'; for(let index in fruits ){ console.log(fruits[index] ) 會輸出多餘的值 } for(let index of fruits ){ console.log(index ) 只輸出數組內的值 能夠 break } //迭代器 for(let [index,fruit] of fruits.entries() ){ console.log(index,fruit ) 只輸出數組內的值 能夠 break }
set
數據結構es6
提供了新的數據結構Set
。它相似於數組,可是成員的值都是惟一的,沒有重複的值。const s=new Set() s.size //看s的長度
es6
能夠進行數組去重const s3=new Set(["a","b","b"]) //用擴展運算符,變成用逗號分隔的 const arr=[...s3]
set
內置方法
tips:
set
的方法可使用鏈式調用
set
遍歷const s5=new Set(['a','b','c']) s5.forEach(value=>{ console.log(value) })
//接口返回數據結構--是個數組 0: {menu_id: 92, menu_name: "微信公衆號", menu_fid: 0, menu_val: "92_wechat_publicnumber"} 1: {menu_id: 1, menu_name: "學校管理", menu_fid: 0, menu_val: "1_school"} 2: {menu_id: 2, menu_name: "教師管理", menu_fid: 0, menu_val: "2_psychologist"} 3: {menu_id: 3, menu_name: "學生管理", menu_fid: 0, menu_val: "3_counseling"} 4: {menu_id: 4, menu_name: "量表中心", menu_fid: 0, menu_val: "4_scale"} 5: {menu_id: 5, menu_name: "心理諮詢", menu_fid: 0, menu_val: "5_advisory"} 6: {menu_id: 6, menu_name: "異常反饋", menu_fid: 0, menu_val: "6_abnormal"} 7: {menu_id: 7, menu_name: "活動管理", menu_fid: 0, menu_val: "7_activity"} 8: {menu_id: 8, menu_name: "在線求助", menu_fid: 0, menu_val: "8_help"} 9: {menu_id: 9, menu_name: "心理課堂", menu_fid: 0, menu_val: "9_classroom"} 10: {menu_id: 10, menu_name: "心理實驗", menu_fid: 0, menu_val: "10_experiment"} 11: {menu_id: 11, menu_name: "訂單管理", menu_fid: 0, menu_val: "11_order"} 12: {menu_id: 12, menu_name: "數據分析", menu_fid: 0, menu_val: "12_data"} 13: {menu_id: 14, menu_name: "學校列表", menu_fid: 1, menu_val: "14_school_list"} 14: {menu_id: 15, menu_name: "學校資訊", menu_fid: 1, menu_val: "15_information_list"} 15: {menu_id: 17, menu_name: "學校橫幅", menu_fid: 1, menu_val: "17_schoolad_list"} 16: {menu_id: 18, menu_name: "老師列表", menu_fid: 2, menu_val: "18_psychologist_list"} 17: {menu_id: 19, menu_name: "老師導入", menu_fid: 2, menu_val: "19_teacher_import"} 18: {menu_id: 20, menu_name: "發送信息", menu_fid: 2, menu_val: "20_edit_notice"} 19: {menu_id: 21, menu_name: "學生列表", menu_fid: 3, menu_val: "21_counseling_list"} 20: {menu_id: 22, menu_name: "學生導入", menu_fid: 3, menu_val: "22_counseling_import"} 21: {menu_id: 23, menu_name: "發送信息", menu_fid: 3, menu_val: "23_edit_cou_notice"} 22: {menu_id: 24, menu_name: "用戶統計", menu_fid: 3, menu_val: "24_user_count"} 23: {menu_id: 25, menu_name: "綜合檔案", menu_fid: 3, menu_val: "25_comprehensive_file"} 24: {menu_id: 26, menu_name: "量表分類", menu_fid: 4, menu_val: "26_scale_shape"} 25: {menu_id: 28, menu_name: "量表權限", menu_fid: 4, menu_val: "28_scale_rights"} 26: {menu_id: 29, menu_name: "測評查詢", menu_fid: 4, menu_val: "29_assess_search"} //根據fid生成帶孩子的二級樹形結構--只有二級就簡單點 getJsonTree (data, fId) { let itemArr = []; data.forEach(item => { const { menu_id = 0, menu_fid = 0, menu_name = '', menu_val = '' } = item || {} if (menu_fid === fId) { let newNode = { id: menu_id, label: menu_name, value: menu_val, checkAll: false, checkedOptions: [], options: this.getJsonTree(data, menu_id) //第一個是0寫死的id找不到父親的,找到的都是當父親的,第二個就是把本身的id當作是fid 去找它的孩子 }; itemArr.push(newNode); } }) return itemArr; }, // 孩子的數組,特殊狀況就用這個來代替 this.getJsonTree函數 (只限於二級) getChild (data, fId) { let itemArr = []; data.forEach(item => { const { menu_id = 0, menu_fid = 0, menu_name = '', menu_val = '' } = item || {} if (menu_fid === fId) { let newNode = { label: menu_name, value: menu_val, }; itemArr.push(newNode); } }) return itemArr; },
es6 對象 變的更增強大
const name='Lara' const age=2 const keys=['name','age'] const values=['lara',2] const laravist={ [keys.shift()]:values.shift(), [keys.shift()]:values.shift(), [keys.shift()]:values.shift(), }
const p=new Promise(reslove,reject)=>{ setTimeout()=>{ reject(Error('Error')) } }) p.then(data=>{console.log(data)}) .catch(err=>{console.log(err)})
tips: 在reject中使用Error返回錯誤信息時,使瀏覽器正肯定位到是reject那行發出的錯誤信息,而不是catch那行。
const userPromise=new Promise((resolove,reject)=>{ setTimeout(()=>{ reslove(['mojom','vanpe']) },2000) }) const moviePromise=new Promise(()=>{ setTimeout(()=>{ reslove({name:"摔跤",rat:9.2}) },500) }) Promise. all([userPromise,moviePromise]) .then(responses=>{ console.log(responses) }) .catch(responses=>{ console.log(responses) })
tips:Promise all
當以上全部promise
都正確執行時,才返回正確的,不然會被catch
捕獲。
Promise race
同時調用多個promise
當第一個調用的promise 正確執行時就在then中返回結果,否則就在catch中返回
Symbol
是js的第七種數據類型, 其餘6種:Undefined、Null、Boolean、Number和String,複雜的數據類型Objectconst peter=Symbol('peter'); const student=Symbol('student'); //如下nina兩個key值重複,因此用Symbol來標識 const classRoom={ [Symbol('lily')]:{grade:60,gender:'female'}, [Symbol('nina')]:{grade:60,gender:'female'}, [Symbol('nina')]:{grade:60,gender:'female'}, } //for 循環不能遍歷 for(let key of classRoom){ console.log(key) //輸出[] } //另類遍歷的方法 const syms=Object.getOwnPropertySymbols(classRoom).map(sym>classRoom[sym]) console.log(syms)
tips:classRoom[sym] 不能改爲 classRoom.sym 這裏會執行 classRoom['sym']但classRoom數據裏並無sym這個屬性名
eslint
代碼規範eslint
會找當前目錄的.eslintrc.js文件,若是找不到就往上級找/* globals Vue */ .eslintrc.js 文件中 globals: { Yx: true }
/* eslint-disable no-new */
/* eslint-enable no-new */
{ "plugins":["markdown"] }
靜態方法 Reflect.ownKeys() 返回一個由目標對象自身的屬性鍵組成的數組。
const object1 = { property1: 42, property2: 13 }; var array1 = []; console.log(Reflect.ownKeys(object1)); // expected output: Array ["property1", "property2"] console.log(Reflect.ownKeys(array1)); // expected output: Array ["length"]
轉化爲整形
//可使用+也可隱士轉化爲數字 +'243'
let methodName = 'info' class User { constructor(name,age){ this.name=name; this.age=age; } [methodName](){ console.log(1) } }
class student extends User { constructor(name,age){ super(name); /*super的做用及原理 做用 :繼承父類,等同於User.call(this,name)調用基類的構造函數 原理: student.prototype=new User() 類的原型被改變了,可是類的原型的構造函數的也改變了,要指定構造函數爲student student.prototype.constructor =student */ this.age=age; } }
爲Array 添加本身的方法
class Movie extends Array { constructor(name,...items){ super(...item) this.name=name } add(movie){ // this.push(movie) } } const movies=new Movie('favorite movies', {name:'rr1',score:8.7}, {name:'rr2',score:99.7}, {name:'rr3',score:91.7} ) movies.add() //添加內容
遍歷器(迭代器)
const colors=[1,2,3] const iterator= colors[Symbol.iterator]() iterator.next() /*輸出*/ Object{value:1,done:false } iterator.next() /*輸出*/ Object{value:2,done:false } iterator.next() /*輸出*/ Object{value:3,done:false } iterator.next() /*輸出*/ Object{value:undefined,done:true}
tips:
當done爲true時遍歷就結束了,輸出一個方法時有包含Iterator,就是遍歷器了,好比數組的 keys,entries,
values
//實現一個Array.values Array.prototype.values=function(){ let i = 0; let items = this; return{ //返回一個函數,造成閉包,能夠進行累加 next(){ const done =i > = items.length; const value = done?undefined:items[i++] return{ value, done } } } }
for of 的運行機制
for(const itme of color){} //of調用,colors[Symbol.iterator]() 這個屬性。 並把裏面的value值賦值給color
function* listColors(){ let i=0; yield i; //返回 i++; yield i; i++; yield i; } //生成了遍歷器 const colors=listColors(); colors.next() /*輸出*/ Object{value:0,done:false} colors.next() /*輸出*/ Object{value:1,done:false} colors.next() /*輸出*/ Object{value:2,done:false} colors.next() /*輸出*/ Object{value:undefined,done:true} const colors=[1,2,3] function* loop(repos){ console.log(colors) for(const repo of repos){ yield repo } } const repoGen=loop(repos)
//進行ajax方法 function ajax(url){ axios.get(url).then( res => 執行成功後再執行下一步 userGen.next(res.data) ) } //生成器 function* steps(){ const users = yield ajax('https://api.github.com/users'); const firstUser = yield ajax(`https://api.github.com/users/${users[0].login}`) const followers = yield ajax(firstUser.followers_url); } const userGen =steps() userGen.next()
const person = {name:'laravist',age:2000}; const personHandle={ //獲取值 get(target,key){ //target:原目標; key:鍵值 //把屬性值都轉換成大寫 return target[key].toUpperCase(); } //設置值 set(target,key,value){ //去掉空格 if(typeof value==='string'){ target[key]=value.trim() } } } const personProxy = new Proxy(person,personHandle) personProxy.name=' codecasts ' console.log(personProxy.name) // 輸出:CODECASTS --去去掉空格並轉換成大寫
// 安全挾持 const safeHandler = { set(target,key,value){ //找相相似的鍵 const likekey = Object.keys(target).find(k=>k.toLowerCase()===key.toLowerCase()); //若是找到就不讓其賦值 if(!(key in target) && likekey ){ throw new Error(` Oops! looks like we already have a property ${key} but with the case of ${likeKey}`) } } } const safetyProxy=new Proxy({id:2}, safeHandler); safetyProxy.ID=5 /*會報錯,賦值已經被挾持了只要和id這個鍵值相相似的 好比 Id ID iD 都不讓賦值*/
// 定義一個set const colors=new Set() colors.add(4)//添加元素 colors.delete(4)//刪除 colors.has(4)//檢驗是否存在 /*能夠用正常的數組循環方式進行循環*/ for(let color of colors ){ console.log(color) } colors.forEach(item=>{ console.log(item) })
const colorsSet=new Set([1,2,3,4,4,4,4]) const colorsArr=[...colorsSet] // 或者能夠經過array.from() 來進行轉換
const { jelly:{name:'jelly',age:20}, mary:{name:'mary',age:25} } ={} const weakPeople=new WeakSet([jelly,mary]) console.log(weakPeople) mary=null console.log(weakPeople) // mary 這個屬性值就不見了, 若是用數組來存儲,這個值仍是存在的
const people = new map(); people.set('jelly',23) people.has('jelly') //檢驗是否含有jelly這個值 people.delect('jelly') //進行刪除 people.clear()所有刪除 //對 fruits 進行賦值 const fruits = new Map([['apple',6],['banana',5]]) //用forEach和解構的方式來遍歷map fruits.forEach([key,value]=>{ console.log(key,value) }) //若是不用解構方式,他返回的值是一整個是數組
const jelly = {name:'jelly'}; const miffy = {name:'miffy'} const strong= new Map(); const weak=new WeakMap(); strong.set(jelly,'jelly is the best!') weak.set(miffy,'miffy is the 2nd best!')