一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情。
背景
旧js中定义构造函数和原型对象时分开定义的,不符合封装的概念。
//想定义一个对象类型,描述所有子对象的统一结构和功能
function Obj(name, age){
this.name=name;
this.age=age;
}
Obj.prototype.say=function(){
console.log(
`I'm ${this.name}, I'm ${this.age}`);
}
//创建一个子对象
var obj1=new Obj("jingjing",18);
console.log(obj1);
obj1.say();
以上可以用es6的class进行简化,解决上面说的问题。
只要在es6中创建一种新类型,包含构造函数+原型对象方法,都要用class来创建。
什么是class
程序中专门集中保存一种类型的所有子对象的统一属性结构和方法定义的程序结构(也就是说构造原型一体化)
如何定义?
- 用class{}包裹原构造函数+原型对象方法。
- 原构造函数名升级为整个class名字,所有构造函数统一更名为:‘constructor’。
- 原型对象中的方法,不再加prototype前缀,也不用=function,直接简写为:方法名()。
直接放在class{}内的方法定义,其实是保存在原型对象中的。
如何使用?
和使用旧的构造函数一样,var 对象名=new class名(属性值,...)。
//想定义一个对象类型,描述所有子对象的统一结构和功能
class Obj{
constructor(name, age){
this.name=name;
this.age=age;
}
say(){
console.log(`I'm ${this.name}, I'm ${this.age}`);
}
}
//创建一个子对象
var obj1=new Obj("jingjing",18);
console.log(obj1);
obj1.say();
静态属性
如果多个子对象共用的相同的属性值,应该放在那里?
旧js中: 是和共有方法一起放在原型对象中。
虽然直接在class中定义的方法,都默认保存在原型对象中。但是直接在class中定义的属性,却不会成为共有属性,不会保存在原型对象中。而是成为每个子对象的自有属性。
解决:
为了和其它主流开发语言尽量一致, ES6的class放弃了在原型对象中保存共有属性的方式。而是改为用静态属性保存!
什么是静态属性?
不需要创建子对象,单靠类型名就可直接访问的属性,就称为静态属性 只要如果希望所有子对象,都可使用一个共同的属性值时,都要用静态属性代替原来的原型对象属性
如何定义静态属性
class 类型名{
static 共有属性名=属性值
...
}
原理
标有static的静态属性,都是保存在构造函数对象身上,因为构造函数在程序中不会重复,所以,静态属性也不会重复,任何时候,任何地点,访问一个类型的静态属性,永远访问的都是同一份。
//想定义一个对象类型,描述所有子对象的统一结构和功能
class Obj{
constructor(name, age){
this.name=name;
this.age=age;
}
static sonName='小明'
say(){
console.log(`I'm ${this.name}, I'm ${this.age}`);
}
}
//创建一个子对象
var obj1=new Obj("jingjing",18);
console.log(obj1);
obj1.say();
如何和直接访问静态属性?
类型名.静态属性
class Obj{
constructor(name, age){
this.name=name;
this.age=age;
}
static sonName='小明'
say(){
console.log(`I'm ${this.name}, I'm ${this.age} ,I'm son ${Obj.sonName}`);
}
}
//创建一个子对象
var obj1=new Obj("jingjing",18);
console.log(Obj.sonName); //小明
Obj.sonName='小涛'
console.log(obj1.say()); //I'm jingjing, I'm 18 ,I'm son 小涛
class Obj到底是什么?
console.log(typeof Obj);//”function”
说明class只是个外壳,其本质还是普通的构造函数function
console.dir(Obj);
class里的Prototype是个函数。