6.26学习 es6中的类

1.了解构造函数的属性

先上一份代码思考一下它的结果,

function Animal(name) {
   //属性分为两种 实例上的属性 公有属性
   this.name = name;
   this.arr = [1,2,3]
}

Animal.prototype.address = {location: '山间'}

let a1 = new Animal('猴子')
let a2 = new Animal('小鸡')

console.log(a1.arr === a2.arr)
console.log(a1.address === a2.address)

结果是false,true;为什么呢
在这里插入图片描述a1和a2相当于是从Animal拷贝了一份包含name,arr等的数据,明显他俩不是一个内存空间()的,所以他俩的arr肯定是不等的;但是a1和a2都是有一个__proto__属性的,他俩的__proto__刚好指向的就是Animal的prototype,所以他俩的address是一块相同的内存空间,所以是相等的

//每个实例都有一个__proto__指向所属类的原型
console.log(a1.__proto__ === Animal.prototype) //当然这个的结果也是true的

在这里插入图片描述
当然a1的constructor就是Animal了

console.log(a1.constructor === Animal) //true

2.类的继承

先创建两个类

function Animal(name) {
   this.name = name;
   this.arr = [1,2,3]
}
Animal.prototype.address = {location: '山间'}
 function Tiger(name) {
    this.name = name;
    this.age = 10;
 }
 Tiger.prototype.say = function(){
    console.log('说话')
 }

2.1继承父类实例上的属性

function Tiger(name) {
   this.name = name;
   this.age = 10;
   Animal.call(this)
}
Tiger.prototype.say = function(){
   console.log('说话')
}
let tiger = new Tiger()
console.log(tiger.arr) //[1,2,3]

一般都是不叫私有属性的,因为js来说,基本没有拿不到的属性,不算私有。

2.2继承父类原型上的属性或则方法(公共属性或则方法)

我们是不能直接把tiger的实例直接指向Animal的原型的,应该是先指向自己的tiger原型,如果原型上找不到的话,才去指向Animal的原型
在这里插入图片描述

Tiger.prototype.__proto__ = Animal.prototype;
let tiger2 = new Tiger()
console.log(tiger2.address) //{ location: '山间' }

2.2.1 Object.create

其实还可以用es5的object.create()来实现

Tiger.prototype = Object.create(Animal.prototype);

也可以自己写写Object.create的实现原理

function create(parentPrototype) {
   let Fn = function () {}
   Fn.prototype = parentPrototype;
   return new Fn()
}
Tiger.prototype = create(Animal.prototype);

在这里插入图片描述
这里有点小饶的,原本是tiger的实例__proto__指向Animal的原型(prototype),现在是tiger的实例指向了Fn的实例(new Fn()),Fn的prototype指向的Animal的prototype。
但是这样写又会有个问题的,如果我们现在打印tiger2的constructor,会是谁呢???

console.log(tiger2.constructor)//[Function: Animal]

会发现是Animal的构造函数,原生的Object.create也是这个结果的,那如果要tiger2的constrctor是Tiger呢,那该怎么写呢,有两种方法:

//1.自定义的create改造下
function create(parentPrototype) {
   let Fn = function () {}
   Fn.prototype = parentPrototype;
   let fn = new Fn();
   fn.constructor  = Tiger;
   return fn
}
//2.Object.create方法加参数配置
Tiger.prototype = Object.create(Animal.prototype,{constructor:{value:Tiger}});

这两种方法是都可以把iger2的constrctor改为Tiger的。

2.2.2 Object.setPrototypeOf

其实还有种es6的写法也可以,还更简洁

Object.setPrototypeOf(Tiger.prototype,Animal.prototype)

一样的效果的,小小的总结下,要继承父类的实例上的属性和公共属性,一般就call+Object.create或则call+Object.setPrototypeOf来实现。

2.3模拟简单的new(2023-8-25更新)

function Animal(type) {
   this.type = type;
   //return { name: 'qsl' }
}

Animal.prototype.say = function () {
   console.log('say')
}

let dog = new Animal('狗');
console.log(dog)
dog.say();

怎么来模拟简单的new呢?先贴张图吧
在这里插入图片描述

function newDemo() {
   //将第一个参数拿出来 Constructor => Animal 其他的arguments就是参数
   let Constructor = [].shift.call(arguments)
   let obj = {};  //要返回的对象
   //不能这样写 let obj = Object.create(null); 这样写的对象是没有原型链的
   obj.__proto__ = Constructor.prototype; //原型上的方法
   let r = Constructor.apply(obj, arguments)//这句话主要是为了如果原来的构造方法就返回的是引用类型(对象,函数),就应该返回的是该引用类型的数据
   return r instanceof Object ? r : obj;
}
let dog = newDemo(Animal, '狗类')
console.log(dog)
dog.say();

3.es6中的类

3.1定义

class Animal{
   static flag(){
      return 222
   } //es7支持静态属性 es6只支持静态方法
   constructor(name){
      this.name = name;
      this.arr = [1,2,3]
   }
   //公共的属性方法怎么写呢
   //公共的方法
   say(){
      console.log('say')
      console.log(this)
   }
}
// 1)类不能当作函数调用
//Animal()  //TypeError: Class constructor Animal cannot be invoked without 'new'
let animal = new Animal()
animal.say()
console.log(Animal.flag())

//有个错误的写法
let say = animal.say
say() 
//这样看着是没有问题的,我先拿到animal的say方法,再在适合的地方调用它,但是!!!如果方法里有this
//es6规范里 如果单独调用原型上的方法 this是不存在的
// say
// Animal { name: undefined, arr: [ 1, 2, 3 ] }
// say
// undefined

运行结果都是一样的
在这里插入图片描述

3.2 继承

class Tiger extends Animal{
   constructor(name,age){
      super(name);
      this.age = age;
   }
}
let tiger = new Tiger();
tiger.say()
//如果Tiger里面不写constructor的话
let tiger2 = new Tiger('老虎',12);
tiger2.say()
console.log(Tiger.flag()) //静态属性也是可以被继承的 需要被类调用
//如果要写constructor的话,要注意规范
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值