类和函数的不同之处

news/2024/11/24 7:29:55/

60. 类和函数的不同之处

1. 创建方式不同

  • 函数可以通过函数表达式或函数声明来创建:
// 函数声明
function greet(name) {console.log(`Hello, ${name}!`);
}// 函数表达式
const add = function (x, y) {return x + y;
};
  • 则是通过 class 关键字来创建:
class Person {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, my name is ${this.name}.`);}
}

2. 对象创建方式不同

  • 通过函数创建的对象可以使用函数调用运算符 () 来创建:
function Person(name) {this.name = name;
}const person1 = new Person('Alice');
const person2 = Person('Bob');
  • 而通过创建的对象必须使用 new 运算符来创建:
class Person {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, my name is ${this.name}.`);}
}const person1 = new Person('Alice');
const person2 = Person('Bob'); // 报错:Class constructor Person cannot be invoked without 'new'

3. 继承方式不同

  • JavaScript 中,函数使用原型链来实现继承:
function Animal(name) {this.name = name;
}Animal.prototype.sayHello = function () {console.log(`Hello, I am ${this.name}.`);
}function Cat(name) {Animal.call(this, name);
}Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;Cat.prototype.meow = function () {console.log(`Meow, I am ${this.name}.`);
}const cat = new Cat('Tom');
cat.sayHello(); // 输出 "Hello, I am Tom."
cat.meow(); // 输出 "Meow, I am Tom."
  • 而类使用 extends 关键字来实现继承,并且还可以使用 super 关键字来访问父类的方法和属性:
class Animal {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, I am ${this.name}.`);}
}class Cat extends Animal {constructor(name) {super(name);}meow() {console.log(`Meow, I am ${this.name}.`);}
}const cat = new Cat('Tom');
cat.sayHello(); // 输出 "Hello, I am Tom."
cat.meow(); // 输出 "Meow, I am Tom."

4. 构造函数不同

  • 函数中,可以使用构造函数来创建对象,但是这个构造函数与函数名称相同:
function Person(name) {this.name = name;
}const person = new Person('Alice');
  • 而在中,类名称本身就是构造函数,使用 new 关键字来创建对象时,会调用该类的构造函数:
class Person {constructor(name) {this.name = name;}
}const person = new Person('Alice');

5. 方法定义方式不同

  • 函数中,可以使用函数表达式或函数声明来定义方法:
function Person(name) {this.name = name;
}Person.prototype.sayHello = function () {console.log(Hello, my name is ${this.name}.);
};const person = new Person('Alice');
person.sayHello();
  • 而在中,可以直接在类体中定义方法:
class Person {constructor(name) {this.name = name;}sayHello() {console.log(Hello, my name is ${this.name}.);}
}const person = new Person('Alice');
person.sayHello();

6. 静态方法定义方式不同

  • 函数中,可以使用对象字面量来定义静态方法:
function Person(name) {this.name = name;
}Person.sayHello = function () {console.log('Hello, world!');
};const person = new Person('Alice');
Person.sayHello();
  • 而在中,可以使用 static 关键字来定义静态方法:
class Person {constructor(name) {this.name = name;}static sayHello() {console.log('Hello, world!');}
}const person = new Person('Alice');
Person.sayHello();

7. 类中的属性和方法默认为不可枚举

在类中,定义的属性和方法默认情况下是不可枚举的,而在函数中,定义的属性和方法默认是可枚举的。这意味着,使用 for...in 循环无法遍历类中的属性和方法,需要使用 Object.keys() 方法获取类中的属性和方法。

例如,在下面的代码中,我们定义了一个类和一个函数,它们都包含一个属性和一个方法:

class Person {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, my name is ${this.name}.`);}
}function PersonFunc(name) {this.name = name;
}PersonFunc.prototype.sayHello = function () {console.log(`Hello, my name is ${this.name}.`);
};const person = new Person('Alice');
const personFunc = new PersonFunc('Bob');console.log(Object.keys(person));       // []
console.log(Object.keys(personFunc));   // ['name']for (const key in person) {console.log(key);   // undefined
}for (const key in personFunc) {console.log(key);   // 'name' 和 'sayHello'
}

