JavaScript進(jìn)階-創(chuàng)新互聯(lián)

一 面向?qū)ο?/h2>

1 ES6之前的對象

1 基本對象的創(chuàng)建

1 定義一個(gè)函數(shù)(構(gòu)造器)對象,使用this定義屬性
2 使用new 和構(gòu)造器創(chuàng)建一個(gè)新對象
當(dāng)使用new關(guān)鍵字后,其函數(shù)的調(diào)用將不再是函數(shù),而是一個(gè)原型,就以這個(gè)原型為模板,構(gòu)造出自己的實(shí)例,然后進(jìn)行對應(yīng)的個(gè)性化操作,將其當(dāng)做構(gòu)造器來處理其特殊的屬性或方法。

漳縣網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,漳縣網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為漳縣近千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個(gè)售后服務(wù)好的漳縣做網(wǎng)站的公司定做!

//古老的定義對象的方式 
var  obj= {
    a:'abc',
    b:'123',
    c:'[1,2,3,4]',
}
console.log(obj.a,obj.b,obj.c) 
function fn(x){
    this.x=x;
}
console.log(typeof(fn)) // 此處返回是一個(gè)函數(shù)
function  fn1(x,y) {
    this.x=x;
    this.y=y;
    console.log(this)  //指代函數(shù)本身,而不是實(shí)例化后的結(jié)果
    console.log(arguments)
}
a=new  fn1(10,20)  //對象構(gòu)建,fn1由普通函數(shù)變成了一個(gè)構(gòu)造器,new 先做對象,基于原型將a進(jìn)行處理,通過對象虧幫屬性
console.log(a.x,a.y)

結(jié)果如下

JavaScript進(jìn)階

2 繼承關(guān)系

function  fn(x,y) {
    console.log('fn')
    this.x=x; //初始化屬性 
    this.y=y;
    this.show=()=> ('show')  //初始化方法,及函數(shù) 
}
//繼承
function  fn1(x,y,z) {
    console.log('fn1')
    fn.call(this,x,y);  //調(diào)用父類構(gòu)造器,
    this.z=z;
}

a=new  fn1(1,2,3)
console.log('fn1',a)  //此處將a修改成一個(gè)對象,及字典,其對象中包含著所有的屬性和方法
console.log(a.show(),a.x,a.y,a.z)

結(jié)果如下

JavaScript進(jìn)階

2 ES6之中的對象

1 要求和基本定義處理

1 類的定義使用class 關(guān)鍵字,創(chuàng)建的本質(zhì)還是函數(shù),是一個(gè)特殊的函數(shù)
2 一個(gè)類只能擁有一個(gè)名為constructor的構(gòu)造方法,如果沒有顯示的定義一個(gè)構(gòu)造方法,則會默認(rèn)添加一個(gè)constructor方法
3 繼承使用extends 關(guān)鍵字
4 一個(gè)構(gòu)造器可以使用super關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)
5 類沒有私有屬性

class  fn{   //定義類
    constructor(x,y){ 
        console.log('fn')
        this.x=x;  //定義屬性 
        this.y=y;
    }
    show ()  //定義方法 
    {  
        console.log(this,this.x,this.y)
    }
}
//繼承關(guān)系 
class  fn1 extends  fn{   //使用extends表示繼承 
    constructor(x,y,z){
        console.log('fn1')
        super(x,y);  //調(diào)用父類方法,必須傳入對應(yīng)的值,否則父類無入值則會報(bào)錯(cuò)。
        this.z=z;
    }
}
a=new  fn1(1,2,3)
console.log(a.show())  //調(diào)用父類的方法
console.log(a.x,a.y,a.z)

結(jié)果如下

JavaScript進(jìn)階

2 函數(shù)重載

函數(shù)重載及函數(shù)名稱相同,參數(shù)個(gè)數(shù)或類型不同,此處稱為重載
子類匯總直接可以重寫父類的方法,如果需要使用父類的方法,則使用super.method()的方式調(diào)用

class  fn{   //定義類
    constructor(x,y){ 
        console.log('fn')
        this.x=x;  //定義屬性 
        this.y=y;
    }
    show ()  //定義方法 
    {  
        console.log(this,this.x,this.y)
    }
}

class  fn1 extends  fn{   //使用extends表示繼承 
    constructor(x,y,z){
        console.log('fn1')
        super(x,y);  //調(diào)用父類方法,必須傳入對應(yīng)的值,否則父類無入值則會報(bào)錯(cuò)。
        this.z=z;
    }
    show(){  //屬性重載操作
        console.log(this,this.x,this.y,this.z)
    }
}
a=new  fn1(1,2,3)
console.log(a.show())  //重載后的屬性調(diào)用
console.log(a.x,a.y,a.z)

