精华内容
下载资源
问答
  • 今天小编就为大家分享一篇关于谈谈JavaScript中super(props)的重要性,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • 最近在开发见到了super,但是对这块不是很清楚,所以学习了一下,并进行一个小小的总结,方便自己再度加强记忆,也方便小伙伴们一起查询。 因为也是学习过程,如果文中有理解错误的地方,请评论区中指正,十分感谢...

    最近在开发中见到了super,但是对这块不是很清楚,所以学习了一下,并进行一个小小的总结,方便自己再度加强记忆,也方便小伙伴们一起查询。
    因为也是学习过程,如果文中有理解错误的地方,请评论区中指正,十分感谢

    1.super的概念

    在MDN中对super的定义如下:

    super关键字用于访问和调用一个对象的父对象上的函数。
    super.prop和super[expr]表达式在类和对象字面量任何方法定义中都是有效的。

    其实我理解就是super关键字可以用在类和对象里面,并且可用于访问父类/父对象构造函数和方法

    2.super的几种应用

    2.1 super在类中调用构造函数

    class Polygon {
        constructor(height, width) {
          this.name = 'Rectangle';
          this.height = height;
          this.width = width;
        }
        static sayName() {
          console.log('Hi, I am a ', this.name + '.');
        }
      }
      
      class Square extends Polygon {
        constructor(length) {
          // ReferenceError,super 需要先被调用!
            this.color = 'red'; 
          
          // 这里,它调用父类的构造函数的,  作为Polygon 的 height, width
          super(length, length);
          
          // 在这可以使用this,注意:在使用this之前, 必须先调用super()。
          this.color = 'red';
        }
      }
    

    在这里要强调的是:在构造函数中使用时,super必须在this之前使用,这点要牢记。

    这是因为:ES6的继承,需要先创建父类的this,子类调用super继承父类的this对象,然后再加工。

    换句话说,子类没有自己的this对象,而是继承父亲的this对象,然后进行加工。如果不调用super,子类就得不到this对象。

    2.2 super在类中调用静态方法

    class Rectangle {
        static logNbSides() {
          return 'I have 4 sides';
        }
      }
      
      class Square extends Rectangle {
        static logDescription() {
          return super.logNbSides() + ' which are all equal';
        }
      }
      console.log(Square.logDescription()); // 'I have 4 sides which are all equal'
    

    另外,使用super可以调用父类的静态方法。如同上面例子,可以调用父类的logNbSides静态方法

    2.3 super在对象中调用方法

      var obj1 = {
        method1() {
          console.log("method 1");
        }
      }
      
      var obj2 = {
        method2() {
         super.method1();
        }
      }
      //Object.setPrototypeOf() 将obj2的原型加到obj1上,然后才能够使用super调用obj1上的method1
      Object.setPrototypeOf(obj2, obj1);
      obj2.method2(); //  "method 1"
    

    在这个例子中,两个对象obj1obj2各定义了一个方法。在obj2中, 我们使用super调用了obj1中的方法。 注意:使用这种方法需要利用 Object.setPrototypeOf()obj2的原型加到obj1,然后才能够使用super调用 obj1上的method1。

    3. super和this的指向

    其实到这里,对于如何使用super就会有个大致了解,在日常开发也能够用,但是我觉得会用不行,还是得再深入了解,所以这里进一步分析super和this使用有什么不同。

    总结的说,this和super的指向如下:

    • this:指向函数所在的当前对象
    • super:指向当前对象的原型对象

    this指向对象,super指向原型对象
    接下来看几个例子:

    3.1 super简单应用

      var obj1 = {
        method1() {
          console.log("method 1");
        }
      }
      
      var obj2 = {
        method2() {
         super.method1();
        }
      }
      //Object.setPrototypeOf() 将obj2的原型加到obj1上,然后才能够使用super调用obj1上的method1
      Object.setPrototypeOf(obj2, obj1);
      obj2.method2(); //  "method 1"
    

    这个例子在2.3中已经见过了,再度拿出来就是为了解释为什么要用Object.setPrototypeOf,因为super是指向当前对象的原型对象,也就是当在obj2中使用super.method1()实际上是调用obj2.prototype.method1(),但是obj2的原型链上没有Method1方法,所以将obj2的原型加到obj1上面,这样就可以调用到原型链上的方法。

    3.2 super中this的指向

    const obj1 = {
    	method:'method1',
    	methods(){
    		return this.method;
    	}
    }
    
    const obj2 = {
    	method:'method2',
    	sayMethods(){
    		return super.methods();
    	}
    }
    
    Object.setPrototypeOf( obj2, obj1 );
    
    console.log(obj2.sayMethods())
    

    想想这个结果是什么?

    答案是:‘method2’

    这个结果说明了虽然super指向原型对象的methods方法,但是this还是绑定在当前obj2对象.

    再看一个例子:

    class obj1{		 
        constructor(x,y) {
            this.x = x;
            this.y = y;
        }    
        name(){
            return this.y
        }    
    }
    
    class obj2 extends obj1{
        constructor(x,y){
            super(x,y);
        }   
        name(){
            return this.x
        }    
        task1(){
            return super.name();
        }    
        task2(){
            return this.name();
        }
    }
    
    let d = new obj2('hello','world');
    console.log(d.task1())	
    console.log(d.task2())
    

    结合上面例子,想想这个结果是什么?

    答案是:‘world’ ‘hello’

    原因和上面相同:使用super调用父类的name方法,执行return this.y的语句,但是this指向当前obj2对象的name方法,执行return this.x的语句

    通过这两个例子验证了上面所说的:

    • this:指向函数所在的当前对象,即this指向 obj2
    • super:指向当前对象的原型对象,即使用super可以调用父类/父对象

    3.3 super在静态和普通方法中的指向

    先看一个例子,猜猜是什么结果?

    class Rectangle {
        static logNbSides() {
          return 'this is static function';
        }
        logNbSides() {
            return 'this is normal function';
          }
      }
      
      class Square extends Rectangle {
        static logDescription() {
          return super.logNbSides();
        }
        logDescription() {
            return super.logNbSides();
          }
      }
    
      var description = new Square()
      console.log(Square.logDescription()); 
      console.log(description.logDescription()); 
    

    答案是:‘this is static function’ ‘this is normal function’

    这是因为 Square.logDescription()执行时,子类会调用静态方法,即执行的是static logDescription()方法,这时super指向的是原型链上构造函数方法,调用static logNbSides()的方法。

    description.logDescription()执行时,是实例进行调用,所以实例会调用普通的方法,即执行的是logDescription()方法,这是super指向的是原型链上实例方法,调用logNbSides()方法。

    简单理解:谁调用super就指向谁的原型链。Square是子类,调用时super指向子类原型链的构造函数;description是实例,调用时super指向实例原型链的方法。

    (至于为什么description为什么没有使用静态方法,这是因为New的实例不能使用静态方法,只能用普通的方法,详细请看JS每日一问中第8节 Class中的static继承)

    展开全文
  • js中super

    万次阅读 多人点赞 2018-09-12 22:27:30
    1.this和super的区别: this关键词指向函数所在的当前对象 super指向的是当前对象的原型对象 2.super的简单应用 const person = { name:'jack' } const man = { sayName(){ return ...

    1.this和super的区别:

    • this关键词指向函数所在的当前对象
    • super指向的是当前对象的原型对象

    2.super的简单应用

    const person = {
    	name:'jack'
    }
    
    const man = {
    	sayName(){
    		return super.name;
    	}
    }
    
    Object.setPrototypeOf( man, person );
    
    let n = man.sayName();
    
    console.log( n )	//jack
    

    3.super的另类实现

    super.name  
    等同于   
    Object.getPrototypeOf(this).name【属性】  
    等同于   
    Object.getPrototypeOf(this).name.call(this)【方法】
    

    4.super中的this指向(易混淆)

    super.name指向的是原型对象person 中的name,但是绑定的this还是当前的man对象。

    const person = {
    	age:'20多了',
    	name(){
    		return this.age;
    	}
    }
    
    const man = {
    	age:'18岁了',
    	sayName(){
    		return super.name();
    	}
    }
    
    Object.setPrototypeOf( man, person );
    
    let n = man.sayName();
    
    console.log( n )	//18岁了
    
    

    Object.getPrototypeOf(this).name指向的是person的name,绑定的this也是person

    const person = {
    	age:'20多了',
    	name(){
    		return this.age;
    	}
    }
    
    const man = {
    	age:'18岁了',
    	sayName(){
    		return Object.getPrototypeOf(this).name();
    	}
    }
    
    Object.setPrototypeOf( man, person );
    
    let n = man.sayName();
    
    console.log( n )		//20多了
    

    Object.getPrototypeOf(this).name.call(this)指向的是person的name,不过通过call改变了函数的执行上下文,所以this指向的还是man

    const person = {
    	age:'20多了',
    	name(){
    		return this.age;
    	}
    }
    
    const man = {
    	age:'18岁了',
    	sayName(){
    		return Object.getPrototypeOf(this).name.call(this)
    	}
    }
    
    Object.setPrototypeOf( man, person );
    
    let n = man.sayName();
    
    console.log( n )	//18岁了
    
    

    4.Class中的super

    (1)Class中的 super(),它在这里表示父类的构造函数,用来新建父类的 this 对象

    super()相当于Parent.prototype.constructor.call(this)

     class Demo{
    			 
    	 constructor(x,y) {
    	     this.x = x;
    		 this.y = y;
    	 }
    	 
    	 customSplit(){
    		 return [...this.y]
    	 }
    	 
     }
     
     class Demo2 extends Demo{
    	 constructor(x,y){
    		 super(x,y);
    	 }
    	 
    	 customSplit(){
    	 	return [...this.x]
    	 }
    	 
    	 task1(){
    		 return super.customSplit();
    	 }
    	 
    	 task2(){
    	 	return this.customSplit();
    	 }
     }
     
     let d = new Demo2('hello','world');
     d.task1()	//["w", "o", "r", "l", "d"]
     d.task2()	//["h", "e", "l", "l", "o"]
    

    (2)子类没有自己的this对象,而是继承父亲的this对象,然后进行加工。如果不调用super,子类就得不到this对象

    class Demo2 extends Demo{
    	constructor(x,y){
    		 this.x = x;		//this is not defined
    	 }
     }
    

    ES5的继承,实质上是先创造子类的实例对象this,然后再将父类的方法添加到this上(Parent.call(this)).
    ES6的继承,需要先创建父类的this,子类调用super继承父类的this对象,然后再加工。

    如果子类没有创建constructor,这个方法会被默认添加:

    class Demo{ 
    	 constructor(x) {
    	   this.x = x;
    	 }
    }
    
    class Demo2 extends Demo{}
    
    let d = new Demo2('hello');
    
    d.x 		//hello
    

    (3) super 在静态方法之中指向父类,在普通方法之中指向父类的原型对象

    class Parent {
    	static myMethod(msg) {
    		console.log('static', msg);
    	}
    	myMethod(msg) {
    		console.log('instance', msg);
    	}
    }
    class Child extends Parent {
    	static myMethod(msg) {
    		super.myMethod(msg);
    	}
    	myMethod(msg) {
    		super.myMethod(msg);
    	}
    }
    
    Child.myMethod(1); // static 1
    
    var child = new Child();
    child.myMethod(2); // instance 2
    
    展开全文
  • javascript中super

    2015-12-25 16:54:43
    uber是德语的super的意思,因为superjavascript的保留字,所以使用德语的super。 用这种方式使用super,感觉还是好恶心 /* Isolating the inheritance part into a function */ function extend(Child...
    /* Uber – access to the parent from a child object */
    function Shape() { }
    Shape.prototype.name = 'Shape';
    Shape.prototype.toString = function() {
        var uber = this.constructor.uber;
        return uber ? uber.toString() + ', ' + this.name : this.name;
    };
    
    function Shape2D() { }
    function A() { }
    A.prototype = Shape.prototype;
    Shape2D.prototype = new A();
    Shape2D.prototype.constructor = Shape2D;
    Shape2D.uber = Shape.prototype;
    Shape2D.prototype.name = 'Shape 2D';
    
    function Triangle(side, height) {
        this.side = side;
        this.height = height;
    }
    function B() { }
    B.prototype = Shape2D.prototype;
    Triangle.prototype = new B();
    Triangle.prototype.constructor = Triangle;
    Triangle.uber = Shape2D.prototype;
    Triangle.prototype.name = 'Triangle';
    Triangle.prototype.getArea = function() {
        return this.side * this.height / 2;
    }
    
    // test
    var t = new Triangle(10, 10);
    console.log(t.getArea());
    console.log(t.toString());      // 输出 Triangle
    
    var s = new Shape();
    console.log(s.toString());      // 输出 Shape
    
    var s2d = new Shape2D();
    console.log(s2d.toString());    // 输出 Shape 2D
    


    uber是德语的super的意思,因为super是javascript的保留字,所以使用德语的super。

    用这种方式使用super,感觉还是好恶心


    /* Isolating the inheritance part into a function */
    function extend(Child, Parent) {
        var F = function() { };
        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor = Child;
        Child.uber = Parent.prototype;
    }
    
    function Shape() { }
    Shape.prototype.name = 'Shape';
    Shape.prototype.toString = function() {
        var uber = this.constructor.uber;
        return uber ? uber.toString() + ', ' + this.name : this.name;
    }
    
    function Shape2D() { }
    extend(Shape2D, Shape);
    Shape2D.prototype.name = 'Shape 2D';
    
    function Triangle(side, height) {
        this.side = side;
        this.height = height;
    }
    extend(Triangle, Shape2D);
    Triangle.prototype.name = 'Triangle';
    Triangle.prototype.getArea = function() {
        return this.side * this.height / 2;
    }
    
    // test
    var t = new Triangle(10, 10);
    console.log(t.toString());
    

    把继承部分封装到extend函数中,看起来清晰了很多

    展开全文
  • js super

    千次阅读 2016-01-20 10:38:08
    The super keyword is used to call functions on an object's parent. The super.prop and super[expr] expressions are valid in any method definition in both classes andobject literals. ...

    The super keyword is used to call functions on an object's parent.

    The super.prop and super[expr] expressions are valid in any method definition in both classes andobject literals.

    Syntax

    super([arguments]); // calls the parent constructor.
    super.functionOnParent([arguments]);
    

    Description

    When used in a constructor, the super keyword appears alone and must be used before the thiskeyword can be used. This keyword can also be used to call functions on a parent object.

    Example

    Using super in classes

    This code snippet is taken from the classes sample (live demo).

    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) {
        this.height; // ReferenceError, super needs to be called first!
        
        // Here, it calls the parent class' constructor with lengths
        // provided for the Polygon's width and height
        super(length, length);
        
        // Note: In derived classes, super() must be called before you
        // can use 'this'. Leaving this out will cause a reference error.
        this.name = 'Square';
      }
    
      get area() {
        return this.height * this.width;
      }
    
      set area(value) {
        this.area = value;
      } 
    }

    Super-calling static methods

    You are also able to call super on static methods.

    class Human {
      constructor() {}
      static ping() {
        return 'ping';
      }
    }
    
    class Computer extends Human {
      constructor() {}
      static pingpong() {
        return super.ping() + ' pong';
      }
    }
    Computer.pingpong(); // 'ping pong'

    Deleting super properties will throw

    You can not use the delete operator and super.prop or super[expr] to delete a parent class' property, it will throw a ReferenceError.

    class Base {
      constructor() {}
      foo() {}
    }
    class Derived {
      constructor() {}
      delete() {
        delete super.foo;
      }
    }
    
    new Derived().delete(); // ReferenceError: invalid delete involving 'super'.

    Super.prop can not overwrite non-writable properties

    When defining non-writable properties with e.g. Object.definePropertysuper can not overwrite the value of the property.

    class X {
      constructor() {
        Object.defineProperty(this, "prop", {
          configurable: true,
          writable: false, 
          value: 1
        });
      } 
      f() { 
        super.prop = 2;
      }
    }
    
    var x = new X();
    x.f();
    console.log(x.prop); // 1

    Using super.prop in object literals

    Super can also be used in the object initializer / literal notation. In this example, two objects define a method. In the second object, super calls the first object's method. This works with the help ofObject.setPrototypeOf() with which we are able to set the prototype of obj2 to obj1, so that super is able to find method1 on obj1.

    var obj1 = {
      method1() {
        console.log("method 1");
      }
    }
    
    var obj2 = {
      method2() {
       super.method1();
      }
    }
    
    Object.setPrototypeOf(obj2, obj1);
    obj2.method2(); // logs "method 1"
    展开全文
  • js中super小结

    千次阅读 2019-04-30 01:59:41
    1.this和super的区别: this关键词指向函数所在的当前对象 super指向的是当前对象的原型对象 2.super的简单应用 const person = { name:'jack' } const man = { sayName(){ return super.name; } } ...
  • JavaScript super关键字

    2020-08-31 07:46:07
    When we work with classes in JavaScript, it’s common to use the super keyword. 当我们使用JavaScript处理类时,通常使用super关键字。 In this post I want to clarify what’s it useful for. 在这篇...
  • super关键字既可以作为一个函数调用(Base.call(this, args...)),作为函数时,super()只能用在子类的构造函数之,用在其他地方就会报错。 此外,阮一峰老师认为super()函数在ES6用来为类构造一个this指针,但...
  • js中class继承和super

    千次阅读 2019-04-22 20:53:59
    js中class继承和super1.class的简单介绍2.class的继承 1.class的简单介绍 先看一段构造函数的代码 function Person(name,age) { this.name = name; this.age=age; } Person.prototype.say = function(){ return ...
  • 我们先研究下prototypejs是如何做到$super,后面再看我们能不能改造它,让$super更像javasuper关键字。 在OOP语言(如java),如果子类Child继承父类Base,那么编写某个子类方法的需求,无外乎下面几个: 1.子类...
  • JS超级定时器 一个纯 JavaScript 计时器,用于为给定事件倒计时小时、分钟和秒。 它适用于 UNIX 时间戳,即您将timestamp变量 UNIX 时间戳值赋予您想要倒计时的日期。 然后脚本将此时间戳乘以 1000 以将其转换为毫秒...
  • javascript中this和super用法

    千次阅读 2014-08-03 20:17:46
    所以,如果super是个变量,也指向当前对象,那么,不管super的静态类型是什么super.method()必然调用的是子类的那个版本,而不会是我们期望的,静态地选择父类的那个版本。 所以,你只要把super.xxx看成一个...
  • 要将videojs-super-resolution包含在您的网站或Web应用程序,请使用以下任何一种方法。 [removed]标记 这是最简单的情况。 以您喜欢的任何方式获取脚本,并在包含之后添加,以使videojs全局可用。 < script ...
  • js代码-SuperSelect

    2021-07-16 16:39:04
    js代码-SuperSelect
  • js class super 的用法

    2019-11-29 09:49:41
    super这个关键字,既可以当作函数使用,也可以当作...子类没有写constructor方法,js引擎默认,帮你执行constructor(){ super() } 第二种情况,super作为对象时,在普通方法,指向父类的原型对象;在静态方法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 144,971
精华内容 57,988
关键字:

js中的super