在类中,属性和方法默认是不可枚举的,因此使用 Object.keys() 方法无法获取属性和方法。而在函数中,属性和方法默认是可枚举的,因此使用 for...in 循环可以遍历所有的属性和方法。

8. 类不能被调用

JavaScript 中,函数可以被当做构造函数使用,通过使用 new 运算符可以创建一个新的对象。而类不能被直接调用,必须通过使用 new 运算符来创建对象。

例如,在下面的代码中,我们尝试直接调用类:

class Person {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, my name is ${this.name}.`);}
}Person('Alice');   // TypeError: Class constructor Person cannot be invoked without 'new'

运行上面的代码会抛出一个 TypeError 错误,因为类不能被直接调用。

9. 类方法是严格模式下执行

中,所有的方法(包括静态方法和实例方法)都是在严格模式下执行,而在函数中,如果不显式声明为严格模式,方法就会在非严格模式下执行。

总之,函数JavaScript 中都扮演着重要的角色,各有不同的特点和用途。需要根据实际情况选择使用哪个。


http://www.ppmy.cn/news/152041.html

相关文章

easylaser激光轴对中仪维修同心仪维修E420

easy-laser激光对中仪常见维修型号包括:E405、E530、E420、E530、E950、E900、E910、E920、E710、E850、D600、XT440等(找正仪/测量仪/轴对中仪/同心仪等) 激光对中仪维修常见故障:触摸屏损坏(屏碎,不显示…

Microsoft 365 E5免费申请

注册E5账号 1.建议用edge打开IP窗口(无痕模式)再打开开发人员计划|Microsoft 365开发人员中心 网站点击立即加入365开发计划进行注册或登陆; 2.基础资料:国家选china,公司名称随便取一个,语言首选项选中文&…

thinkpad E530 关注

联想ThinkPad E530(32595JC)参数 价格5300 日期2012-6-28 重要参数 屏幕尺寸:15.6英寸 1366x768CPU型号:Intel 酷睿i5 3210M CPU主频:2.5GHz内存容量:2GB DDR3 1600MHz硬盘容量:500GB 7200转&…

解决ThinkPad早期笔记本Broadcom博通系列无线网卡Win10掉线、受限、速度慢问题(ThinkPad E530为例)

说明:如果不想更换网卡可以,参照设置无线网卡的步骤试一下有没有效果。因为原来网卡最大到72M。 1. 首先某宝更换一块网卡,原来网卡类型为博通BCM94313HMGB,新更换网卡为BCM943228HMGB。 2. 发现更换网卡后速度不稳定,而且经常掉线。并且速度不仅达不到300M而且有…

ftp服务部署及使用

安装ftp服务 yum install -y vsftpd 查看一下是否安装成功 rpm -qa |grep ‘vsftpd’ ftp的配置文件主要有三个,位于/etc/vsftpd/目录下,分别是: ftpusers:用来指定哪些用户不能访问ftp服务器 user_list::这个文件中的…

【华为OD机试】打印任务排序【2023 B卷|200分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 某个打印机根据打印队列执行打印任务。打印任务分为九个优先级,分别用数字1-9表示, 数字越大优先级越高。打印机每次从队列头部取出第一个任务A, 然后检查队列余下任务中有没有比A优…

360压缩for linux

我的操作系统是ubuntu2004,下面是360压缩for linux下载地址 链接: https://pan.baidu.com/s/1yhUQo-0-Z_Vg5h27EKYZbQ 密码: 6nff

LiDAR360使用说明书

LiDAR360是一款强大的激光雷达点云数据处理和分析平台,拥有超过10种先进的点云数据处理算法,可同时处理 超过300G点云数据。平台包含丰富的编辑工具和自动航带拼接功能,可为地形、林业和电力行业(参见 LiPowerline软件&#xff0…