結(jié)果如下

JavaScript進(jìn)階

使用箭頭函數(shù)重寫方法

class  fn{   //定義類
    constructor(x,y){ 
        console.log('fn')
        this.x=x;  //定義屬性 
        this.y=y;
    }
    show = () => console.log(this,this.x,this.y)
}

class  fn1 extends  fn{   //使用extends表示繼承 
    constructor(x,y,z){
        console.log('fn1')
        super(x,y);  //調(diào)用父類方法,必須傳入對應(yīng)的值,否則父類無入值則會報(bào)錯(cuò)。
        this.z=z;
    }
    show  = ()  => console.log(this,this.x,this.y,this.z)
}
a=new  fn1(1,2,3)
console.log(a.show())  //重載后的屬性調(diào)用
console.log(a.x,a.y,a.z)

3 類和屬性的繼承先后次序

class  fn{   //定義類
    constructor(x,y){ 
        this.x=x;  //定義屬性 
        this.y=y;
        this.show=() => console.log('this fn',this.x,this.y)
    }
    show = () => console.log('fn',this.x,this.y)
}

class  fn1 extends  fn{   //使用extends表示繼承 
    constructor(x,y,z){
        super(x,y);  //調(diào)用父類方法,必須傳入對應(yīng)的值,否則父類無入值則會報(bào)錯(cuò)。
        this.z=z;
        this.show=()  => console.log('this fn1',this.x,this.y,this.z);
    }
    show  = ()  => console.log('fn1',this.x,this.y,this.z);
}
a=new  fn1(1,2,3)
console.log(a.show())

結(jié)果如下

JavaScript進(jìn)階

此處默認(rèn)調(diào)用的是子類的屬性,

class  fn{   //定義類
    constructor(x,y){ 
        this.x=x;  //定義屬性 
        this.y=y;
        this.show=() => console.log('this fn',this.x,this.y)
    }
    show = () => console.log('fn',this.x,this.y)
}

class  fn1 extends  fn{   //使用extends表示繼承 
    constructor(x,y,z){
        super(x,y);  //調(diào)用父類方法,必須傳入對應(yīng)的值,否則父類無入值則會報(bào)錯(cuò)。
        this.z=z;
        // this.show=()  => console.log('this fn1',this.x,this.y,this.z);
    }
    show  = ()  => console.log('fn1',this.x,this.y,this.z);
}
a=new  fn1(1,2,3)
console.log(a.show())

結(jié)果如下

JavaScript進(jìn)階

此處調(diào)用的是子類的方法

class  fn{   //定義類
    constructor(x,y){ 
        this.x=x;  //定義屬性 
        this.y=y;
        this.show=() => console.log('this fn',this.x,this.y)
    }
    show = () => console.log('fn',this.x,this.y)
}

class  fn1 extends  fn{   //使用extends表示繼承 
    constructor(x,y,z){
        super(x,y);  //調(diào)用父類方法,必須傳入對應(yīng)的值,否則父類無入值則會報(bào)錯(cuò)。
        this.z=z;
        // this.show=()  => console.log('this fn1',this.x,this.y,this.z);
    }
    // show  = ()  => console.log('fn1',this.x,this.y,this.z);
}
a=new  fn1(1,2,3)
console.log(a.show())

結(jié)果如下

JavaScript進(jìn)階

class  fn{   //定義類
    constructor(x,y){ 
        this.x=x;  //定義屬性 
        this.y=y;
        // this.show=() => console.log('this fn',this.x,this.y)
    }
    show = () => console.log('fn',this.x,this.y)
}

class  fn1 extends  fn{   //使用extends表示繼承 
    constructor(x,y,z){
        super(x,y);  //調(diào)用父類方法,必須傳入對應(yīng)的值,否則父類無入值則會報(bào)錯(cuò)。
        this.z=z;
        // this.show=()  => console.log('this fn1',this.x,this.y,this.z);
    }
    // show  = ()  => console.log('fn1',this.x,this.y,this.z);
}
a=new  fn1(1,2,3)
console.log(a.show())

結(jié)果如下

JavaScript進(jìn)階

總結(jié)
屬性和方法定義,不管是父類還是子類。都是優(yōu)先使用屬性,若兩個(gè)都是方法,則子類覆蓋父類 ,如果都是屬性,則是子類覆蓋父類,子類的優(yōu)先級是高于父類的

4 靜態(tài)方法

