构造函数和原型 ES5

在 ES6 之前,对象不是基于类创建的,而是用一种称为 构造函数的特殊函数 来定义对象和他们的特性

创建对象可以通过以下三种方法:

  1. 对象字面量

    let obj1 = {} ;
  2. new Object()

    let obj2 = new Object();
  3. 自定义构造函数

    function Star(name,age){
    this.name = name;
    this.age = age;
    this.sing = function(){
    console.log('i can sing')
    }
    }
    let ldh = new Star('刘德华'18);
    let zxy = new Star('zxy',20);

new在执行的时 会做四件事情

  1. 在内存中 创建一个新的空对象
  2. 让this指向这个新的对象
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法
  4. 返回这个新对象( 所以构造函数里面不需要 return )

静态成员 与 实例成员

实例成员就是构造函数内部通过 this 添加成员 例如 name age 就是 实例成员

实例成员只能通过实例化的对象来进行访问

静态成员只能通过构造函数来访问

构造函数的问题

存在浪费内存的问题

构造函数原型 prototype

注: 构造函数通过原型分配的函数是所有对象所共享的

每一个构造函数都有 一个 prototype 属性 (原型对象),指向另一个对象,注意这个prototype 就是一个对象,这个对象所有的属性和方法都会被构造函数所拥有

注:我们可以把那些不变的方法,直接定义在prototype 对象上,这样所有的对象的实例就可以共享这些方法~

对象原形 proto

对象都会有一个属性__proto__指向构造函数的prototype原形对象,只所以我们对象可以使用构造函数 prototype原形对象上的属性和方法,就是因为对象有__proto__原形的存在

详解

function Star(name,age){
this.name = name;
this.age = age;
// this.sing = function(){
// console.log('i can sing')
// }
}
// 把公共方法挂到原型对象上
Star.prototype.sing = function () {
console.log('i can sing')
}


let ldh = new Star('刘德华'18);
let zxy = new Star('zxy',20);
console.log(ldh)//对象身上系统自己添加一个__proto__指向构造函数的prototype的原形对象上
console.log( ldh.__proto__ === Star.prototype) // true

constructor 构造函数

对象原形 proto 和 构造函数prototype 原形对象里面都有一个属性 constructor 属性,constructor我们成为构造函数,因为它指回构造函数本身

constructor 主要用于记录该对象引用哪个构造函数,它可以让原形对象重新指向原来的构造函数

console.log(Star.prototype.constructor);
console.log(ldh.__proto__.constructor);

原形链

原形对象函数里面的this指向的是实例对象ldh