前言
js中的原型毫无疑问一个难点,学习如果不掌握原理就容易晕!可能这时候懂,等几个小时过后再来写就很容易蒙,任何一个js知识点,比如学习事件流,闭包,继承等,对于这些知识点我们都应该先熟练原理,然后自己整理一套属于自己的理解说辞,才不会忘。
以下是个人学习JavaScript对象高级知识笔记(由浅入深)
一、对象创建模式
1、Object构造函数模式
- 套路: 先创建空Object对象, 再动态添加属性/方法
- 适用场景: 起始时不确定对象内部数据
- 问题: 语句太多
代码演示:
varp=newObject() p= {} p.name='Tom'p.age=12p.setName=function (name) { this.name=name} p.setaAge=function (age) { this.age=age} console.log(p)
2、对象字面量
- 套路: 使用{}创建对象, 同时指定属性/方法
- 适用场景: 起始时对象内部数据是确定的
- 问题: 如果创建多个对象, 有重复代码
代码演示:
varp= { name: 'Tom', age: 23, setName: function (name) { this.name=name } } console.log(p.name, p.age) p.setName('JACK') console.log(p.name, p.age)
3.工厂模式
- 套路: 通过工厂函数动态创建对象并返回
- 适用场景: 需要创建多个对象
- 问题: 对象没有一个具体的类型, 都是Object类型
代码演示:
functioncreatePerson(name, age) { varp= { name: name, age: age, setName: function (name) { this.name=name } } returnp} varp1=createPerson('Tom', 12) varp2=createPerson('JAck', 13) console.log(p1) console.log(p2)
4.自定义构造函数模式
- 套路: 自定义构造函数, 通过new创建对象
- 适用场景: 需要创建多个类型确定的对象
- 问题: 每个对象都有相同的数据, 浪费内存
代码演示:
functionPerson(name, age) { this.name=namethis.age=agethis.setName=function (name) { this.name=name } } varp1=newPerson('Tom', 12) varp2=newPerson('Tom2', 13) console.log(p1, p1instanceofPerson)
5.构造函数+原型的组合模式
- 套路: 自定义构造函数, 属性在函数中初始化, 方法添加到原型上
- 适用场景: 需要创建多个类型确定的对象
代码演示:
functionPerson (name, age) { this.name=namethis.age=age} Person.prototype.setName=function (name) { this.name=name} varp1=newPerson('Tom', 12) varp2=newPerson('JAck', 23) p1.setName('TOM3') console.log(p1) Person.prototype.setAge=function (age) { this.age=age} p1.setAge(23) console.log(p1.age) Person.prototype= {} p1.setAge(34) console.log(p1)
二.对象的继承
1.原型链继承
方式1: 原型链继承
套路
定义父类型构造函数
给父类型的原型添加方法
定义子类型的构造函数
创建父类型的对象赋值给子类型的原型
将子类型原型的构造属性设置为子类型
给子类型原型添加方法
创建子类型的对象: 可以调用父类型的方法
关键
子类型的原型为父类型的一个实例对象
代码演示:
functionparentFun() { //父类型this.parenName='我是父类型'} //原型的数据所有的实例对象都可见parentFun.prototype.addParentFun1=function () { console.log(this.parenName) } functionsonFun() { //子类型this.sonName='我是子类型'} // 子类的原型为父类的实例sonFun.prototype=newparentFun() // 修正sonFun.prototype.constructor为sonFun本身sonFun.prototype.constructor=sonFunsonFun.prototype.addSonFun1=function () { console.log(this.sonName) } // 创建子类型的实例varnewSonFun=newsonFun() // 调用父类型的方法newSonFun.addParentFun1() //我是父类型// 调用子类型的方法newSonFun.addSonFun1() //我是父类型
2.借用构造函数继承
方式2: 借用构造函数继承(假的)
- 套路
- 定义父类型构造函数
- 定义子类型构造函数
- 在子类型构造函数中调用父类型构造
- 关键
- 在子类型构造函数中通用super()调用父类型构造函数
代码演示:
functionPerson(name, age) { this.name=namethis.age=age} functionStudent(name, age, price) { Person.call(this, name, age) // this.Person(name, age)this.price=price} vars=newStudent('Tom', 20, 12000) console.log(s.name, s.age, s.price)
3.组合继承
方式3: 借用构造函数的组合继承
- 套路
- 利用原型链实现对父类型对象的方法继承
- 利用call()借用父类型构建函数初始化相同属性
代码演示:
functionPerson(name, age) { this.name=namethis.age=age} Person.prototype.setName=function (name) { this.name=name} functionStudent(name, age, price) { Person.call(this, name, age) //得到父类型的属性this.price=price} Student.prototype=newPerson() //得到父类型的方法Student.prototype.constructor=StudentStudent.prototype.setPrice=function (price) { this.price=price} vars=newStudent('Tom', 12, 10000) s.setPrice(11000) s.setName('Bob') console.log(s) console.log(s.constructor)
4.new一个对象背后做了什么?
- new一个对象背后做了些什么?
- 创建一个空对象
- 给对象设置__proto__, 值为构造函数对象的prototype属性值 this.proto = Fn.prototype
- 执行构造函数体(给对象添加属性/方法)
三、总结
以上就是个人学习javaScript高级对象的知识点,如有错漏之处,敬请指正”。