啥是构造函数

其实说是构造函数,其实和函数没有区别,但是如果被new操作符来调用时,该函数则是一个构造函数。那么这个new到底有什么特殊的呢?

new操作符调用的作用

当一个函数被new操作符调用时,它会发生以下的操作

  1. 会在内存当中创造一个空的对象,
  2. 个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性
  3. 构造函数的this,会指向新创造出的对象
  4. 执行内部代码
  5. 并且自动返回
function Person(value, age) {
  this.name = value,
    this.age = age
  this.fun = function () {
    console.log(this.name + "在吃东西");
  }
}
var p1 = new Person("张三", 19)
var p2 = new Person("王五", 29)
p2.fun() //王五在吃东西
console.log(p1);//Person { name: '张三', age: 19, fun: [Function (anonymous)] }
console.log(p2);//Person { name: '王五', age: 29, fun: [Function (anonymous)] }

对象原型

JavaScript中每个对象都有一个特殊的属性[[proto ]],该属性会指向另一个对象

函数的原型

所有的函数都有一个prototype的属性

new操作符

当我们构造函数创造出来的对象
我们通过Person构造函数创建出来的所有对象的__proto__属性都指向Person.prototype:

function Person(){
    name:"12"
}
var  p1 = new Person()
Person.prototype.name="李四"
p1.name="张三"

// console.log(p1.name);
console.log(Person.prototype.constructor);

image.png

constructor属性

其实这个属性就是会指向自身的函数对象

重写原型对象

当我们需要在原型上添加过多的属性,这个时候我们就会整个对象

unction foo(){

}

foo.prototype={
    name:"老爹",
    age:"19",
    height:10
}
var p1 =new foo()

但是这样就会出现一个个问题,这个新对象的constructor属性, 会指向Object构造函数, 而不是Person构造函数。
我们可以手动进行添加

function foo(){

}

foo.prototype={
    name:"老爹",
    age:"19",
    height:10
}
var p1 =new foo()
// console.log(Object.getOwnPropertyDescriptors(p1.__proto__));
Object.defineProperty(foo.prototype,"constructor",{
value:foo,
writable:true,
enumerable:false,
configurable:true
})

console.log(p1);

构造函数+原型的组合

function foo(name, age, height) {
    this.name = name
    this.age = age
    this.height = height
}
foo.prototype.eat = function () {
    console.log(this.name + "吃东西");
}
var p1 = new foo("张三", 19, "22cm")
var p2 = new foo("李四", 29, "32cm")
p1.eat() //张三在吃东西
p2.eat() //李四在吃东西

Q.E.D.