所有分类
  • 所有分类
  • 后端开发
React学习必备:super是什么?为何关键?

React学习必备:super是什么?为何关键?

中的继承高级程序设计》一书中,给这种继承方式定义为「寄生组合式继承」。中实现继承始终就是要坚持一个原则:将实例属性放在构造函数中挂在this上,将一些方法属性挂在原型对象上,子类可共享。上面这种继承方式的关键在于两点:中的继承

最近大家都在聊 React,还老提到 “super”,看起来有点儿难懂。这到底是个啥玩意儿呀?

可能,同学会不会误会了?以为咱们这儿说的“超级”就是找爹地(父类)构造函数。千万别漏掉,给构造函数加点超级(super),否则程序就不对头咯。

原因很简单因为子类得告诉祖宗构造函数关于自个儿 this 对象的事儿,让祖宗心里有底。这就搞定了,咱们就可以把自家的个性加进去!要是不安特地叫 super,那还怎么拿到这个 this 对象?

// Shape - 父类(superclass)
function Shape() {
 this.x = 0;
 this.y = 0;
}
// 父类的方法
Shape.prototype.move = function(x, y) {
 this.x += x;
 this.y += y;
 console.info('Shape moved.');
};
// Rectangle - 子类(subclass)
function Rectangle() {
 Shape.call(this); // call super constructor.
}
// 子类续承父类
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?',
 rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
 rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'

你知道吗?ES6居然把这对象给改了跟以前可大不相同咯!有没有想起咱们那时研究的那本讲JS的书《JavaScript高级程序设计》里提到过的“寄生组合式继承”?这个概念就是在构造函数里面加上属性,然后和this捆绑起来;至于函数,就在 prototype上放着,这样子无论怎样继承,都是共享一份数据哟。

咱们该咋办?就让子类一开始就按着apply或call来模仿老妈的初始化方法呗。这么一搞,就像克隆一样,把老爸的程序整个搬过来。然后,用个新的招式——Object.create(Child.prototype),就好了。其实就是让Child.prototype跟Parent.prototype成为亲戚关系(让原型链从子类上去到老爸那儿)。

急性子先别急,ES6给继承搞舒服多了!增新了个extends代替老掉牙的super。而且连函数都可以是class。或许你觉得麻烦,但实际上,就跟平时咱们用的那些语法糖差不多。那么,怎么弄?跟着babel学学看呗。

class Point {
 constructor(x, y) {
  this.x = x;
  this.y = y;
 }
 toString() {
  return '(' + this.x + ', ' + this.y + ')';
 }
}
class ColorPoint extends Point {
 constructor(x, y, color) {
  super(x, y); // 调用父类的constructor(x, y)
  this.color = color;
 }
 toString() {
  return this.color + ' ' + super.toString(); 
 }
}

嘿。看看这个,这就是Babel帮我们做的事,只要搞懂几个重点就没问题了!

React学习必备:super是什么?为何关键?

这个规则是强调了构造函数要用“new”才能调用!

var ColorPoint =
/*#__PURE__*/
function (_Point) {
 _inherits(ColorPoint, _Point);
 function ColorPoint(x, y, color) {
  var _this;
  _classCallCheck(this, ColorPoint);
  _this = _possibleConstructorReturn(this, _getPrototypeOf(ColorPoint).call(this, x, y)); // 调用父类的constructor(x, y)
  _this.color = color;
  return _this;
 }
 _createClass(ColorPoint, [{
  key: "toString",
  value: function toString() {
   return this.color + ' ' + _get(_getPrototypeOf(ColorPoint.prototype), "toString", this).call(this);
  }
 }]);
 return ColorPoint;
}(Point);

其实,就是先把现在这东西弄到手(’this’),然后给下一代接着用。这样下一代就能借着我们的文化遗产和个人本领,直接搞出点新鲜事儿咯!

如果这么做,那么子类中的 `this` 就不见了,绝对会搞砸的

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      writable: true,
      configurable: true
    }
  });
  if (superClass) _setPrototypeOf(subClass, superClass);
}

好了,现在得给属性和方法找个新家!要是构造函数里的原型属性,直接把它们安在构造函数的原型上就行;至于那些静态属性和方法,直接交给构造函数就完事了!

ColorPoint.__proto__ === Point;
ColorPoint.prototype.__proto__ === Point.prototype;

你是不是在好奇为什么类里面总要有个”超级”?其实这货能让我们享用之前那个类的特色和方法,然后再发挥点儿我们自己的创新,简直就是绝配!有了它,继承就变得轻而易举了,棒极了!这下明白了?下次可别忘了把”超级”加到类中,这样继承起来才更加轻松。还是不懂的话?赶紧问,咱们立刻解决!别忘了顺便点个赞或转下贴子这样我会更有劲儿滴

function _classCallCheck(instance, Constructor) {
 if (!_instanceof(instance, Constructor)) {
   throw new TypeError("Cannot call a class as a function");
 }
}

原文链接:https://www.icz.com/technicalinformation/web/2024/03/11336.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?