ES6的class的理解和ES5的一些区别

42 篇文章 0 订阅
10 篇文章 0 订阅

ES6的class

class Person {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            show() {
                console.log('x---', this.x, 'y----', this.y);
            }
        }

类型为function

console.log(typeof Person)  //function

构造函数的prototype属性,在ES6的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面

console.log(Person === Person.prototype.constructor) //true
console.dir(Person)
let p = new Person(1, 2);

//b是Person 类的实例,它的constructor方法就是Person 类原型的constructor方法

console.log(p.constructor === Person.prototype.constructor); //true

//Object.assign方法可以很方便地一次向类添加多个方法

Object.assign(Person.prototype, {
    toString() { console.log('toString') },
    toValue() { console.log('toValue') }
})

console.dir(Person);

prototype对象的constructor属性,直接指向“类”的本身,这与ES5的行为是一致的。

console.log(Person === Person.prototype.constructor); //true
console.log('keys', Object.keys(Person.prototype)) //keys只能获取可枚举的
//getOwnPerperty可以获取全部属性
console.log('getOwnPerperty', Object.getOwnPropertyNames(Person.prototype))
//在es5中的prototype上定义的方法是可以枚举的,在class内定义的是不可枚举的
var Person1 = function (x, y) {
    //..
};
Person1.prototype.toString = function () {
    // ...
};
console.log('keys', Object.keys(Person1.prototype)) //keys只能获取可枚举的
//getOwnPerperty可以获取全部属性
console.log('getOwnPerperty', Object.getOwnPropertyNames(Person1.prototype))

constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象

class Foo {
constructor() {
     return Object.create(null);  //返回null
 }
}
console.log(new Foo() instanceof Foo)// false

类的构造函数,不使用new是没法调用的,会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行

Foo() // TypeError: Class constructor Foo cannot be invoked without 'new'

x和y都是实例对象Person自身的属性(因为定义在this变量上),所以hasOwnProperty方法返回true,而toString是原型对象的属性(因为定义在Person类上),所以hasOwnProperty方法返回false。这些都与ES5的行为保持一致。

console.log(p.hasOwnProperty('x')) // true
console.log(p.hasOwnProperty('y')) // true
console.log(p.hasOwnProperty('show')) // false
console.log(p.__proto__.hasOwnProperty('show')) // true
var p1 = new Person(2, 3);
var p2 = new Person(3, 2);

 //p1和p2都是Point的实例,它们的原型都是Point.prototype,所以__proto__属性是相等的。

//这也意味着,可以通过实例的__proto__属性为Class添加方法
 console.log(p1.__proto__ === p2.__proto__)
 //true

不能想es5的方法一样无论在什么位置定义都可以,class需要先定义才能用

const MyClass = class Me {
    getClassName() {
        return Me.name;
    }
};
//上面代码使用表达式定义了一个类。需要注意的是,这个类的名字是MyClass而不是Me,Me只在Class的内部代码可用,指代当前类。

let my = new MyClass();
console.log(my.getClassName()) // Me
//console.log(Me.name) // ReferenceError: Me is not defined
//立即执行class
let person = new class {
    constructor(name) {
        this.name = name;
    }

    sayName() {
        console.log(this.name);
    }
}('旺旺');		

person.sayName(); // "张三"

this的指向,类的方法内部如果含有this,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错

class Logger {
   printName(name = 'there') {
        this.print(`Hello ${name}`);
    }

    print(text) {
        console.log(text);
    }
}

const logger = new Logger();
const { printName } = logger;
//printName(); // TypeError: Cannot read property 'print' of undefined
//解决方法1,在构造方法中绑定this,这样就不会找不到print方法了。
// class Logger {
//     constructor() {
//将对象的this绑定到方法中的this上,无论怎么调用都是new的时候的this
//         this.printName = this.printName.bind(this);
//     }

//     // ...
// }
//方法2,使用箭头函数
// class Logger {
//     constructor() {
//         this.printName = (name = 'there') => {
//             this.print(`Hello ${name}`);	//this就是指向定义时的this
//         };
//     }

//     // ...
// }
//方法3,使用Proxy,获取方法的时候,自动绑定this。
function selfFun (target) {
  //将绑定this后的方法存入weakMap中,如果对象不存在了会自动回收
  const cache = new WeakMap();	
  const handler = {
    get (target, key) {
    //调用Reflect来执行get操作,获取target的key属性
      const value = Reflect.get(target, key);  
      if (typeof value !== 'function') {	//非方法
        return value;
      }
      if (!cache.has(value)) {	//方法
        cache.set(value, value.bind(target));
      }
      return cache.get(value);
    }
  };
  const proxy = new Proxy(target, handler);
  return proxy;
}

const logger = selfFun (new Logger());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值