靜態(tài)屬性目前支持不完全
在方法前面加上static就是靜態(tài)方法了,此處的靜態(tài)方法是在類中進(jìn)行調(diào)用的,而不是在實(shí)例中。

class  fn{   //定義類
    constructor(x,y){ 
        this.x=x;  //定義屬性 
        this.y=y;
    }
    static  show = () => console.log('fn',this.x,this.y)
}
console.log(fn.show())
a=new fn(1,2)
console.log(a.show())

結(jié)果如下

JavaScript進(jìn)階

3 this 中坑

1 問題引出

雖然JavaScript和C和Java都有this,但JavaScript的表現(xiàn)是不同的
原因在于C,Java是靜態(tài)編譯語言,this是在編譯期間綁定的,而js是動(dòng)態(tài)語言,是在運(yùn)行期間鎖定的。

var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
name: 'test',
getNamefunc: function(){
    console.log(this.name)
    console.log(this)
    console.log('-----------------')
    return  function() {
        console.log(this == global);  //檢查其是否是全局的
        return this.name;
    }
    }
}

method=school.getNamefunc //此屬性調(diào)用后返回的是函數(shù)的類型,并未調(diào)用外層函數(shù)
a=method()  //調(diào)用外層函數(shù)
a()  //調(diào)用內(nèi)層函數(shù)

結(jié)果如下

JavaScript進(jìn)階

上面的返回結(jié)果是其this本應(yīng)該是school,卻被處理稱為了全局函數(shù)

var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
name: 'test',
getNamefunc: function(){
    console.log(this.name)
    console.log(this)
    console.log('-----------------')
    return  function() {
        console.log(this == global);  //檢查其是否是全局的
        return this.name;
    }
    }
}

method=school.getNamefunc() //此處調(diào)用外層函數(shù)
a=method()  //調(diào)用外層函數(shù)

結(jié)果如下

JavaScript進(jìn)階

此處的結(jié)果是this仍然是全局屬性


分析上例
第三行的打印結(jié)果是true,則表明當(dāng)前是global的作用于,因?yàn)檎{(diào)用這個(gè)返回的函數(shù)是直接調(diào)用的,這是一個(gè)普通函數(shù)調(diào)用,因此this是全局對象

第四行undefined,就是因?yàn)閠his是global,所以沒name屬性

這就是函數(shù)調(diào)用的時(shí)候,調(diào)用方式不同,this對應(yīng)的對象不同,它已經(jīng)不是C++,Java的指向?qū)嵗旧砹恕?/p>

this的問題,這是歷史遺留問題,新版本只能兼容了。

2 解決辦法

1 顯式傳參
var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
name: 'test',
getNamefunc: function(){
    console.log(this.name)
    console.log(this)
    console.log('-----------------')
    return  function(that) {  //通過此處傳遞參數(shù)的方式改變
        console.log(that == global);  //檢查其是否是全局的
        return that.name;
    }
    }
}

console.log(school.getNamefunc()(school))

結(jié)果如下

JavaScript進(jìn)階

2 ES3 引入了apply和 call方法

通過call將指定的this進(jìn)行指定了。JavaScript中指代的是這個(gè),其他的Java指定的不同,普通函數(shù)的調(diào)用和對象的調(diào)用是不同的,普通函數(shù)的調(diào)用中的thi指代的是全局變量,而在對象中調(diào)用,默認(rèn)傳遞的值是this的本身

var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
    name: 'test',
    getNamefunc: function(){
        console.log(this.name)
        console.log(this)
        console.log('-----------------')
        return  function() {
            console.log(this == global);  //檢查其是否是全局的
            return this.name;
        }
        }
    }

    var school1={
        'name': 'test1'
    }
    method=school.getNamefunc() //此屬性調(diào)用后返回的是函數(shù)的類型,并未調(diào)用外層函數(shù)
    console.log(method.call(school1))  //通過call將其this傳遞進(jìn)去,
    console.log('---------------')
    console.log(method.call(school))
    console.log('++++++++++++++++')
    console.log(method.apply(school)) //通過apply,將其this傳遞過去

結(jié)果如下

JavaScript進(jìn)階

相關(guān)源碼

JavaScript進(jìn)階

apply和 call方法都是函數(shù)對象的方法
apply傳遞其他參數(shù)使用數(shù)組,call傳遞其他參數(shù)需要使用可變參數(shù)收集。相關(guān)情況如下

