最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 「查漏补缺」对比class与旧构造函数的区别

    正文概述 掘金(SwordQiu)   2020-12-28   305

    前言

    JavaScript是没有类这个概念的,区别于其他传统的强类型语言,例如Java,JS的类(构造函数)在设计根本上就有本质的不同,Java的类是代码的拷贝,而JS则用了原型链继承而已,所谓的构造函数只不过就是个普通函数,(只是大家习惯在使用时大写,这事也就成了规范)。

    ES6的class本质上是构造函数的语法糖,只是这个语法糖写得更像是Java,为了做区分,我将在这篇博客上专门对比class和es5构造函数的不同写法

    设置实例对象自身属性

    构造函数写法

    通过构造函数,我们能更了解JS的原型链设计原理,下面是构造函数的基本用法

    function Person(name,age){
       this.name=name
       this.age=age
    }
    const p=new Person('jack',23)
    

    class写法

    class Person{
       constructor(name,age){
          this.name=name
          this.age=age
       }
    }
    const p=new Person('jack',23)
    

    设置实例对象的共有方法

    构造函数写法

    Person.prototype={
       constructor:Person,
       fn1(){},
       fn2(){}
    }
    

    class写法

    class Person{
       constructor(name,age){
       ...
       };
       fn1(){};
       fn2(){};
    }
    

    设置实例对象的自有方法

    构造函数写法

    function Person(name,age){
    ...
       this.saiHi=function(){console.log(this.name)}
    }
    

    class写法

    class Person{
        name='';
        age='';
       constructor(name,age){
          ...
       };
       fn1(){};//prototype上的
       fn2(){};
       sayHi=function(){console.log(this.name)} //自有的
    }
    

    设置构造函数静态属性

    构造函数的静态属性指的是构造函数自己能访问

    构造函数写法

    Person.prop1='staticProp1'
    Person.prop2='staticProp2'
    

    class写法

    class Person{
       static prop1='staticProp1'
       static prop2='staticProp2'
       constructor(name,age){
          ...
       };
       fn1(){};//prototype上的
       fn2(){};
       sayHi=function(){console.log(this.name)} //自有的
    }
    

    设置构造函数静态方法

    构造函数写法

    Person.staticFn=function (){}
    

    class写法

    class Person{
    ...
       static staticFn=function(){}
       constructor(name,age){
          ...
       };
      ...
    }
    

    设置构造函数的私有字段

    构造函数写法

    function Person(name,age){
       let _selfName='123456' //构造函数私有属性,无法被外部直接访问
       let _selfFn=()=>{return _selfName} //构造函数私有方法,无法被外部直接访问
       this.saiHi=function(){console.log(_selfFn())} //实例的自有方法
    }
    

    在变量名前加_,这种写法是开发者自己定义的,用来区分一下私有字段

    class写法

    class Person{
       #selfName='123456'
       #selfFn=()=>{return this.#selfName}
       constructor(name,age){
          ...
       };
       sayHi=function(){console.log(this.#selfFn())}
    

    class写法采用#关键字符来定义,如果想访问,需要加上this

    由于私有字段无法直接访问,只好通过sayHi方法来变相访问了。

    小结

    构造函数写法

    function Person(name,age){
       let _selfName='123456' //构造函数私有属性,无法被外部直接访问
       let _selfFn=()=>{return _selfName} //构造函数私有方法,无法被外部直接访问
       this.name=name //实例的自有属性
       this.age=age
       this.saiHi=function(){console.log(_selfFn())} //实例的自有方法
    }
    Person.prototype={ //实例的共有方法
       constructor:Person,
       fn1(){},
       fn2(){}
    }
    Person.prop1='staticProp1' //构造函数的自有属性
    Person.prop2='staticProp2'
    Person.staticFn=function (){} //构造函数的自有方法
    const p=new Person('jack',23)
    

    class写法

    class Person{
        name='';//这里也可以写实例的属性
        age='';
       static prop1='staticProp1'//构造函数的自有属性
       static prop2='staticProp2'
       #selfName='123456'//构造函数私有属性,无法被外部直接访问
       #selfFn=()=>{return this.#selfName}//构造函数私有方法,无法被外部直接访问
       constructor(name,age){
          this.name=name//实例的自有属性
          this.age=age//实例的自有属性
       };
       fn1(){};//实例的共有方法
       fn2(){};//实例的共有方法
       sayHi=function(){console.log(this.#selfFn())}//构造函数的自有方法
    }
    const p=new Person('jack',23)
    

    继承

    构造函数写法

    采用构造函数方法可以分成两步实现。

    第一步是在子类的构造函数中,调用父类的构造函数。

    function Super(name){
       this.name=name
    }
    function Sub(age){
       Super.call(this)
       this.age=age
    }
    

    上面代码中,Sub是子类的构造函数,this是子类的实例。在实例上调用父类的构造函数Super,就会让子类实例具有父类实例的属性。

    第二步,是让子类的原型指向父类的原型,这样子类就可以继承父类原型。

    Super.prototype.sayHi=function (){console.log('hi')}
    Sub.prototype = Object.create(Super.prototype);
    Sub.prototype.constructor = Sub;//这句可加可不加,建议加
    

    要注意不要直接Sub.prototype=Super.prototype,这样虽然也是有用的,但是就相当于两个构造函数共用一个原型,万一以后修改Sub或者Super其中一个的原型就会影响双方。

    最好的方法就是使用Object.Create直接改造子构造函数的原型,让子构造函数的__proto__连接到父构造函数的原型上。

    class写法

    class Person{
        name;
        age;
        constructor(name,age){
            this.name=name
            this.age=age
        }
        sayHi(){
            console.log(this.name)
        }
    }
    class Man extends Person{
        constructor(name,age,prop){
            super(name,age)//这里调用
            this.prop=prop
        }
    }
    const a=new Man('qiuyanxi',20,'帅')
    

    class的形式非常方便,目前子类已经能使用父类的方法了,而且无需再去关联子类和父类的原型链,extends关键字已经帮我们做好了工作

    Man.prototype.__proto__===Person.prototype //true
    Man.__proto__ ===Person //true //注意,这是class自动实现的
    

    class方法比ES5的方法多一种关系,ES5的方法并没有把子类的__proto__跟父类做关联,而class的写法则是自动做了关联。不过如果ES5想要实现的话也可以用Object.setPrototypeOf(Man,Person)关联

    //传统ES5继承手动挡
    //原来
    Sub.__proto__ ===> Function.protoyype
    Super.__proto__ ===> Function.protoyype
    //使用Object.setPrototypeOf(Sub,Super)后
    Sub.__proto__ ===>Super===>Super.__proto__===>Function.prototype
    //使用Sub.prototype = Object.create(Super.prototype)后;
    Sub.prototype.__proto__ ===> Super.prototype
    

    总结

    class的语法从未来来看,更多的新人朋友们可能会非常喜欢,这也非常符合学过JAVA的科班生,不过Js跟Java之间的差别还挺大的,还是建议能够在实践class的基础上,了解构造函数的工作原理,这能够帮助我们更好地理解Js这门不完美但是非常优秀的语言

    参考文档

    wangdoc.com/javascript/…

    wangdoc.com/es6/class-e…

    developer.mozilla.org/zh-CN/docs/…


    起源地下载网 » 「查漏补缺」对比class与旧构造函数的区别

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元