这是我参与更文挑战的第13天,活动详情查看:更文挑战
对象的两种定义方式
原生js定义
function Person(age, name) {
this.age = age
this.name = name
}
Person.prototype.eat=function(){
console.log("干饭")
}
const p=new Person(18,'tom')
复制代码
class定义
- class定义的方法不可被枚举
class Person2 {
constructor(name, age) {
this.name = name
this.age = age
}
eat() {
console.log("干饭")
}
}
const p2 = new Person2('tony', 18)
复制代码
牵扯到原型与原型链的一些知识
console.log(p2.__proto__ === Person2.prototype) //true
复制代码
constructor
-
每个类中都存在一个constructor方法,即使没有手动创建,也会被默认添加
-
对于一个类来说,只能存在一个
constructor
方法,constructor
中的this指向被创建的实例对象
变量提升
对于变量和函数来说,都存在变量提升,但是作为class,不存在变量提升这一说,所以要先创建,在调用
class P{
}
new P()
复制代码
私有方法
变量前添加下划线
- 开发团队事先约定好私有变量名之前添加下划线
class P{
constructor(name, age) {
this.name = name
this.age = age
this._a = 1//代表_a是一个私有属性
}
}
new P()
复制代码
但是打印对象时,可以看到_a
属性仍然可以被调用,这种方法简单且直观,但是在外部仍可被调用,只是表面上的私有变量
symbol
symbol用来定义一个唯一的值,利用这个特性来实现私有变量
Symbol('a')===Symbol('a')//false
复制代码
//在一个文件中封装一个类
const _a = Symbol('_a') //
class Person2 {
constructor(name, age) {
this.name = name
this.age = age
this[_a] = 1 //添加私有属性
}
eat() {
console.log("干饭")
}
show() {
return this[_a]
}
}
//在别的js文件引入这个类
const p2 = new Person2('tony', 18)
console.log(p2)
console.log(p2.show()) //1
console.log(p2._a) //undefined 不可被访问
复制代码
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
复制代码
利用bind
class Logger {
constructor() {
this.printName = this.printName.bind(this);
}
// ...
}
复制代码
箭头函数
class Logger {
constructor() {
this.printName = (name = 'there') => {
this.print(`Hello ${name}`);
};
}
// ...
}
复制代码
super
作为方法
- 作为方法使用时,例如
super(name)
,代表父类的构造函数,只能写在constructor
中
作为对象
- 作为对象时,例如
super.move()
代表父类的原型对象
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END