类/原型与原型链
Contents
类
构造函数和普通函数
相同点:
定义的方式,都是通过function来定义
执行时参数传递方式一样
都会形成私有上下文,都有私有变量
不同点:
构造函数执行通过new
来执行,在执行时浏览器会在当前上下文中创建一个实例对象,并且会让函数中的this指向到这个实例对象中,而普通函数中的this指向为window。
函数如过没有返回值或返回值为基本类型值,则返回undefined
或你指定的返回值;如果是构造函数,它没有返回值,则返回当前的实例对象,如果有返回值,返回值是基本类型则也是返回当前对象,当返回的是引用类型,则返回你所指定的类型。
构造函数:箭头函数没有this,不能当构造函数,箭头函数没有prototype;ES6简写没有prototype;
原型与原型链
箭头函数没有prototype原型属性;ES6简写没有prototype;
每一个函数数据类型都自带一个prototype原型属性,属性值是一个对象,并且对象中自带一个属性为:constructor
,属性值是当前构造函数本身。
每一个对象数据类型都自带一个__proto__
原型链属性,属性值是所属类的prototype
原型对象。
prototype也是一个对象,每一个类new出来的实例对象从prototype原型对象中继承属性;对象中包含 __proto__
指向类的原型对象,原型中包含constructor
属性,指向构造函数。
原型链:在对象的私有属性中查找结果,如果私有中存在就是用私有的(优先级最高),如果不存在,则基于__proto__
找所属类prototype上的属性,再找prototype的 __proto__
上的属性,直到Object.prototype
为止,报错。原型链查找。
获取对象的原型方式:
|
|
Object.create()
:会创建一个空对象,基于传入的对象来创建,
获取与设置原型
|
|
原型重定向
原型重定向会引发constructor丢失,手动添加constructor属性,是可以通过for in枚举出来的,默认这个属性是不可以的。
设置对象属性不可枚举
|
|
原型检测
instanceof
检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,只要能找到则为真,检查对象是否属于某个类;使用isPrototypeOf
检测一个对象是否是另一个对象的原型链中;
在ES6以后,先查找当前对象是否有Symbol,通过 Symbol.hasInstance
方法,把要比较的对象放到此方法中,返回true/false。
|
|
原型扩展方法
可以实现链式写法、限定调取方法的类型,必须是指定类型的实例
继承
封装:类也是一个函数,把实现一个功能的代码进行封装,以此实现“低耦合高内聚”。
多态:重写: 子类重写父类上的方法(伴随着继承运行的); 重载: 相同的方法,由于参数或者返回值不同,具备了不同的功能(js中不具备严格意义上的重载)。
继承: 子类继承父类中的方法和属性。
方式:
原型继承 (让子类的原型 = 父类实例)、call继承(只能继承父类中私有的,不能继承父类中公共的)、寄生组合式继承(call继承 + 原型继承)、混合继承(间接实现多继承)
原型继承:把父类中的私有方法,都在子类中变成公有的,让子类的prototype = 父类。
call/apply继承:把父类当普通函数执行,所以prototype丢失,但是让this指向还要指向到当前的对象中。
Author Ankang
LastMod 2021-04-25