var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
    name: 'test',
    getNamefunc: function(){
        console.log(this.name)
        console.log(this)
        console.log('-----------------')
        return  function(x,y,z) {
            console.log(this == global,x,y,z);  //檢查其是否是全局的
            return this.name;
        }
        }
    }

    method=school.getNamefunc() //此屬性調(diào)用后返回的是函數(shù)的類型,并未調(diào)用外層函數(shù)
    console.log('---------------')
    console.log(method.call(school,[1,2,3])) //此處傳地過去不會解構(gòu),是一個(gè)參數(shù)
    console.log('++++++++++++++++')
    console.log(method.apply(school,[1,2,3])) //通過apply,會解構(gòu),

結(jié)果如下

JavaScript進(jìn)階

3 ES5中引入了bind方法
var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
    name: 'test',
    getNamefunc: function(){
        console.log(this.name)
        console.log(this)
        console.log('-----------------')
        return  function(x,y,z) {
            console.log(this == global,x,y,z);  //檢查其是否是全局的
            return this.name;
        }
        }
    }

method=school.getNamefunc() //此屬性調(diào)用后返回的是函數(shù)的類型,并未調(diào)用外層函數(shù)
console.log(method.bind(school)(1,2,3))

結(jié)果如下

JavaScript進(jìn)階

bind 是會返回一個(gè)新函數(shù),其和偏函數(shù)相似

4 ES6中支持了this箭頭函數(shù)
var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
    name: 'test',
    getNamefunc: function(){
        console.log(this.name)
        console.log(this)
        console.log('-----------------')
        return  (x,y,z)  => {
            console.log(this == global,x,y,z);  //檢查其是否是全局的
            return this.name;
        }
        }
    }

school1={
    name:'test1'
}
method=school.getNamefunc() //此屬性調(diào)用后返回的是函數(shù)的類型,并未調(diào)用外層函數(shù)
console.log(method(1,2,3))

結(jié)果如下

JavaScript進(jìn)階

最外層使用箭頭函數(shù)的結(jié)果

var  school= {  //此處定義一個(gè)對象,其中包含name和getNamefunc兩個(gè),其中name是屬性,getNamefunc是方法,其返回值是一個(gè)函數(shù)
    name: 'test',
    getNamefunc: () => {
        console.log(this.name)
        console.log(this)
        console.log('-----------------')
        return  (x,y,z)  => {
            console.log(this == global,x,y,z);  //檢查其是否是全局的
            return this.name;
        }
        }
    }

school1={
    name:'test1'
}
method=school.getNamefunc() //此屬性調(diào)用后返回的是函數(shù)的類型,并未調(diào)用外層函數(shù)
console.log(method(1,2,3))

結(jié)果如下

JavaScript進(jìn)階

因此,一般不建議最外層使用箭頭函數(shù)

4 高階對象

1 簡介

Mixin 模式,及混合模式,這是一種不用繼承就能復(fù)用的技術(shù),主要還是為了解決多重繼承的問題,多重繼承路徑是個(gè)問題

JS是基于對象的,類和對象都是對象模板

混合Mixin,指的是將一個(gè)對象的全部或者部分拷貝到另一個(gè)對象上去了,其實(shí)就是屬性,可以將多個(gè)類或者對象混合成一個(gè)類或者對象,任何一個(gè)對象都可以作為另一個(gè)對象的原型。

2 基礎(chǔ)代碼

class test{
    constructor(){
        console.log('test',this)
        if (typeof(this.show) !=='function')  {
            throw  new  ReferenceError('should define stringify.');
        }
    }
}
class test1  extends  test{
    constructor(x,y){
        super();
        this.x=x;
        this.y=y;
    }
    show(){
        return   `test1 ${this.x} ${this.y}`;
    }
}
p=new  test1(1,2)
console.log(p.show())

結(jié)果如下

JavaScript進(jìn)階

此處的核心是誰調(diào)用的問題,上述父類的this是子類的實(shí)例,而不是子類調(diào)用父類后父類形成的實(shí)例,因此這也是驗(yàn)證通過的原因。

class test{
    constructor(){
        console.log('test',this)
        if (typeof(this.show) !=='function')  {
            throw  new  ReferenceError('should define stringify.');
        }
    }
}
class test1  extends  test{
    constructor(x,y){
        super();
        this.x=x;
        this.y=y;
    }
    show(){
        return   `test1 ${this.x} ${this.y}`;
    }
}

class test2  extends  test1 {
    constructor(x,y,z)  {
        super(x,y);
        this.z=z;
    }
}
p=new  test2(1,2)
console.log(p.show())  //此處自己本身沒有show,則通過調(diào)用父類的show來實(shí)現(xiàn),上述傳入的this 仍然是子類的實(shí)例,

結(jié)果如下

JavaScript進(jìn)階

3 高階對象實(shí)現(xiàn)

