Class类

class类的基本写法

  • es6引入了class类的概念,可通过class关键字来定义类
  • 每个类都会有一个构造函数,即constructor()方法,用于创建和初始化class对象
  • 要注意,如果一个类没有指定constructor()方法则会默认添加,其中this关键字代表实例对象
class CustomData {
   constructor(x,y){
      this.x = x;
      this.y = y;
   }
   // 定义方法
   toString() { return '(' + this.x + ', ' + this.y + ')'; }
}
  • 使用时和构造函数一样,通过new命令生成对象实例
 let p = new CustomData(1, 2);
 console.log(p) // Point {x: 1, y: 2}
 console.log(p.toString())   // "(1, 2)"
  • 类的数据类型就是函数,类本身指向构造函数constructor
console.log(typeof CustomData) // function
console.log(CustomData === CustomData.prototype.constructor) // true
  • 类的所有方法都定义在prototype对象上,所有类的新方法可以添加在prototype对象上。
  • 其中Object.assign()方法可以很方便地一次向类添加多个方法
p.add = function (){ return this.x + 5 }
console.log(p.add()) // 6
===================================
Object.assign(CustomData.prototype, {
   add(){  return this.x + 5 },
   addSuffix(){ return this.x + 'Suffix' }
});
console.log(p.add()) // 6
console.log(p.addSuffix()) // 1Suffix
  • 类内部定义的所有方法都是不可枚举的
    Object.getOwnPropertyNames() 返回一个数组,元素为对象自身属性的所有名称,包括不可枚举值,它不考虑继承的属性
console.log(Object.keys(CustomData.prototype)) // []
console.log(Object.getOwnPropertyNames(CustomData.prototype)) // ["constructor", "toString"]
  • xy都是实例对象自身的属性 ( 定义在this对象上 ),所以CustomData.hasOwnProperty('x') // true
  • toString原型对象的属性 ( 定义在CustomData上 ),所以CustomData.hasOwnProperty('toString') // false

私有属性/私有方法———只能在类的内部访问的属性和方法,外部无法访问

  • 给class类添加私有属性,可在属性面前添加#,私有方法同理
