01 静态成员和实例成员
构造函数中的属性和方法我们称之为成员 成员是可以添加的
通过构造函数new出来的对象叫做实例化对象
实例成员就是构造函数内部通过this添加的对象
实例成员只能通过实例化对象去访问 不能通过构造函数去访问
静态成员 是在构造函数本身上添加的成员 不能通过实例化对象去访问
02 原型对象
在构造函数里有prototype属性 也叫做原型对象 共享的方法都放到原型对象里面
原型是一个对象 我们称prototype为原型对象(构造函数的一个属性)
原型对象的作用是 共享方法 不需要开辟内存空间
一般情况下 我们把公共属性放到构造函数里面 公共方法放到我们的原型对象里面
03 对象原型
为什么实例化对象能使用构造函数的原型对象里面的方法呢?
因为对象里面有一个系统自带的属性__proto__ 指向了构造函数的原型对象
prototype原型对象
__proto__对象原型
指向的是构造函数的原型对象 但他是非标准的属性
在实际开发中 不可以使用这个属性 这个属性只是指明了一条路线
04 constructor
构造函数方法比较多的时候 往原型对象中添加 用对象的形式去写
如果我们修改了原型对象 给原型对象赋值了一个新对象的时候导致原来的constructor没有了
所以我们必须手动的利用constructor指回原来的构造函数
05 原型链
只要是对象就有__proto__属性 指向 原型对象
原型对象里面的__proto__指向的是Object.prototype(object的实例化对象)
object.prototype原型对象里面有__proto__指向的是null
这个链条就叫做原型链
原型链上面的成员查找规则是 就近原则
原型对象中的this指向实例化对象
06 call方法
call( ) 可以调用函数
call( ) 可以改变这个函数的this指向
- function fn(x,y){
- console.log('');
- console.log(this);
- console.log(x+y);
- }
-
- var obj={
- name:'狗蛋'
- }
-
- fn.call(obj,1,2)
- //以上调用 函数的this指向了obj这个对象 后面的就是普通参数
07 借用原型对象继承方法
- //父构造函数
- function Father(uname,age){
- this.uname=uname
- this.age=age
- }
- //能挣钱
- Father.prototype.money=function(){
- console.log(100000);
- }
- // 子构造函数
- function Son(uname,age,score){
- Father.call(this,uname,age)
- this.score=score
- }
-
- // Son.prototype=Father.prototype
- //因为这样赋值之后 两个原型对象的内存地址相同了 然后一改全改
- // 如果按照上面的直接赋值绘存在问题 子原型对象修改了 父原型对象也跟着修改了
-
- Son.prototype=new Father();
- //实例化了父构造函数 赋值给了子构造函数的原型对象
- // 父实例化对象可以访问父原型对象的方法 因为有__proto__的存在
- // 子实例化对象本身没有这个方法 去子构造函数的原型对象上面找 也没有 然后发现
- // 子原型对象指向了父的实例化对象 父的实例化对象有一个__proto__指向了父的原型对象
- // 然后父的原型对象上面有这个方法了 所以就可以继承了
- // 子构造函数有他自己的专门的方法
-
- Son.prototype.constructor=Son
- Son.prototype.exam=function(){
- console.log('孩子要考试');
- }
- var son=new Son('小黑',10,100)
- console.log(son);
- son.money()
- son.exam()
- console.log(Father.prototype);
- console.log(Son.prototype.constructor);