通過在test中使用函數(shù)并傳遞參數(shù)的方式將test1的相關(guān)屬性注入進(jìn)去,相關(guān)代碼如下

初步改造結(jié)果如下

class test1{
    constructor(x,y){
        this.x=x;
        this.y=y;
    }
    show(){
        return   `test1 ${this.x} ${this.y}`;
    }
}
const  test = function  test(SUP)   {  //此函數(shù)的返回值是一個(gè)類,通過將類test1傳入其中進(jìn)行相關(guān)的操作處理并進(jìn)行輸出
    return   class    extends  SUP {
          constructor(...args) {
              super(...args);
              console.log('test',this)
              if (typeof(this.show) !=='function')  {
                  throw  new  ReferenceError('should define stringify.');
          }
      }
    }
}

class test2 extends  test(test1){
  constructor(x,y,z)  {
      super(x,y);
      this.z=z;
  }
}
p=new test2(1,2,3)
console.log(p.show())

結(jié)果如下

JavaScript進(jìn)階

將上述函數(shù)修改為箭頭函數(shù)結(jié)果如下

class test1{
    constructor(x,y){
        this.x=x;
        this.y=y;
    }
    show(){
        return   `test1 ${this.x} ${this.y}`;
    }
}
const  test =  SUP=>  class    extends  SUP {
          constructor(...args) {
              super(...args);
              console.log('test',this)
              if (typeof(this.show) !=='function')  {
                  throw  new  ReferenceError('should define stringify.');
          }
      }
    }

class test2 extends  test(test1){
  constructor(x,y,z)  {
      super(x,y);
      this.z=z;
  }
}
p=new test2(1,2,3)
console.log(p.show())

注意:
test(test1)這一步實(shí)際上是一個(gè)匿名箭頭函數(shù)的調(diào)用,返回一個(gè)新的類型,test2繼承自這個(gè)新的類型,增強(qiáng)了功能,react大量使用了這種Mixin技術(shù)。

二 異常

1 基礎(chǔ)實(shí)例

try {
    throw  1; // 拋出異常
} catch (error){    //此處不用指定異常類型,此處的error是上面的throw扔出來的
    console.log(error,typeof(error));
}

JavaScript進(jìn)階

拋出一個(gè)對象

try {
    throw  {}; // 拋出異常
} catch (error){    //此處不用指定異常類型,此處的error是上面的throw扔出來的
    console.log(error,typeof(error));
}

結(jié)果如下

JavaScript進(jìn)階

拋出一個(gè)函數(shù)

try {
    throw  () => console.log(2); // 拋出異常
} catch (error){    //此處不用指定異常類型,此處的error是上面的throw扔出來的
    console.log(error,typeof(error));
}

結(jié)果如下

JavaScript進(jìn)階

2 拋出異常

try {
    throw  Error('new Error'); // 拋出異常
} catch (error){    //此處不用指定異常類型,此處的error是上面的throw扔出來的
    console.log(error,typeof(error));
}

結(jié)果如下

JavaScript進(jìn)階

try?{
    ????throw?ReferenceError('new?Error')
    }?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
    ????console.log(error,typeof(error));
    };

結(jié)果如下

JavaScript進(jìn)階

try?{
    ????throw?ReferenceError('new?Error')
    }?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
    ????console.log(error,typeof(error));  //此處不影響下面的執(zhí)行
        console.log(error.constructor);  //此處的執(zhí)行結(jié)果是函數(shù)
    };

結(jié)果如下

JavaScript進(jìn)階

try?{
    ????throw?ReferenceError('new?Error')
    }?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
    ????console.log(error,typeof(error));  //此處不影響下面的執(zhí)行
        console.log(error.constructor.name);  //獲取函數(shù)名稱
    };

結(jié)果如下

JavaScript進(jìn)階

3 必須執(zhí)行的finally

try?{
    ????throw?null;
    }?catch??(error){??//此處不用指定類型??,此處的error是接上面扔出來的東西
    ????console.log(error,typeof(error));
    ????console.log(error.constructor.name);?//一切皆函數(shù)
    }?finally??{  //定義必須執(zhí)行的函數(shù)
    ????console.log('1325345234')
    }

結(jié)果如下

JavaScript進(jìn)階

三 解構(gòu)和相關(guān)方法

1 JS數(shù)組解構(gòu)

1 常量的修改

常量的聲明和初始化時(shí)不能被分開的,常量只是對象的地址不能發(fā)生改變了,并不是其中的內(nèi)容也不能改變了。

const   l1=[1,2,3,4]
l1.pop() //l1雖然是一個(gè)常量,但其可以被修改
console.log(l1)

