JavaScript calss语法糖
基础知识
严格意义上来讲,在
Js
中是没有类这一概念的。
我们可以运用前面章节提到的构造函数来模拟出类这一概念,并且可以通过原型对象的继承来完美的实现实例对象方法复用。
但是这样十分的麻烦,我们需要将实例对象需要用到的公共方法来存放到构造函数的原型对象中,而使用
class
语法糖整个过程就变得非常简单。
声明定义
使用
class
来定义类,类中定义的函数称为方法,不需要用关键字
function
也不需要用逗号进行分割。
<script>\"use strict\";class User {f1() {console.log(\"运行了f1...\");}// 不需要逗号分隔f2() {console.log(\"运行了f2...\");}}let u1 = new User();u1.f1(); // 方法调用u1.f2(); // 方法调用</script>
构造函数
使用
constructor
构造函数传递参数,该函数会在
new
时自动执行。
<script>\"use strict\";class User {constructor(name, age, gender) {this.name = name;this.age = age;this.gender = gender;}show(){console.log(`姓名:${this.name},年龄:${this.age},性别:${this.gender}`);}}let u1 = new User(\"云崖\",18,\"男\");u1.show(); // 执行方法</script>
构造函数不是必须定义的,当没有定义构造函数时。
它会自动去查找原型链,相当于如下代码所示。
constructor(...args) {super(...args);}
原理分析
不管是使用构造函数还是
class
语法糖,其原理都是一样的。
但是构造函数中的方法应该存放进原型对象,这一步需要我们手动去做,使用
class
语法糖的结构后则会自动将方法放入原型对象。
<script>\"use strict\";class U1 {constructor(name) {this.name = name;}show() {console.log(\"U1 show\");}}console.log(typeof U1); // function class只是语法糖,内部还是函数。</script>
<script>\"use strict\";class U1 {constructor(name) {this.name = name;}show() {console.log(\"U1 show\");}}let u1 = new U1(\"class语法糖\");console.dir(u1);// ============ 两种操作一模一样 class自动将方法写入原型对象中function U2(name) {this.name = name;}U2.prototype.show = function () {console.log(\"U2 show\");}let u2 = new U2(\"构造函数\");console.dir(u2);</script>
<script>\"use strict\";class Vehicle {// 交通工具类constructor(name) {this.name = name;}whistle() {console.log(`${this.name}在鸣笛`); // 公用方法放父类中}}class Aircraft extends Vehicle {constructor(name) {super(name);}}class Car extends Vehicle {constructor(name) {super(name);}}let Flyable_Mixin = {// 飞行器的功能fly() {console.log(`${this.name}在飞`);},outer() {console.log(\"其他功能...\");},};Object.assign(Aircraft.prototype, Flyable_Mixin); //给飞机添加上飞机Mixin的功能let Car_Mixin = {// 汽车的功能reversing() {console.log(`${this.name}正在倒车入库`);},outer() {console.log(\"其他功能...\");},};Object.assign(Car.prototype, Car_Mixin); //给汽车添加汽车Mixin的功能let c1 = new Car(\"法拉利\");let a1 = new Aircraft(\"波音747\");c1.whistle(); // 法拉利在鸣笛c1.reversing(); // 法拉利正在倒车入库a1.whistle(); // 波音747在鸣笛a1.fly(); // 波音747在飞</script>
代码示例
原型检测
检测方法
使用
instanceof
检测构造函数的
prototype
属性是否出现在某个实例对象的原型链上
使用
isPrototypeOf
检测一个对象是否是另一个对象的原型链中
<script>\"use strict\";class User {}let u1 = new User();console.log(u1 instanceof User); // true u1的原型链中包含User的原型对象吗?console.log(User.prototype.isPrototypeOf(u1)); // true User的原型对象在u1的原型链中吗?</script>
instanceof原理
递归不断向上检测原型对象。
function checkPrototype(obj, constructor) {if (!obj.__proto__) return false;if (obj.__proto__ == constructor.prototype) return true;return checkPrototype(obj.__proto__, constructor);}