Es6中class的属性定义

在ES6中增加了class关键字,这对于传统C++程序员来说,无非是更友好的关键字。

传统类定义和class类定义比较:

传统方法中的一种(方法比较多,传统方法比较多,就不一一例举):

function Human( age )
{
this.age = age
this.say = function()
{
console.log( "hello, I am ", this.age , "years old!" )
}
}

let h = new Human( 18)
h.say()
let h2 = new Human( 20)
h2.say()
输出:
hello, I am 18 years old!
hello, I am 20 years old!

该方式定义类就像是一个函数,因为有function关键字,对于c++程序员来说,总觉得哪里不对。

有了es6标准,一切都变的明朗,下面修改上面类为es6方式

class Human
{
constructor(age)
{
this.age = age
}
say()
{
console.log( "hello, I am ", this.age , "years old!" )
}
}

let h = new Human( 18)
h.say()
let h2 = new Human( 20)
h2.say()
输出:
hello, I am 18 years old!
hello, I am 20 years old!

是不是有了c++的感觉,一看就是定义的一个类。

既然有了类,就涉及到变量的私有化问题,就是在c++中定义类成员变量的public和private问题,那么怎么定义public和private变量呢?不好意思,es6暂不支持私有属性,所有属性默认为public,那我们是不是没有办法使用私有属性呢?我们必须通过es6提供的新特性Symbol来实现。下面给出例子

首先js是以文件为单位,那么一个类常规的写法是定义在一个单独的js文件中,那么新建文件Human.js


单独文件中的class不要忘了export哦,不然外部无法使用,在例子中,可以看出,定义public有两种方式,一种是在任意函数中用this.XXX定义属性,另一种是直接在class内部写XXX,两种方式等价,看个人习惯。定义pravite只需在class外部定义即可。下面是测试代码和输出:

export default class Human {
constructor(age) {
this.age = age //public
this.height = 170 //public
}

hasChild = false //public
say() {
this.sex = "male" //public
console.log( "hello, I am ", this.age, "years old!")
}
}
测试代码:
import Human from './js/runtime/Human' //该处一定要import

let human = new Human( 18)
human.say()

console.log(human.age)
console.log(human.sex)
console.log(human.height)
console.log(human.hasChild)

输出结果如下:

hello,I am 18 years old!
18
male
170

false

私有变量例子:

const weight = Symbol( 'weight');//定义Symbol,用于内部私有变量,Symbol的作用自行查资料

export default class Human {
constructor(age, w) {
this.age = age //public
this.height = 170 //public
    this [weight] = w //private
}

hasChild = false //public
say() {
this.sex = "male" //public
console.log( "hello, I am ", this.age, "years old! I am ", this[weight], "kg")
}
}
测试代码:
import Human from './js/runtime/Human' //该处一定要import

let human = new Human( 18, 50)
human.say()
console.log(human.age)
console.log(human.sex)
console.log(human.height)
console.log(human.hasChild)
console.log(human.weight)

输出结果如下:

hello,I am 18 years old!I am 50 kg
18
male
170

false

undefined

最后一个human.weight打印undefined,说明外部违法访问到human的weight属性,这样就让weight属性变为私有变量,看到这,你可能有一个疑问,为什么需要使用symbol,而不直接定义一个变量?下面来解释这个问题,在human.js文件中的确可以直接定义一个变量(写在类的外部),外部也没办法访问,但是为什么我们不这样做呢,先看测试代码:

let weight = 50
export default class Human {
constructor(age, w) {
this.age = age //public
this.height = 170 //public
     weight = w //private
}

hasChild = false //public
say() {
this.sex = "male" //public
console.log( "hello, I am ", this.age, "years old! I am ", weight , "kg")
}
}

import Human from './js/runtime/Human' //该处一定要import
let human = new Human( 18, 50)
let human2 = new Human( 18, 55 )
human.say()
console.log(human.age)
console.log(human.sex)
console.log(human.height)
console.log(human.hasChild)
console.log(human.weight)

输出结果如下:

hello,I am 18 years old!I am 55 kg
18
male
170

false

undefined

从输出结果看出,human输出结果55kg,为什么出现这种情况,明明在构造时传入的参数是50。那是因为,默认定义在类外部的变量会处理成static类型,在human2初始化的时候,就把Human中的weight修改为了55,所以说在实例化human2之后在调用human.say(),里面访问到的weight是已经修改过后的值,所以输出55。正因为有这样的特性,在写单例时,可以使用该特性。

使用ES6定义使用函数的方式就比较简单了,在es6中写在class内部的函数(没用function打头)都为public函数,写在类外部的函数(需使用function打头)为类的私有函数。


总结:ES6的class特性看起来也有不好之处,但是个人觉得利大于弊,更符合面向对象的编码规则,除了私有属性不是很好用之外,其他都还ok,比如文中还未提及的继承特性,只需要用extends关键字即可实现继承。并且ES6对私有属性已经有了提案


在之后的标准中,应该会有解决方案。总之个人认为标准更新肯定是为了解决老版本存在的问题,为了更好的发展,所以介意采用新标准。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值