Appearance
如何对class降级
这里有一个es6的class写法,如何降级成es5?
js
class Product {
static count = 0;
constructor(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
get totalPrice() {
return this.number * this.unitPrice;
}
increase() {
this.number++;
}
}
class Product {
static count = 0;
constructor(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
get totalPrice() {
return this.number * this.unitPrice;
}
increase() {
this.number++;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
30分的写法 - 基本
js
function Product(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
Product.count = 0;
Product.prototype.increase = function () {
this.count++;
};
function Product(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
Product.count = 0;
Product.prototype.increase = function () {
this.count++;
};
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
写出上面代码能拿到30分,但还有很多问题
暂时性死区问题: es6的class在不能在申明前调用的,但是在上面的构造函数中却可以,因为函数有提升
js
Product()
function Product(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
Product()
function Product(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
1
2
3
4
5
6
7
2
3
4
5
6
7
40分的写法 - 自执行函数
通过自执行函数来解决这一问题
js
var Product = (function () {
function Product(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
Product.count = 0;
Product.prototype.increase = function () {
this.count++;
};
return Product;
})();
var Product = (function () {
function Product(name, unitPrice, number) {
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
Product.count = 0;
Product.prototype.increase = function () {
this.count++;
};
return Product;
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在es6里的class里,只能通过new来调用,不能当初普通函数来调用,但上面的写法却可以
50分的写法 - 只能new调用
js
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
Product.count = 0;
Product.prototype.increase = function () {
this.count++;
};
return Product;
})();
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
}
Product.count = 0;
Product.prototype.increase = function () {
this.count++;
};
return Product;
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class中还有totalPrice访问器,而且这访问器不仅出现在原型,还会出现在实例上
60分的写法 - 访问器
js
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Product.prototype.increase = function () {
this.count++;
};
return Product;
})();
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Product.prototype.increase = function () {
this.count++;
};
return Product;
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class中原型上方法都不可枚举,即不可通过以下方式获得
js
console.log("Product keys :>> ", Object.keys(Product.prototype));
// > [ "increase"] // 不应该获得到increase
console.log("Product keys :>> ", Object.keys(Product.prototype));
// > [ "increase"] // 不应该获得到increase
1
2
2
70分的写法 - 方法不可枚举
js
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Object.defineProperty(Product.prototype, "increase", {
value: function () {
this.count++;
},
enumerable: false
});
return Product;
})();
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Object.defineProperty(Product.prototype, "increase", {
value: function () {
this.count++;
},
enumerable: false
});
return Product;
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
同样的原型是的静态属性也不可以枚举
80分的写法 - 静态属性不可枚举
js
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
// 静态属性不可被枚举
Object.defineProperty(this, "count", {
enumerable: false
});
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Object.defineProperty(Product.prototype, "increase", {
value: function () {
this.count++;
},
enumerable: false
});
return Product;
})();
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
Product.count++;
// 静态属性不可被枚举
Object.defineProperty(this, "count", {
enumerable: false
});
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Object.defineProperty(Product.prototype, "increase", {
value: function () {
this.count++;
},
enumerable: false
});
return Product;
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class中的方法是不能关键字new来当构造器调用的,但上面却可以,比如:
js
const p = new Product("qiezi", 2.5, 3);
new p.increase()
// 在class中
// > TypeError: p.increase is not a constructor
// 但在es5中
// > {"count": null}
const p = new Product("qiezi", 2.5, 3);
new p.increase()
// 在class中
// > TypeError: p.increase is not a constructor
// 但在es5中
// > {"count": null}
1
2
3
4
5
6
7
2
3
4
5
6
7
所以在es5中也需要对increase函数的调用做约束
90分的写法 - 方法不可new调用
js
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
// 实例上添加访问器属性
Object.defineProperty(this, "count", {
enumerable: false
});
Product.count++;
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Object.defineProperty(Product.prototype, "increase", {
value: function () {
if (
Object.getPrototypeOf(this) === Product.prototype.increase.prototype
) {
throw new TypeError("increase is not a constructor");
}
this.count++;
},
enumerable: false
});
return Product;
})();
var Product = (function () {
function Product(name, unitPrice, number) {
// this.__proto__ !== Product.prototype 这种写法es官方不推荐
if (Object.getPrototypeOf(this) !== Product.prototype) {
throw new TypeError(
"Class constructor Product cannot be invoked without 'new'"
);
}
this.name = name;
this.unitPrice = unitPrice;
this.number = number;
// 实例上添加访问器属性
Object.defineProperty(this, "count", {
enumerable: false
});
Product.count++;
// 实例上添加访问器属性
Object.defineProperty(this, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
}
Product.count = 0;
// 原型上添加访问器属性
Object.defineProperty(Product.prototype, "totalPrice", {
get() {
return this.unitPrice * this.number;
}
});
Object.defineProperty(Product.prototype, "increase", {
value: function () {
if (
Object.getPrototypeOf(this) === Product.prototype.increase.prototype
) {
throw new TypeError("increase is not a constructor");
}
this.count++;
},
enumerable: false
});
return Product;
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
剩下的10分会考察原型继承上,有待于探索...