构造函数和原型 ES5
在 ES6 之前,对象不是基于类创建的,而是用一种称为 构造函数的特殊函数 来定义对象和他们的特性
创建对象可以通过以下三种方法:
对象字面量
let obj1 = {} ;
new Object()
let obj2 = new Object();
自定义构造函数
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在执行的时 会做四件事情
- 在内存中 创建一个新的空对象
- 让this指向这个新的对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象( 所以构造函数里面不需要 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