构造函数详解

构造函数

1. 工厂函数

// 工厂函数
function createObj(name,age){
  const obj = new Object()
  obj.name = name
  obj.age = age

  return obj
}

// 使用工厂函数创建对象
const obj1 = createObj("小明",11)
const obj2 = createObj("小红",12)

console.log(obj1);
console.log(obj2);

2. 构造函数

// 构造函数,构造函数一般首字母大写
function Fun(name,age){
  // 它的this是指向使用此构造函数创建的实例对象的
  // 定义属性
  this.name = name
  this.age = age

  // 定义函数
  // 定义函数会发现,在每当new一个实例对象的时候, 就会多一个函数, 但是其实每一个实例对象中的函数都是一样的, 一样的东西多次定义, 没有意义, 所以要在构造函数上定义方法, 使用原型是最好的
  // this.sayHi = function(){
  //   console.log("你好")
  // }
}

// 将函数定义到原型上, 可以避免每new一个实例对象,就生成一份一样的函数, 占用两个地址空间
Fun.prototype.sayHi = function(){
  console.log("你好"+this.name);
}

// new出实例对象
const fun1 = new Fun("tom",12)
const fun2 = new Fun("jack",13)

// 调用方法
fun1.sayHi()
fun2.sayHi()

// 总结: 构造函数,属性写在构造函数体内,方法写在原型方法中

3. 显式原型和隐式原型

  • 所有函数都有一个属性prototype, 这个属性指向一个空对象, 这个空对象, 叫做原型对象
  • 使用函数new出来一个对象, 这个函数被叫做构造函数, new出来的对象称为实例对象, 每个实例对象都有一个属性__proto__, 这个属性也指向原型对象
  • 构造函数的属性prototype(称为显式原型)和用它new出的实例对象的属性__proto__(称为隐式原型), 它们的指向是同一个原型对象
// 每一个函数(当有对象用此函数new出来时,这个函数就被称为构造函数)都自带一个属性prototype, 这个属性指向一个空对象, 也就是原型对象
function Fun(){
  this.name = "我的名字叫函数"
}

// 可以在原型对象上存入属性,方法,一般方法存的较多
Fun.prototype.age = 20
Fun.prototype.text = function(){
  console.log("text()");
}

// 使用Fun()函数还能new出对象
// 由Fun()构造函数构造出的实例对象
const fun = new Fun()

// 每个实例对象都有一个自带的属性,这个属性是__proto__, 这个属性也指向一个空对象, 也就是构造函数prototype指向的原型对象
console.log(fun.__proto__ === Fun.prototype); // true

// js为了方便访问,__proto__可以省略
// console.log(fun.__proto__.age); // 这种写法等于下一行的写法
console.log(fun.age)
fun.text()

// 总结: 构造函数有个prototype显式原型,用此构造函数new出的实例对象有个属性__proto__隐式原型, 两个属性指向同一个对象object(原型对象)

4. constructor

  • 对象的__proto__中有一个属性叫做constructor
  • 这个属性就是指向当前这个对象所属的构造函数
function Fun(){

}
Fun.prototype.name = "123"

const fun = new Fun()
console.log(Fun.prototype);

// 在原型对象的身上有个constructor属性, 指向的是构造函数本身
console.log(Fun.prototype.constructor === Fun); // true
console.log(fun.__proto__.constructor === Fun); // true
console.log(fun.constructor === Fun); // true

5. 原型链

// 构造函数
function Fun(){
}
Fun.prototype.age = 20

// 实例对象
const fun = new Fun()
fun.name = "小红"

// 获取元素流程
// 先找自身,是否有该对象
console.log(fun.name)
// 如果没有,则去自身原型对象上找
console.log(fun.age)
// 如果还没有,这去原型对象的原型对象上找,
console.log(fun.toString())
// 最后还没有找到就直接报错
// 这就是原型链, 我们一般说的原型链都是隐式原型链

// Fun原型对象的原型对象
console.log(Fun.prototype.__proto__)

// 在原型链中,Object的原型对象就是原型链的尽头
console.log(Object.prototype.__proto__); // null

6. 对象的赋值

  • 到这里,我们就会觉得,如果是赋值的话,那么也会按照原型链的规则来
  • 但是: 并不是!并不是!并不是! 重要的事情说三遍
  • 赋值的时候,就是直接给对象自己本身赋值
    • 如果原先有就是修改
    • 原先没有就是添加
    • 不会和 __proto__ 有关系
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值