JavaScript進(jìn)階

2 參數(shù)解構(gòu)

完全解構(gòu)

const   l1=[1,2,3,4]
const  [a,b,c,d]=l1 
console.log(a,b,c,d)

JavaScript進(jìn)階

丟棄解構(gòu)

const   l1=[1,2,3,4]
const  [a,b,,c,d]=l1 
console.log(a,b,c,d)

結(jié)果如下

JavaScript進(jìn)階

const   l1=[1,2,3,4]
const [a]=l1
console.log(a)

結(jié)果如下

JavaScript進(jìn)階

可變變量

const   l1=[1,2,3,4]
const  [a,...d]=l1 
console.log(a,d)

結(jié)果如下

JavaScript進(jìn)階

const   l1=[1,2,3,4]
const  [a,...d,e]=l1  //可變長必須放置在最后面 
console.log(a,d,e)

JavaScript進(jìn)階

默認(rèn)值

const   l1=[1,2,3,4]
const [x=10,,,,y=20]=l1  //能覆蓋的覆蓋,不能覆蓋的保持原值,先賦值,再覆蓋,
console.log(x,y)

JavaScript進(jìn)階

3 復(fù)雜數(shù)組解構(gòu)

const?arr?=?[1,[2,3],4];??//三個(gè)元素,嵌套解構(gòu)
const?[a,[b,c],d]=arr;??
console.log(a,b,c,d);??//直接拆開?
const?[e,f]=arr;??//?只有兩
console.log(e,f);??//?第一個(gè)和第二個(gè)?

const?[g,h,i,j=18]=arr;??//?三個(gè)?加1?,則是對應(yīng)的
console.log(g,h,i,j);
const??[k,...l]=arr;??//?此處會將后面兩個(gè)元素進(jìn)行搬家
console.log(k,l);

結(jié)果如下

JavaScript進(jìn)階

2 數(shù)組方法

1 方法描述

方法 描述
push(...items)尾部追多個(gè)元素
pop()移除最后一個(gè)元素,并返回它
map引入處理函數(shù)來處理數(shù)組中的每一個(gè)元素,返回新的數(shù)組
filter引入處理函數(shù)處理數(shù)組中的每一個(gè)元素,此處理函數(shù)返回true的元素保留,否則該元素被過濾掉,保留的元素構(gòu)成新的數(shù)組返回
foreach迭代所有元素,無返回值

2 push方法

const   l1=[1,2,3,4]
l1.push([5,6,7,8])
l1.push(...['a','b','c'])
l1.push(9,10,11)
console.log(l1)

結(jié)果如下

JavaScript進(jìn)階

3 pop 方法

const   l1=[1,2,3,4]
l1.push([5,6,7,8])
l1.push(...['a','b','c'])
l1.push(9,10,11)
console.log(l1.pop())
console.log(l1.pop())
console.log(l1.pop())
console.log(l1)

結(jié)果如下

JavaScript進(jìn)階

4 map方法

const  abs = (x) => x**2
const   l1=[1,2,3,4]
console.log(l1.map(abs))

結(jié)果如下

JavaScript進(jìn)階

5 filter

const  abs  = function  (x)  {
    if (x%2==0) {
        return  true;
    }
    else {
        return  false;
    }
}
const   l1=[1,2,3,4]
console.log(l1.filter(abs))

結(jié)果如下

JavaScript進(jìn)階

6 foreach

const   l1=[1,2,3,4]
const  newarr= l1.forEach(x=>x+10) //無返回值
console.log(newarr,l1)

結(jié)果如下

JavaScript進(jìn)階

7 數(shù)組練習(xí)

有一個(gè)數(shù)組const arr=[1,2,3,4,5];,要求計(jì)算出所有元素平方值是偶數(shù)且大于10的。

代碼一

const   arr=[1,2,3,4,5];
console.log(arr.filter(x?=>?((x**2)%2==0?&&?(x**2)>10)))

代碼二,若平方是偶數(shù),則該數(shù)也應(yīng)該是偶數(shù),則如下

const   arr=[1,2,3,4,5];
console.log(arr.filter((x=> x%2==0 && x**2>10)))

代碼三,通過map來實(shí)現(xiàn)

const   arr=[1,2,3,4,5];
console.log(Math.log2(((arr.filter(x=>x%2==0)).map(x=>x**2)).filter(x=>x>10)))

代碼四,求10的平方根,然后再進(jìn)行相關(guān)比較

const   arr=[1,2,3,4,5];
const  cond=10
const  cond1=Math.sqrt(cond)
console.log(arr.filter(x=>x%2==0 && x> cond1))

