文章目录
✨文章有误请指正,如果觉得对你有用,请点赞收藏关注一波,谢谢支持😘
前言
js中的原型毫无疑问一个难点,学习如果不掌握原理就容易晕!可能这时候懂,等几个小时过后再来写就很容易蒙,任何一个js知识点,比如学习事件流,闭包,继承等,对于这些知识点我们都应该先熟练原理,然后自己整理一套属于自己的理解说辞,才不会忘。
以下是个人学习JavaScript对象高级知识笔记(由浅入深)
一、对象创建模式
1、Object构造函数模式
- 套路: 先创建空Object对象, 再动态添加属性/方法
- 适用场景: 起始时不确定对象内部数据
- 问题: 语句太多
代码演示:
var p = new Object()
p = {}
p.name = 'Tom'
p.age = 12
p.setName = function (name) {
this.name = name
}
p.setaAge = function (age) {
this.age = age
}
console.log(p)
2、对象字面量
- 套路: 使用{}创建对象, 同时指定属性/方法
- 适用场景: 起始时对象内部数据是确定的
- 问题: 如果创建多个对象, 有重复代码
代码演示:
var p = {
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类型
代码演示:
function createPerson(name, age) {
var p = {
name: name,
age: age,
setName: function (name) {
this.name = name
}
}
return p
}
var p1 = createPerson('Tom', 12)
var p2 = createPerson('JAck', 13)
console.log(p1)
console.log(p2)
4.自定义构造函数模式
- 套路: 自定义构造函数, 通过new创建对象
- 适用场景: 需要创建多个类型确定的对象
- 问题: 每个对象都有相同的数据, 浪费内存
代码演示:
function Person(name, age) {
this.name = name
this.age = age
this.setName = function (name) {
this.name = name
}
}
var p1 = new Person('Tom', 12)
var p2 = new Person('Tom2', 13)
console.log(p1, p1 instanceof Person)
5.构造函数+原型的组合模式
- 套路: 自定义构造函数, 属性在函数中初始化, 方法添加到原型上
- 适用场景: 需要创建多个类型确定的对象
代码演示:
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function (name) {
this.name = name
}
var p1 = new Person('Tom', 12)
var p2 = new Person('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: 原型链继承
- 套路
- 定义父类型构造函数
- 给父类型的原型添加方法
- 定义子类型的构造函数
- 创建父类型的对象赋值给子类型的原型
- 将子类型原型的构造属性设置为子类型
- 给子类型原型添加方法
- 创建子类型的对象: 可以调用父类型的方法
- 关键
- 子类型的原型为父类型的一个实例对象
代码演示:
function parentFun() { //父类型
this.parenName= '我是父类型'
}
//原型的数据所有的实例对象都可见
parentFun.prototype.addParentFun1 = function () {
console.log(this.parenName)
}
function sonFun() { //子类型
this.sonName = '我是子类型'
}
// 子类的原型为父类的实例
sonFun.prototype = new parentFun()
// 修正sonFun.prototype.constructor为sonFun本身
sonFun.prototype.constructor = sonFun
sonFun.prototype.addSonFun1 = function () {
console.log(this.sonName)
}
// 创建子类型的实例
var newSonFun = new sonFun()
// 调用父类型的方法
newSonFun.addParentFun1() //我是父类型
// 调用子类型的方法
newSonFun.addSonFun1() //我是父类型
2.借用构造函数继承
方式2: 借用构造函数继承(假的)
- 套路
- 定义父类型构造函数
- 定义子类型构造函数
- 在子类型构造函数中调用父类型构造
- 关键
- 在子类型构造函数中通用super()调用父类型构造函数
代码演示:
function Person(name, age) {
this.name = name
this.age = age
}
function Student(name, age, price) {
Person.call(this, name, age) // this.Person(name, age)
this.price = price
}
var s = new Student('Tom', 20, 12000)
console.log(s.name, s.age, s.price)
3.组合继承
方式3: 借用构造函数的组合继承
- 套路
- 利用原型链实现对父类型对象的方法继承
- 利用call()借用父类型构建函数初始化相同属性
代码演示:
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function (name) {
this.name = name
}
function Student(name, age, price) {
Person.call(this, name, age) //得到父类型的属性
this.price = price
}
Student.prototype = new Person() //得到父类型的方法
Student.prototype.constructor = Student
Student.prototype.setPrice = function (price) {
this.price = price
}
var s = new Student('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高级对象的知识点,如有错漏之处,敬请指正”。