class CustomData {
   #count = 'count' // 私有属性
   constructor(x,y) {
      this.x = x;
      this.y = y;
   }
   toString() { return this.#count + this.#handler(); } //可内部调用
   // 私有方法
   #handler() { return this.x }
}
let p = new CustomData(1,2)
console.log(p.toString()) // count1
console.log(p.#count)     // 报错
console.log(p.#handler)   // 报错
  • 另外,私有方法也可通过命名方式加以区别,比如通过在方法名前添加_下划线来定义此方法为私有方法,命名的方式只是为了使用时区分,本身在类的外部还是可以正常调用的
  • 因为类的所有方法都是对外可见的,或许我们可以直接将私有方法移出类,通过类内部调用私有方法,同时利用call()改变被调用的私有方法this指向
class CustomData {
   constructor(x,y) {
      this.x = x;
      this.y = y;
   }
   toString() {
     return handler.call(this,this.x,this.y)
   }
}
function handler(parameter1,parameter2) {
   return parameter1 + parameter2;
}
let p = new CustomData('参数1',"参数2")
console.log(p.toString()) // 参数1参数2

静态属性/静态方法———在方法面前添加static关键字表明此方法为静态方法

  • 在类中定义的所有方法都会被实例继承,但如果是静态属性/静态方法,则表示该属性/方法不会被实例继承,而是直接通过类来调用
export class CustomData {
	// 静态属性
	static prop = '静态属性';
   // 静态方法
   static toString() { return '我是一个静态方法'; }
}
console.log(CustomData.prop) // 我是一个静态方法  // 直接通过类来调用
console.log(CustomData.toString()) // 我是一个静态方法  // 直接通过类来调用
let p = new CustomData(1,2)
console.log(p.toString()) // [object Object] 不会被实例继承,故不可以通过实例对象调用
console.log(p.prop) // undefined
  • 注意:父类的静态方法是可以被子类继承的,不要和实例无法继承这一点混淆
  • 另外在子类中,可以通过super对象调用父类的静态方法
export class Custom_object extends CustomData{
	static toString_object(){ return super.toString() + ',子类'}
}
console.log(Custom_object.toString()) // 我是一个静态方法
console.log(Custom_object.toString_object()) // 我是一个静态方法,子类

class类的继承

  • class通过extends关键字实现继承,让子类继承父类的属性和方法
  • es6中的extends继承必须先调用super()方法,因为这一步会生成一个继承父类的this对象,不调用无法继承父类
  • 也是在子类的构造函数中,只有调用了super()方法后,才可以使用this关键字,否则会报错
  • 另一方面来讲调用super(),在新建子类实例时,父类的构造函数必定会先运行,即 “继承在前,实例在后”
class CustomData {
   constructor(x,y) {
      this.x = x;
      this.y = y;
      console.log('父类') // 1 先输出“父类”
   }
   toString() { return '(' + this.x + ', ' + this.y + ')'; }
}
class Custom_object extends CustomData{
   constructor() {
      super();
      console.log('子类') // 2 再输出“子类”
   }
}
let p = new Custom_object()
console.log(p) // 3最后Custom_object{x: undefined, y: undefined}
  • 继承父类的子类,通过super()继承父类,同时通过传参继承父类的属性
  • 在继承关系中,实例对象同时是父类和子类的实例
class CustomData {
   constructor(x,y) {
      this.x = x * 2 ;
      this.y = y;
   }
}
class Custom_object extends CustomData{
   constructor(x,y,color) {
      super(x,y);
      this.color = this.x + this.y + color
   }
}
let p = new Custom_object(1,2,'color')
console.log(p); // Custom_object {x: 1, y: 2, color: "4color"}
console.log(p instanceof Custom_object) // true
console.log(p instanceof CustomData) // true
  • 子类中,除了私有属性和私有方法,父类的所有属性和方法都会被子类继承,其中包括静态属性和静态方法

Object.getPrototypeOf()方法

  • 可从子类上获取父类,因此可通过此法来判断一个类是否继承了另一个类,类似instanceof作用
class CustomData {
   constructor(x,y,) {
      this.x = x ;
      this.y = y;
   }
   toString() { return '(' + this.x + ',' + this.y + ')' }
}
class Custom_object extends CustomData{
   constructor(x,y,color) {
      super();
      this.color = this.x + this.y + color
   }
}
console.log(Object.getPrototypeOf(Custom_object)) // ƒ CustomData(x, y) {}
console.log(Object.getPrototypeOf(Custom_object) === CustomData) // true
console.log(new Custom_object() instanceof CustomData) // true

super 关键字

  • super既可以当做函数使用,也可当做对象使用
  • 当作为函数使用时,代表父类的构造函数。且在子类的构造函数中必须执行一次super函数
  • 当作为对象时,在普通方法中,指向父类的原型对象
class CustomData {
   constructor(x,y) {
      this.x = x ;
      this.y = y;
   }
   toString() { return '(' + this.x + ',' + this.y + ')' }
}
class Custom_object extends CustomData{
   constructor(x,y) {
      super(x,y); // 函数时
      console.log(super.toString())
   }
}
let p = new Custom_object(1,2)

====================================================================

call、apply、bind的区别

callapplybind 每个函数都有这三个属性,它们的作用都是可以改变函数内部的this指向,且三个的第一个参数是this要指向的对象

  • callapply传参方式不一样,call可以枚举多个参数;apply只有两个参数,第二个参数为数组
    Function.call(this,parameter1,parameter2)
    Function.apply(this,[parameter1,parameter2])

  • bindcall使用方式一致,不过需要多一步手动调用
    let foo = Function.bind(this,[parameter1,parameter2])
    foo()

====================================================================

instanceof

  • 在js中判断一个变量的类型常用typeof,但如果是用引用类型,无论是什么类型的变量,都只会返回Object,为此引入了instanceof,用以验证引用类型为那种类型
let arr = []
let obj = {}
console.log(typeof arr) // Object
console.log(typeof obj) // Object
console.log(arr instanceof Array,arr instanceof Object) // true true
console.log(obj instanceof Object)  // true
  • 可以判断实例对象是否是类的实例
  • 在继承关系中判断实例对象是否是父类的实例
function Father(){}
function Son(){}
Son.prototype = new Father(); // 原型继承
let sonDate = new Son()
console.log(sonDate instanceof Son) // true 判断变量sonDate是否是Son的实例
console.log(sonDate instanceof Father) //true 在继承关系中判断实例对象是否是父类的实例

待续。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值