原型和继承
- constructor存在于prototype原型中,指向构建函数的引用
设置原型的方法:
1.使用 setPrototypeOf 与 getPrototypeOf 获取与设置原型
2.使用Object.create创建一个新对象时,使用现有对象做为新对象的原型对象,可以使用第二个参数设置新对象的属性
3.使用 __proto__ 设置对象的原型
__proto__ 内部使用getter/setter 控制值,所以只允许对象或null
创建对象的方法:
1.使用对象的 constructor 创建对象
2.直接 new 一个
一、构造函数
构造函数的原型对象中包含属性 constructor 指向该构造函数
所以,可以通过以调用一个实例中的constructor属性,来实例化另一个新对象
但若直接设置了构造函数的运行,将导致constructor 丢失
所以,必须保证原型中的 constructor指向构造函数
二、继承
继承实现
(Admin和Member分别继承User)
方法重写:
三、深挖继承
继承的本质是将原型指向到另一个对象,this 不受原型继承影响,this 指向调用属性时使用的对象。
因此使用 call/apply 为每个生成的对象设置属性
使用原型工厂,将继承的过程封装,其本质仍旧是指定原型
在原型继承基础上,将对象的生成使用函数完成,并在函数内部为对象添加属性或方法:
(以下代码未 Admin 和 member 两个类继承User 并定义新的方法)
四、类
class的底层实现机制依旧是原型继承,只是通过语法糖使声明更加简洁
在类中,是使用 constructor 构造函数传递参数,并且会在 new 时自动执行
下例中show为构造函数方法,getName为原型方法
类 本质仍旧是个 函数
即
等同于
类的静态属性与静态方法:
静态属性:
即为类设置属性,而不是为生成的对象设置 其原理如下:
但在class中,添加static关键字即可
静态方法:
指通过类访问不能使用对象访问的方法,比如系统的Math.round()就是静态方法 在class中,同样添加static关键字即可
但其原理为:
访问器:
就是在函数前加上 get/set 修饰 ,但使用时仍旧是以属性的形式使用
访问控制:
(1)public
指不受保护的属性,在类的内部与外部都可以访问到
(2)protected
是受保护的属性修饰,不允许外部直接操作,但可以继承后在类内部访问,有以下几种方式定义
a.命名保护:将属性定义为以 _ 开始,来告诉使用者这是一个私有属性,请不要在外部使用。
但这只是提示,就像吸烟时烟盒上的吸烟有害健康
b.Symbol:使用 Symbol定义私有访问属性,即在外部通过查看对象结构无法获取的属性
//Symbol相关知识:
Symbol用于防止属性名冲突而产生的,比如向第三方对象中添加属性时
Symbol的声明和访问使用 [ ] 形式操作
const protecteds = Symbol(); class Common { constructor() { this[protecteds] = {}; this[protecteds].host = "https://houdunren.com"; } set host(url) { if (!/^https?:/i.test(url)) { throw new Error("非常网址"); } this[protecteds].host = url; } get host() { return this[protecteds].host; } } class User extends Common { constructor(name) { super(); this[protecteds].name = name; } get name() { return this[protecteds].name; } } let hd = new User("后盾人"); hd.host = "https://www.hdcms.com"; // console.log(hd[Symbol()]); console.log(hd.name);
(3)private:指私有属性,只在当前类可以访问到,并且不允许继承使用
为属性或方法名前加 # 为声明为私有属性,只能在声明的类中使用
五、类的继承
属性继承:
属性继承的原理如下,需要通过call来绑定当前对象,
因此在class中 子类构造函数中要先执行super
方法继承:
原生的继承主要是通过操作原型链实现
在class中,使用extend就可以实现
super:
表示从当前原型中执行方法,使用 super 调用时,在所有继承中 this 始终为调用对象
也就是说把查询原型方法的事情交给了 super,this 只是单纯的调用对象在各个继承中使用
但 super 只能在类或对象的方法中使用,而不能在函数中使用
super() 指调用父类的构造函数 super.sum()为调用父类方法
继承内置类:
使用原型扩展内置类时:
使用class扩展内置类时:
mixin:
mixin 类是一个包含许多供其它类使用的方法的类