JavaScript相较于其他语言,他的语法格式风格多变,尤其是在定义类和对象这一块,形式更是多种多样,曾让我一度感到困惑,后经过仔细研究,总结出本文。
本文列出了es6以前定义构造函数中属性和方法的所有写法,并介绍了他们的含义和使用范围。
后又引出es6以后类的语法糖,介绍了类中定义属性和方法的所有写法、含义和使用范围
//es5的构造函数
function B(s) {
//实例属性,在创建实例时,给每个实例对象单独挂载该属性
//一般这种每个实例都要用的函数习惯写在原型对象中,这样节省内存空间
this.s = s
this.f = function () {
console.log('h')
}
// let s=1 不能这么写
// function c() {
// console.log('cc')
// } 也不能这么写
}
//设置B类的静态属性,且只能通过类名来访问,相当于给B类这个对象挂载属性,因为类本质也是对象
B.s1 = 'kk';
B.f1 = function () {
console.log('h')
};
//在B的prototype属性指向的原型对象上挂载公共属性,且只能通过实例对象来共享访问
B.prototype.s2 = 3
B.prototype.f2 = function () {
console.log('h')
};
let b = new B(1)
console.log(b)
console.log(b.__proto__ === B.prototype)//true
//b实例中的__proto__原型属性和B构造函数中的prototype原型属性指向同一块内存,所以他俩相同
//执行b.f2()时,先去b实例里找,如果没有则去原型对象中找,如果没有再去原型对象的原型对象(父级的原型对象)中去找
//原型对象中有个constructor属性指向构造函数
//es6的类同理
let p = 1
class A {
constructor(s) {
//实例属性,在创建实例时,给每个实例对象单独挂载该属性
this.s = s
this.f = function () {
console.log('h')
}
}
//静态属性,子类也可通过类名访问
static s1 = 2
static f1 = function () {
console.log('h');
};
//实例属性,在创建实例时,给每个实例对象单独挂载该属性
s2 = 3
p = p //不能简写成'p'
f2 = function () {
console.log('h');
}
//上面形式的简写,但是是往原型上添加方法,子类对象也可访问
f3() {
console.log('h');
}
}
//添加静态属性另外一种写法,意思是往A类这个对象身上挂载属性
A.s3 = 3
A.f4 = function () {
console.log('h');
};
let a = new A(1)
console.log(a)