class field所带来的一些问题

public field 和private field组成了class field,这篇文章不讲private field ,只谈public field所带来的问题

我会根据例子来讲解,这样会更好理解一些

class SafeUser {
    constructor() {
       	this.password = '1234'
   	}
}

上面代码非常简单,就是声明了一个SafeUser类,接下来我们根据public field来简化一下代码

class SafeUser {
    password = '123'
}

这两种方式有什么区别呢?

下面这种方式在执行的时候调用了

Object.defineProperty

为当前的实例添加属性,当然上面那种写法也是在当前实例上添加password属性

在一般的情况下,这两种写法是没什么差别的,但在一些特殊的情况下,下面的写法会出现问题。举个例子

class User {
    get password() { 
    	return this._password
    }
    set password(val) { 
    	this._password = val;
    	console.log('change password')
    }
}

class SafeUser extends User {
    constructor() {
    	super()
    	this.password = '1234'
    }
}

父类 User,子类SafeUser,我们的目的在于当SafeUser的实例每次改变时,都打印出change password,(在真实的开发中,可能是以日志的形式记录下来)

看下效果

我们发现当改变password的时候,确实会打印出'change password'

不仅如此,在生成一个实例的时候,就已经打印出来'change password',这是因为调用super,初始化了父类,

接下来this.password = ‘1234’,触发了set函数,也就是触发了父类的set方法,为当前实例添加了_password属性

所以password不是inst的属性,是它从原型上找的,_password才是inst自身的属性,下图就验证了我们的说法

如果把SafeUser改为下面那种public field的写法,就会出现问题

class User {
    get password() { 
	    return this._password
	}
	set password(val) { 
		this._password = val;
		console.log('change password')
	}
}

class SafeUser extends User{
	password = '123'
}

具体的差别,我们从下面的截图就可以看出来

改变password没有触发set函数

为什么会这样呢?

就向上面说的,内部相当于执行了

Object.defineProperty

既然inst自己有password属性,就不会访问父级的password了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值