Javascript ES6 Class继承的原理

1. 前言

ES6新增的Class(类)给我们编程带来了极大方便,有人说这实际上是函数的语法糖,我是赞同的,但词法作用域和原型链是Javascript的核心思想,Class是基于原型链实现的,函数也是基于原型链实现的,这两者必然有一些共性,甚至使用 typeof 类标识符考察类到底是一个什么东西?控制台会告诉你这是一个function。然而,Class作为一个新特性,它有函数该有的东西,它也有函数没有的东西,这是它强大的地方。

2. Class本质上是一个特别的函数

    class Polygon {
        constructor(height, width) {
            this.name = 'Polygon';
            this.height = height;
            this.width = width;
        }
        sayName() {
            console.log('Hi, I am a ', this.name + '.');
        }
    }

    class Square extends Polygon {
        constructor(length) {
            super(length, length);
            this.name = 'Square';
        }

        get area() {
            return this.height * this.width;
        }

        set area(value) {
            this.area = value;
        }
    }
    var mySquare = new Square(4,4);

typeof Polygon //function   控制台输入typeof Polygon, 它会告诉你这是一个函数

console.dir(Polygon)  //反射查看Polygon类的属性

3. Class比函数多一根原型链

我们说函数supF是函数subF的父类,是因为subF.__protol__ = sup.prototype,即子函数的原型对象sub.prototype被链接到父函数supF的原型对象supF.prototype。但是两个父子函数supF和subF本身是独立的,没有任何关系,它们是靠原型对象关联到了一起。Class恰恰把这根链接上了。即子类自己的__protol__指向了父类。简单理解:extend关键字将类和类原型链接到了两根不同的链。

4. super伪引用

我们知道this绑定是动态绑定,super也是动态绑定的吗?super一定指向对象原型链的上级吗?类有两根原型链,那到底是哪根的上级呢?对于Javascript而言,没有类也是可以创建对象的,我们可以使用Object.setPrototypeOf(),随时将一个对象链接到另一个对象,这让super的指向更加复杂?其实也没那么复杂,如前言所讲,Javascript的核心思想:词法作用域链和原型链,函数被定义的位置和被调用的形式,这些能给你答案。

函数是一个独立的特殊对象,它可以作为对象的方法和普通对象(object)关联,这种关联仅仅是一种动态关系,谁也不依赖谁,谁也可以没有谁。但是函数被创建时关联的对象很重要,它是函数一出生就看见的对象,函数长大了,会飞了,换了很多环境生活,但是它的故乡只有一个,称为[[HomeObject]],它出生时就会用[[HomeObject]]记录这个故乡(对象)。

简单点说: super指向封闭函数定义的对象在原型链中的上级。

		class P {
			foo() {console.log("P.foo");}
		}

		class C extends P {
			//静态方法的[[HomeObject]]指向Class 
			//实例方法的[[HomeObject]]指向实例
			foo() {
				/*
				super指向主调函数foo.[[HomeObject]].[[prototype]]
				即定义函数的对象的原型链上级
				*/
				super.foo();

			}
		}
		var c1 = new C();
		c1.foo();
		var D = {
			foo: function() {
				console.log("D.foo");
			}
		};

		var E = {
			foo: C.prototype.foo
		};
		Object.setPrototypeOf(E,D);
		E.foo();

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值