构造函数

构造函数的概念

在典型的oop的语言中(如:java),都存在类的概念,类就是对象的模板,对象就是类的实例,但是es6之前,js中并没有引入类的概念

创建对象的3种方式

1.利用new Object() 创建对象

      var obj1 = new Object();

2.利用 对象字面量创建对象

      var obj2 = {};

3.利用构造函数创建对象

      function Star(uname,age) {
       this.uname = uname; 
       this.age = age;
       this.sing = function() { // 方法
       console.log(‘我会唱歌’)
    }   
   var ldh = new Star(‘刘德华’, 18) // 实例化

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋值初始值,它总是与new 一起使用,我们可以把对象中的一些公共的属性和方法抽取出来,然后封装到这个函数里

New 在执行时会做四件事情

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

构造函数中的属性和方法我们称为成员,成员可以添加

1.实例成员:构造函数内部通过this添加的成员(name,age,sing)

  // 实例成员只能通过实例化的对象来访问的
  console.log(ldh.uname);
  ldh.sing();
  // 不可以通过构造函数来访问实例成员
  console.log(Star.uname);  // undefined

2.静态成员: 在构造函数本身上添加的成员

Star.sex = ‘男’;  // sex就是静态成员
// 静态函数只能通过构造函数来访问,同样也不能通过对象形式访问
console.log(Star.sex);
console.log(ldh.sex); // undefined

构造函数虽然很好用,但是还是存在内存浪费的问题
因为,每创建一次新的对象就会开辟一新的内存空间,来存放同一个函数
解决方法:让所有的对象使用同一个函数

构造函数原型prototype

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

在原型上添加一个方法:

Star.prototype.sing(){
    console.log(‘我会唱歌’)
}
// 调用sing()方法
ldh.sing() // 我会唱歌
zxy.sing() // 我会唱歌

小结:一般情况下,我们的公共属性(uname,age)定义到构造函数里面,公共的方法(sing())我们放在原型对象身上

console.log(ldh) // 对象身上系统会给自己加一个__proto__指向我们构造函数原型对象prototype,
console.log(ldh.__proto__ === star.prototype) // true  // __proto__ 和prototype 是等价的

方法查找规则:首先从ldh对象身上 查找是否有sing方法,有就执行这个对象身上的sing
没有就找自己身上的__proto__属性,然后从__proto__属性找到构造函数的原型对象prototype身上查找sing()这个方法

__proto__和prototype

我们为了区分__proto__和prototype,我们把__proto__称为对象原型,prototype称为原型对象
__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者就说是一个线路,是一个非标准属性,在实际开发中不能使用这个属性,它只是内部指向原型对象prototype

constructor 构造函数

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

costructor 的作用:

    1.主要用于记录该对象引用哪个构造函数
    2.它可以让原型对象重新指向原来的构造函数

如果构造函数里面有很多方法,那么可以通过对象形式赋值给构造函数原型,在对象里面添加方法,但是会覆盖原来的实例,所以此时我需要手动的利用constructor这个属性来值回原来的构造函数

 Star.prototype = { 
          constructor:Star,
          sing: function() {
                 console.log(‘我会唱歌’)
                 },
          movie: function() {
                console.log(‘我会唱歌’)
                 }
      }
     console.log(Star.prototype.constructor)

小结:如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数,这样就知道我们的对象是通过哪个构造函数来创建出来的了

构造函数,实例,原型对象三者之间的关系

在这里插入图片描述

原型链:
在这里插入图片描述

this的指向:

在构造函数中,里面的this→对象实例
原型对象函数中,this→实例化对象
普通函数中,this→window
定时器,this→window
立即执行函数: this→window
事件处理函数中:this→事件触发对象
对象方法调用: this→该方法所属对象
在js中一般理解就是谁调用这个this就指向谁

call()

调用这个函数,并且修改函数运行时的this指向
语法:

fun.call(thisArg, arg1, arg2, ...)

thisArg: 当前调用函数this的指向对象
Arg1, arg2: 传递的其他参数

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值