JavaScript构造函数和类的区别

原文

  • 构造函数
    • 没有显式的创建对象
    • 创建对象时使用new操作符。
    • 所有属性和方法赋值给this对象。
    • 没有return语句
    • 按照惯例,构造函数的方法名首字母应该使用大写字母,用于区分普通函数,其实构造函数也是函数,其主要功能是用来创建对象。
    • 每个构造函数都有一个原型属性prototype,该属性指向一个该构造函数的原型对象,原型对象中有一个constructor属性,该属性指向改构造函数;实例对象中包含一个指针([[Prototype]]),指向构造函数的原型对象,浏览器厂商给每个实例属性都加上了一个__**proto__**属性,用于获取构造函数的原型对象
    • 使用构造函数的缺点就是,每个方法都要在实例上重新创建一遍,如果我们根据Person构造函数创建两个实例,person1和person2都有一个sayName()的方法,但这两个方法是不同的Function的实例,因为Function也是对象,因此每定义一个函数,就会创建一个对象。
      • 解决方式:将共享属性和方法放到原型对象上。每个构造函数都有一个原型属性prototype,该属性指向一个包含该类型所有实例共享属性和方法的对象,即原型对象。
    • 类本身也指向构造函数,类似于一个语法糖,让对象原型更清晰,更加面向对象编程
    • 类里面有一个constructor方法,即构造方法;this关键字代表实例对象。也就是说ES5的构造函数Point,对应ES6的Point的构造方法。
    • 使用的时候,直接对类使用new命令,跟构造函数的用法完全一致,并且类必须用new调用,否则会报错
    • 类的所有方法都是定义在类的prototype属性上面。
    • 在类的实例上面调用方法,其实就是调用原型上面方法
    • prototype对象上面的constructor属性,直接指向‘类’本身,这与ES5的行为一致。
    • 类内部的方法都是不可枚举的。
    • 类里面必须有一个constructor方法,如果没有显示指定,将自动添加一个空的constructor方法,通过new命令生成对象实例时,自动调用该方法,默认返回实例对象this。
    • 实例属性除非显式定义在本身(即定义在this对象上),否则都定义在原型上,所有实例共享原型对象。
    • 可以使用get和set关键字,对某个属性设置存值函数与取值函数,拦截该属性的存取行为。
    • 类和模块内部默认是严格模式,不需要使用use strict指定运行模式。
    • 类不存在变量提升。
    • 类方法内部,如果含有this,它默认指向类的实例。
    • 静态方法:类相当于实例的原型,类中定义的方法都会被实例继承,如果在一个方法前加上static关键字,表示该方法不会被实例继承,而是通过类来调用,这就称为‘静态方法’。如果静态方法中包含this关键字,这个this指的是类,而不是实例。
    • 实例属性除了可以定义在constructor方法里面的this上面,还可定义在类的最顶层
    • 私有属性和私有方法:在属性和方法前面加上#,就表示私有属性或者方法,在内部调用时,要加上#
    • 继承:ES6中Class可以通过extends关键字实现继承,比ES5的通过原型链实现继承清晰和方便的多。
    • 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。
    • 在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错,这是因为子类实例的构建是基于父类实例的,只有super方法才能调用父类实例。
    • ES5的继承,实质上先创建子类的实例对象this,然后再将父类的方法添加到this上面(parent.apply(this))。ES6的继承机制完全不同,实质是先将父类实例对象的属性和方法加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。
    • Object.getPrototypeOf()方法可以用来从子类上获取父类,可以使用这个方法判断一个类是否继承了另一个类
    • 大多数浏览器的 ES5 实现之中,每一个对象都有proto属性,指向对应的构造函数的prototype属性。Class 作为构造函数的语法糖,同时有prototype属性和proto属性,因此同时存在两条继承链。
      (1)子类的proto属性,表示构造函数的继承,总是指向父类。
      (2)子类prototype属性的proto属性,表示方法的继承,总是指向父类的prototype属性。
    • 类声明不会提升
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值