2019-11-29:
Learning Content:
A, (1) class:
Examples of the conventional method of generating an object: Constructor
ES6 the class:
Generating instance of an object: var b = new Point (x, y)
Constructor prototype
property, continues to exist above the "class" of for ES6. In fact, all methods defined in the class are the class prototype
attributes :( following three methods above are the same)
(2) constructor method:
constructor
The method, which is the constructor, and this
keyword represents the instance of the object. constructor
The method returns an instance of a default object (i.e. this
), you can specify another object returned .
By new
generating a command object instance, the method is automatically invoked .
(3) instances of objects:
All instances of a class share a prototype object: xxx.prototype. __proto__ property
If there are two instances Photo p1 and p2, a method of adding a printName prototype of p, p2 can also be used, such use is not recommended.
(4) get and set Keywords:
The definition and values of attributes stored-value functions, and therefore the assignment and reading behavior was customized.
(5) Write a class with the expression:
Note that the name of this class is Me
, but Me
only within Class available , refer to the current class. In Class outside, only use this class MyClass
reference. If the unused inner class, it can be omittedMe。
(6) Notes:
i, with strict mode by default.
II, the absence of lift , and this is the biggest example of an object ES5 difference generated
III, if a previous method with an asterisk ( *
), indicates that the method is a function Generator.
⚠️iiii, this point:
避免如果将这个方法提取出来单独使用,this
会指向该方法运行时所在的环境(由于 class 内部是严格模式,所以 this 实际指向的是undefined
),应该将这个方法的this 绑定在构造函数中,或者用箭头函数(react就是利用这个)
iiiii、私有方法:没有给出实现方法,只有在方法名称前加 _ ,自我约束(类似于python)
(7)静态方法:
加static 关键字变成静态方法,实例用不了,但是子类可以,这个定义在ts也有。
(8)new.target 属性:
如果构造函数不是通过new
命令或Reflect.construct()
调用的,new.target
会返回undefined
,因此这个属性可以用来确定构造函数是怎么调用的。
能被实例:
Class 内部调用new.target
,返回当前 Class:
如果是继承的子类使用,new.target 返回子类的name。这样能限定一个类不能实例只能被(某一个子类)继承,更不能被实例:
二、class的继承:
(1)继承:
Class 通过 extend 关键字继承。
constructor
方法和toString
方法之中,都出现了super
关键字,它在这里表示父类的构造函数,用来新建父类的this
对象。
子类必须在constructor
方法中调用super
方法,否则新建实例时会报错。这是因为子类自己的this
对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super
方法,子类就得不到this
对象。
在子类的构造函数中,只有调用super
之后,才可以使用this
关键字,否则会报错。
(2)Object.getPrototypeOf() 方法:
该方法用于从子类获得父类,也能用于判断一个类是否继承了另一个类:
(3) super 关键字:
既可以当作函数使用,也可以当作对象使用。
i、super
作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super
函数。作为函数时,super()
只能用在子类的构造函数之中,用在其他地方就会报错。
假如A是父类,B继承了A,注意,super
虽然代表了父类A
的构造函数,但是返回的是子类B
的实例,即super
内部的this
指的是B
的实例,因此super()
在这里相当于A.prototype.constructor.call(this)
。
ii、super
作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。super
在普通方法之中,指向A.prototype
,所以super.p()
就相当于A.prototype.p()
。 由于super
指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super
调用的。
使用super
的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错。例如:不能写 console.log(super)
(4)类的 prototype 属性和 __proto__ 属性:
ES5 中每一个对象都有__proto__
属性,指向对应的构造函数的prototype
属性。
Class 作为构造函数的语法糖,同时有prototype
属性和__proto__
属性,因此同时存在两条继承链。
(1)子类的__proto__
属性,表示构造函数的继承,总是指向父类。
(2)子类prototype
属性的__proto__
属性,表示方法的继承,总是指向父类的prototype
属性。
通过子类实例的__proto__.__proto__
属性,可以修改父类实例的行为。
(5)原生构造函数的继承:
原生构造函数是指语言内置的构造函数,通常用来生成数据结构。ECMAScript 的原生构造函数大致有下面这些。
- Boolean()
- Number()
- String()
- Array()
- Date()
- Function()
- RegExp()
- Error()
- Object()
ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象this
,然后再用子类的构造函数修饰this
,使得父类的所有行为都可以继承。
上面这个例子也说明,extends
关键字不仅可以用来继承类,还可以用来继承原生的构造函数。因此可以在原生数据结构的基础上,定义自己的数据结构。