Day18笔记
一、什么是构造函数
在JavaScript中,当一个函数创建好以后,我们并不知道它是不是构造函数,只有当一个函数用new关键字来调用的时候,我们才能称它时一个构造函数。
二、构造函数的语法
// 首字母需大写。
let Fn() {
this.属性 = 属性值,
this.say = function() { }
}
// 必须使用new关键字调用构造函数。
// 实例化构造函数,得到一个实例化对象p1。
let p1 = new Fn()
// 此时p1就可以调用构造函数中的属性及方法。
p1.属性/方法()
三、构造函数与普通函数的区别
- 构造函数也是一个普通函数,创建方式和普通函数一样,但构造函数首字母需大写。
- 调用方式不一样:
- 普通函数:直接调用 fn()
- 构造函数:需要使用new关键字来调用 new Fn()
- 构造函数的函数名与类名相同:Fn()这个构造函数,Fn既是函数名,也是这个对象的类名
- 构造函数的内部用this来构建属性和方法。
- 构造函数不需要定义返回类型(void是无需返回值的意思,请注意区分两者)。
普通函数
function Obj() { }
Obj.a = 0 // 静态变量
Obj.fn=function() { } // 静态函数
// 直接访问函数
console.log(Obj.a) => 0
console.log(typeof Obj.fn) => function
// new实例化函数
let p1 = new Obj()
console.log(p1.a) => undefined
console.log(typeof p1.fn()) => undefined
构造函数
function Obj() {
this.a = [] // 实例变量
this.fn = function(){ } // 实例方法
}
// 直接访问函数
console.log(Obj.a) => undefined
console.log(typeof Obj.fn()) => undefined
// new实例化函数
let p1 = new Obj()
p1.a.push(1)
p1.fn = { }
console.log(p1.a) => [1]
console.log(typeof p1.fn()) => object
let p2 = new Obj()
console.log(p2.a) => []
console.log(typeof p2.fn()) => function
四、构造函数的执行流程
- 当构造函数以new关键字调用时,会立刻在堆内存中创建一个新的内存空间(instance对象)。
- 此时内存空间(instance对象)内部的this指向该实例对象。
- 因为构造函数默认返回this,那么给this添加属性或者方法,就相当于给实例对象添加属性或者方法。
五、prototype原型对象
每当创建了一个新函数,都会为该函数创建一个prototype属性(原型对象)。通过同一个函数创建的实例对象都会从函数的prototype原型对象上继承属性。换句话说通过同一个类(构造函数)创建的所有实例对象,都从同一个原型对象上继承属性。
prototype原型对象与实例对象的创建没有关系,它在实例对象创建之前就已经存在。
当代码读取实例对象的某个属性的时候,先在实例对象中找,如果找到该属性则返回,如果没有则找到则从prototype原型对象中查找是否有该属性。
如果希望实例对象通用属性或方法则定义到prototype原型对象中,如果希望每个实例对象单独拥有属性或方法则定义到this中,可以通过构造函数传递实例化参数。
六、实例对象中的_ proto _
当使用new关键字调用构造函数创建一个实例对象的时候,实例对象内部将包含一个内部指针(很多浏览器这个指针名字为_ proto _ ), _ proto _指向构造函数的prototype,这个连接存在于实例对象和构造函数的prototype之间,而不是实例与构造函数之间。
实例对象.__proto__ === 构造函数.prototype === prototype原型对象
只有构造函数才有prototype属性,而构造函数的实例对象时没有该属性的,它只有_ proto _。每个函数都自动有一个prototype属性,而不是而一个对象都有prototype属性。
七、constructor构造函数
默认情况下prototype原型对象会默认获得一个constructor(构造函数)属性,这个属性是指向该prototype原型对象所在的构造函数的指针。
构造函数会继承prototype的属性,所以也会自动获得一个constructor属性,该属性正是指向构造函数(自己本身)。
构造函数会继承prototype的属性,所以也会自动获得一个constructor属性,该属性正是指向构造函数(自己本身)。