JavaScript 类的三部曲(一)

4 篇文章 0 订阅
3 篇文章 0 订阅

什么是构造函数和类

  • 构造函数与类其实是差不多的,说通俗点,类就是ES6版本的构造函数,而构造函数则是出现在ES6之前,ES5的类
  • 虽然我这样说可能有些不标准,但是通俗点可以这样理解

构造函数与类的共同点

我上面也讲到了,构造函数和类差不多,所以他们之间的共同点也是蛮多的

  • 构造函数与类都需要通过 new 来创建一个它们各自的实例对象
	// 创建一个构造函数
	function Con(x, y) {
      this.x = x;
      this.y = y;
    }
    // 在 Con 构造函数的原型上定义了一个 toStr 方法
    Con.prototype.toStr = function() {
      console.log('调用了toStr方法')
    }
    // 实例化 Con 构造函数
    let obj = new Con()

等同于

	// 创建一个类
	class Fun {
	  // 在类的 constructor 方法上定义了
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
      // 在 Con 类的内部定义了一个 toStr 方法
      toStr() {
        console.log('调用了toStr方法');
      }
    }
    // 实例化 Con 类
    let obj = new Con()
  • 看到这,有些小伙伴可能会有疑惑,为啥构造函数的方法需要定义在原型上,而类的方法不需要呢?
  • 因为定义在类内部的方法本身就在该类的原型上,别问我怎么知道的,因为我试过,不信看下面打印的结果:
	// 这块代码是对应上面所定义的 Con 类
	console.log(Con.toStr);   // undefined
  • 好,看到这里有些不懂的小伙伴可能又会问,你都没在方法后面加小括号,怎么可能会打印呢?
  • 既然你这么真情实意的问了,那我便大发慈悲的告诉你,加了小括号会报错,不信看下面的代码:
	console.log(Con.toStr())   // Uncaught TypeError: Fun.toStr is not a function
	// 不信你自己去试试,试试就知道我说的对不对了,如果我说的对的话,请你狠狠的给我点个赞吧
  • 上面说了类的方法即使是定义在类自己内部的,但却也是定义在原型上面的,因为只有通过原型去调用它,它才会打印
	// 注意了,注意了,这段代码也是对应最上面所定义的 Con 类的
	console.log(Con.prototype.toStr) // 打印 toStr 方法
	// 注意了,如果你已经通过 new Con() 得出了一个实例类的话,就不能这样写了
	console.log(obj.__proto__.toStr) // 打印 toStr 方法
	// 这两个打印出来的都是一样的,所以我们将它们相比较你会发现,它们打印的是 true
	console.log(Con.prototype.toStr === obj.__proto__.toStr) // true

注意:如果大伙觉得上下来回翻滚累的话,可以把最上面的类 copy 下来,放到你的编辑器里,这样方便阅读,如果是一个屏幕的小伙伴的话,第一步操作不变,copy 下来,然后 alt + tab 编辑器和文章之间来回切换

  • 大伙注意哈,我上面那段代码中,通过 new 得出来的实例对象是没有 prototype 的,为什么呢,这你就要去问JavaScript的开发者了,我也不知道,反正它就是没有
  • 但是呢,虽然没有 prototype 原型了,但是 new 出来的实例对象,它有一个 __proto__ 啊,__proto__prototype 本质上是一样的,它俩是全等的(这里看不懂的可以跳过)
  • 上面我们说了 obj.__proto__.toStr === Con.prototype.toStr,由此可得 obj.__proto__ === Con.prototype
	console.log(obj.__proto__ === Con.prototype)  // true
  • 既然已经说到这里了,那我就在给大家提一个注意点吧

  • 虽然 obj.__proto__ === Con.prototype,但是,它们俩里面的 toStr 方法却不全等哦

  • obj 直接调用 toStr 方法,得到的是 toStr 方法,但 Con 直接调用 toStr 方法的话,得到的并不是 toStr 方法
    在这里插入图片描述
    由上图可见,它俩既不全等,也不相等

  • 但是,obj.toStrCon.prototype.toStr 却是全等的哦

  • 好,到了这里,有小伙伴就要疑惑了,为什么它俩会全等呢?

  • 细心的小伙伴可能发现了,我上面说过类的方法虽然是定义在它内部的,但实则是在原型上的,既然是定义在原型上的,自然就需要通过 prototype 来调用了,否则怎么可能得到这个方法呢对吧

  • 好,又有小伙伴会有疑惑,那为啥 obj 不需要通过 __ptoto__来调用呢?

  • 因为 objCon 这个类 new 出来的实例对象,类里面的属性和方法它自然也有,当然,我这样解释你们可能会听不太懂哈,通俗点就是,obj 包含了 Con 这个类中所有的属性,以及 Con 原型上的方法

  • 也就是说,obj 在某种情况下,和 Con 是全等的

  • 既然 obj 拥有 toStr , 还是从 Con 身上得到的,那么两者的 toStr 方法自然是一样的,既然是一样的,肯定是全等的

	console.log(obj.toStr === Con.prototype.toStr)  // true
	console.log(obj.__proto__.toStr === Con.prototype.toStr)  // true

上面代码块中的第二行是什么意思呢?

大家不要着急,我来给大家解惑

  • obj 是 通过 new Con 得出来的实例对象是吧,那么我们暂时可以这样理解, obj === Con ,既然 obj === Con ,那么就解释的通了,obj.__proto__ === Con.prototypeCon 的原型上有 toStr 这个方法,所以obj 的原型上自然也有 toStr 这个方法了呀,所以可以通过 obj.__proto__.toStr 来调用 toStr 这个方法了

  • 我上面说过,某种情况下,obj 在某种情况下全等于 Con 对吧,说的就是这种情况

	console.log(obj.__proto__ === Con.prototype) // true

文章到这里也是接近尾声了,我在这里给大伙啰嗦两句吧,这是我的第一篇文章,我也不知道写的到底好不好,如果有不好或者不足的地方大伙可以在评论区提出来的,没关系的,当然,大伙如果觉得还可以的话,可以点点赞,收收藏啥的,对吧,毕竟谁会不喜欢自己的文章火呢

大伙可以加我一起交流哦,虽然我也不是很厉害
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值