3 對象解構(gòu)

var??metadata=?{
    ????title:?"Seratchpad",
    ????translations?:[
    ????????{
    ????????locale:?"de",
    ????????localization_tags:?[],
    ????????last_edit:?"2019-01-01T08:11:11",
    ????????url:?"/de/docs/Tools/scratchpad",
    ????????title:?"JavaScript-Umgebung"
    ????????}
    ????],
    ????url:?"/en-US/docs/Tools/Scratchpad"?
}
var  {title:enTitle,translations:[{title:?localeTitle}]?}=metadata; //: 后面的是重命名

console.log(enTitle)
console.log(localeTitle)

JavaScript進(jìn)階

4 對象操作

1 基本介紹

object 的靜態(tài)方法 描述
object.keys(obj)ES5開始支持,返回所有key
object.values(obj)返回所有值,實(shí)驗(yàn)階段,支持較差
object.entries(obj)返回所有值,試驗(yàn)階段,支持較差
object.assign(target,...sources)使用多個(gè)source對象,來填充target對象,返回target對象
var??obj?=?{
    ????a:100,
    ????b:200,
    ????c:()=>{}
    }
console.log(Object.keys(obj)) //返回所有的鍵
console.log(Object.values(obj)) //返回所有的值
console.log(Object.entries(obj))//返回所有的鍵和值
obj1={
    d:300,
    e:400,
}
let  obj2=Object.assign(obj,obj1)  //返回新的對象
console.log()

結(jié)果如下

JavaScript進(jìn)階

四 模塊化

1 簡介

ES6 之前,JS沒有出現(xiàn)模塊化系統(tǒng)
JS主要是在前端瀏覽器中使用,JS文件下載緩存到客戶端,在瀏覽器中執(zhí)行。
比如簡單的表達(dá)本地驗(yàn)證,漂浮一個(gè)廣告。


服務(wù)器端使用ASP,JSP等動(dòng)態(tài)網(wǎng)頁技術(shù),將動(dòng)態(tài)生成數(shù)據(jù)嵌入一個(gè)HTNL模板,里面夾雜著JS后使用<script>標(biāo)簽,返回瀏覽器端。
這時(shí)候的JS知識一些簡單的函數(shù)和語句組合。


2005年后,隨著Google大量使用了AJAX技術(shù)后,可以一步請求服務(wù)器端數(shù)據(jù),帶來了前端交互的巨大變化,前端的功能需求越來越多,代碼也越來越多,隨著JS文件的增加,災(zāi)難性的后果產(chǎn)生了,由于習(xí)慣了隨便寫,JS腳本中各種全局變量污染,函數(shù)名沖突,無法表達(dá)腳本之間的依賴關(guān)系。此時(shí)便有待模塊化的產(chǎn)生。


2008年V8引擎發(fā)布后,2009年誕生了nodejs,支持服務(wù)端JS編程,但沒有模塊化是不可以的,之后產(chǎn)生了commonjs規(guī)范。

commonjs 規(guī)范
使用全局require函數(shù)來導(dǎo)入模塊,模塊名就是文件名,使用exports導(dǎo)出變量
exports包含了所有需要導(dǎo)出的函數(shù)

require會將exports中的所有函數(shù)遍歷出來即可進(jìn)行相關(guān)的處理操作。


AMD規(guī)范
AMD (asynchronous module definition)異步模塊定義,使用異步方式加載模塊,模塊的加載不影響它后面語句的執(zhí)行,所有依這個(gè)模塊的語句,都需要定義在一個(gè)回調(diào)函數(shù)中,回調(diào)函數(shù)中使用模塊的變量和函數(shù),等模塊加載完成之后,這回調(diào)函數(shù)才執(zhí)行,就可以安全的使用模塊中的資源了。其實(shí)現(xiàn)就是AMD/requireJS.AMD雖然是異步,但是會預(yù)先加載和執(zhí)行。


CMD(Common Module Defintion),使用seajs,作者是淘寶前端玉伯,兼容并解決了requirejs的問題,CMD推崇as lazy as possible,盡可能的懶加載。

2 ES6模塊中的導(dǎo)入

import語句,導(dǎo)入另一個(gè)模塊導(dǎo)出的綁定

export語句,從模塊中導(dǎo)出函數(shù),對象,值等,供其他模塊import導(dǎo)入


創(chuàng)建兩個(gè)文件

1.js和2.js

1.js中寫入如下數(shù)據(jù)

