记录一下前端学习笔记,每天打卡!!
目标:
必知必会: js | 布局样式 | 客户端 | 技术栈
加分项:工具(CI/CD等) 热门模块工程化
进阶:模式 实战/算法
实战项目统一模板:做完的项目都需要自己再思考下下面的模板
业务层:modules network adapter
工程化层 :webpack plugins output
基础:ci/cs util/e2e vue/react monitor
开始第二天知识学习
构造函数
- 函数体内的this,指向所要生成的实例
- 生成的对象用new来进行实例化
- 可以做初始化传参
追问:
- 如果构造函数不初始化,可以使用? - 无法正常使用
- 如果项目中需要使用,通常(不被外界感知)如何解决?
let staticProps
function Course(){
const _isClass = this instanceof Course
if(!_isClass){
staticProps = new Course()
return staticProps
}else{
return staticProps
}
this.teacher= teacher
this.course='oob'
this.startCourse = function (){
}
}
// 使用
const course = Course()
上述暴露出去的是实例,而将实例化的过程防止在下层不被外界感知
启发:如果写底层代码时,不需要让外界熟悉感知内部代码思想
延深:通过改进=>不多次实例化,同一个实例=>单例模式
思考:new是什么?new的原理/ mew的时候做了什么?
function Course(teacher,course){
this.teacher = teacher
this.course = course
}
const course1 = new Course('yy','oop')
const course2 = new Course('zz','js')
- 结构上,创建了一个空对象,作为返回的对象实例
- 属性上,将生成的对象的原型对象指向了构造函数的prototype属性
- 关系上,将当前实例对象赋值给了内部的this
- 声明上,构造函数初始化代码的执行
思考:constructor是什么?
- 每个对象在创建的时候,会自动拥有一个构造函数的属性constructor
- constructor继承自原型对象,指向了构造函数的引用=>实例获得了类的属性=>继承了类的属性
追问:使用构造函数没有问题吗?会有什么性能上的问题? 构造函数中的每一个方法和属性都 存在每一个实例中,重复挂载导致了资源浪费
如果初始化?原型对象又是什么?
- 构造函数:赋予一个属性prototype,该属性引用等于实例对象的__proto__;course1.proto === Course.prototype
- 实例对象:每一个实例对象都有一个constructor => 指向当前构造函数;course1.constructor === Course
- prototype是什么?
4. 上面的问题,如何优化? 将公有属性和方法,放在原型链上
function Course(teacher,course){
this.teacher = teacher
}
Course.prototype.course = course
const course1 = new Course('yy','oop')
const course2 = new Course('zz','js')
继承
- 原型链直接继承
function Game(){
this.name = 'lol'
this.skin = ['s']
}
Game.prototype.getName = function(){
return this.name
}
// LOL类
function LOL(){}
LOL.prototype = new Game()
LOL.prototype.constructor = LOL
const game1 = new LOL()
// 拓展
const game2 = new LOL()
game1.skin.push('ss')
上面原型链继承存在的问题:
- 父类属性一旦复制给子类的原型属性,此时属性属于子类的共享属性了
- 实例化子类实例的时候,无法像父类传参
解决方法:构造函数继承
- 构造函数继承:子类的构造函数内部调用父类的构造函数
function Game(arg){
this.name = 'lol'
this.skin = ['s']
}
Game.prototype.getName = function(){
return this.name
}
// LOL类
function LOL(arg){
Game.call(this,arg)
}
const game3 = new LOL('arg')
存在问题: 无法继承原型链上共享的方法
- 组合继承
function Game(arg){
this.name = 'lol'
this.skin = ['s']
}
Game.prototype.getName = function(){
return this.name
}
// LOL类
function LOL(arg){
Game.call(this,arg)
}
LOL.prototype = new Game()
LOL.prototype.constructor = LOL
const game4 = new LOL('arg')
追问:组合继承有什么问题?问题在于:无论在何种场景下,都会调用两次父类构造函数=>寄生组合继承
- 寄生组合继承,原生继承方法比较完美的方式
function Game(arg){
this.name = 'lol'
this.skin = ['s']
}
Game.prototype.getName = function(){
return this.name
}
// LOL类
function LOL(arg){
Game.call(this,arg)
}
LOL.prototype = Object.create(Game.prototype)
LOL.prototype.constructor = LOL
追问:如何实现多重继承? 本质是原型属性的合并
function Game(arg){
this.name = 'lol'
this.skin = ['s']
}
Game.prototype.getName = function(){
return this.name
}
function Store(arg){
this.shop = 'steam'
}
Store.prototype.getPlatform = function(){
return this.shop
}
function LOL(arg){
Game.call(this,arg)
Store.call(this,arg)
}
LOL.prototype = Object.create(Game.prototype)
Object.assign(LOL.prototype,Store.prototype)
LOL.prototype.constructor = LOL