//導(dǎo)出默認(rèn)類
export  default  ?class A {//此處設(shè)置默認(rèn)導(dǎo)出,可以導(dǎo)出類,函數(shù),變量和常量
    ????constructor(x){
    ????????this.x=x;
    ????}
    ????show()?{
    ????????console.log(this.x)
    ????}????
}
//導(dǎo)出函數(shù)?
export?var foo =()?=>console.log('foo?function')

//導(dǎo)出變量?
export??const?CONST='aaa';

2.js中進(jìn)行相關(guān)導(dǎo)入

如下

import {foo,CONST}  from  './1'; //此處若不指定./當(dāng)前目錄。則默認(rèn)是全局變量
import A from "./1";

let a=new A(10);
a.show();

foo();
console.log(CONST)

由于相關(guān)的引擎均不支持import 和export操作,因此需要通過相關(guān)的附加模塊來實(shí)現(xiàn)此種操作
上述中使用{}可以同時(shí)導(dǎo)入多個(gè)環(huán)境變量。

3 轉(zhuǎn)譯(label)

1 簡介

轉(zhuǎn)譯就是從一種語言代碼到另一個(gè)語言代碼,當(dāng)然可以使從高版本轉(zhuǎn)譯到低版本的支持語句。
由于JS存在不同的版本,不同瀏覽器的兼容問題可通過transpiler轉(zhuǎn)譯工具進(jìn)行解決,而babel就是其中的一種,官網(wǎng)如下
https://www.babeljs.cn

2 本地安裝label

1 需要生成package.json文件,用于編譯使用,可通過npm init 進(jìn)行初始化

JavaScript進(jìn)階

生成文件如下

JavaScript進(jìn)階

3 設(shè)置國內(nèi)鏡像,用于下載相關(guān)依賴包速度更快

.npmrc文件,此文件可通過touch .npmrc創(chuàng)建
可以放置到npm目錄下的npmrc文件中。也可以放置到用戶家目錄中,也可以放置到項(xiàng)目根目錄中,此處放置到項(xiàng)目根目錄,如下

registry=http://registry.npm.taobao.org

如下
JavaScript進(jìn)階

4 安裝

npm install  babel-core babel-cli  --save-dev

JavaScript進(jìn)階

相關(guān)參數(shù)說明

--save-dev 說明
當(dāng)你為你的模塊安裝一個(gè)依賴模塊時(shí),正常情況下你得先安裝他們(在模塊根目錄下npm install mode-name),然后連同版本號手動(dòng)將其添加到模塊配置文件package.json中的依賴中


--save 和--save-dev可以省略你手動(dòng)修改package.json文件的步驟。
npm install mode-name --save 自動(dòng)將模塊和版本號添加到dependencies部分,用于在打包至線上的依賴關(guān)系時(shí)使用
npm install mode-name --save-dev 自動(dòng)將模塊和版本號添加到devdependencise部分

查看package.json中的內(nèi)容

JavaScript進(jìn)階

5 準(zhǔn)備目錄

項(xiàng)目根目錄中創(chuàng)建src和lib目錄
src是源碼目錄;
lib是目標(biāo)目錄;

JavaScript進(jìn)階

6 配置 babel

在目錄根目錄下創(chuàng)建.babelrc文件,json格式,其babelrc是和babel運(yùn)行相關(guān)的
內(nèi)容如下

{
    "presets":["env"]
}

JavaScript進(jìn)階

7 修改配置文件package.json,確定轉(zhuǎn)換源和目標(biāo)

{
  "name": "test",
  "version": "1.0.0",
  "description": "from test",
  "main": "1.js",
  "scripts": {
    "build": "babel src -d  lib"
  },
  "author": "test",
  "license": "MIT",
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.3"
  }
}

此處是scripts中的修改,其若目標(biāo)為目錄,則為-d,若目標(biāo)為文件,則為-o。

8 準(zhǔn)備源文件

將1.js 和 2.js放置到src下

JavaScript進(jìn)階

9 安裝依賴

npm install  babel-preset-env --save-dev

JavaScript進(jìn)階

10項(xiàng)目根目錄執(zhí)行npm run build

npm run  build

JavaScript進(jìn)階
JavaScript進(jìn)階

轉(zhuǎn)換后的結(jié)果

JavaScript進(jìn)階

JavaScript進(jìn)階

運(yùn)行如下

JavaScript進(jìn)階

后期的通過webpack來實(shí)現(xiàn)所有的的聯(lián)動(dòng),自動(dòng)化的打包操作全部進(jìn)行處理。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

當(dāng)前文章:JavaScript進(jìn)階-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://muchs.cn/article14/dscjde.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊ChatGPT、App開發(fā)網(wǎng)站建設(shè)、品牌網(wǎng)站制作網(wǎng)站設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)