/*P74-面向对象-定义class
//其他面向对象语言的核心结构-class(类)
//与JS的原型类似,(是图纸-工厂生产产品的图纸),造出来的产品就是对象实例!
//JS是在ES6规范中才有了面向对象的语法,只不过它是prototype原型的一种语法糖
//就是说内部还是会转化成object和prototype这种形式的
//它的面向对象的语法,只是方便大家编写面向对象的代码
//如何定义class,
//class 类名字 {代码}
//1.定义构造方法,使用constructor关键字(老师说依据个人习惯构造函数也是可以的)
//constructior()可以带参数或不带参数,
//{}里面代码和普通构造函数写法是一样的,可以定义Employee类中的成员属性
class Employee {
constructor(name,position){
this.name = name;
this.position = position;
}
}
//初始化一个对象实例,和js原生的一样
//使用new关键字+类名,代表调用这个类的构造方法,然后把参数传进去
//与使用函数作为构造函数new创造的对象是一样的
//log(emp)的结果,是Employee对象,其中有2个属性,也有proto,constructor是class的Employee,再上层还是Object
var emp = new Employee('峰华','前端工程师');
console.log(emp);//Employee {name: "峰华", position: "前端工程师"}
//output
// Employee {name: "峰华", position: "前端工程师"}
// name: "峰华"
// position: "前端工程师"
// __proto__:
// constructor: class Employee
// __proto__: Object
//end
/** */
/*P75-面向对象-成员方法
//在类里面定义方法也很简单,直接写函数名,无需function关键字
//剩下的和定义普通函数一样,另外它也可以用this引用自身的属性
//VH:构造函数定义方法语法this.signIn=function(){},这样的方式。在66节原型有例子,但在构造函数63节只有定义属性的例子。
class Employee {
constructor(name,position){
this.name = name;
this.position = position;
}
signIn(){
console.log(this.name+'打卡上班');
}
get info(){//get info(info)会提示Uncaught SyntaxError: Getter must not have any formal parameters.
return this.name+' '+this.position;
}
set info(info){
let [name,position] = info.split(' ');
this.name = name;
this.position = position;
}
}
var emp = new Employee('峰华','前端工程师');
console.log(emp);//Employee {name: "峰华", position: "前端工程师"}
//调用方法和属性
emp.signIn();//峰华打卡上班
console.log(emp.position);//前端工程师
//定义getter和setters
//语法与原生一样,使用get和set关键字,后面跟代表属性名的函数
console.log(emp.info);//峰华 前端工程师
emp.info = '李四 后端';
console.log(emp.info);//李四 后端
console.log(emp.name, emp.position);//李四 后端
/** */
/*P76-面向对象-实现继承*/
/*使用extends关键字
//VH:复制上节的必要代码
class Employee {
constructor(name,position){
this.name = name;
this.position = position;
}
signIn(){
console.log(this.name+'打卡上班');
}
}
//实现面向对象里面的继承,使用extends关键字
//VH:实际就是类和类之间的继承,Js构造函数之间能继承么?还是说只能对象之间继承。记得是:对象<-对象<-构造函数<-原型函数<-null
//下面例子定义新的类manager继承自Employee类,manager叫子类,Employee叫父类,
//一个子类只能继承一个父类,父类的所有属性子类中都可以使用
class Manager extends Employee{};//老师这里没加分号;之前定义函数的时候好像都没有加
//创建实例
var manager = new Manager('王五', '经理');
console.log(manager);//Manager {name: "王五", position: "经理"}
//调用方法
manager.signIn();//王五打卡上班
//增加对象的属性,可用原生方式,不符合面向对象的规范
manager.dept = '技术部';
console.log(manager);//Manager {name: "王五", position: "经理", dept: "技术部"}
/** */
/*面向对象的增加属性的方法
//VH:复制上节的必要代码
class Employee {
constructor(name,position){
this.name = name;
this.position = position;
}
signIn(){
console.log(this.name+'打卡上班');
}
}
//通过调用父类的构造函数来扩展manager自身的属性
//使用super关键字来代表父类自身
//manager类中定义自己的构造函数
class Manager extends Employee{
constructor(name,position,dept){//constructor定义Manager自己的构造函数
super(name,position);//调用父类的构造函数,先把name和position初始化
this.dept = dept;
}
}
var manager = new Manager('王五', '经理','技术部');
console.log(manager);
/** */
/*覆盖问题
//VH:复制必要代码
class Employee {
constructor(name,position){
this.name = name;
this.position = position;
}
signIn(){
console.log(this.name+'打卡上班');
}
}
//也可以用super去调用父类的其他方法
//子类中写相同方法,覆盖父类中的signIn()方法
//子类中signIn()再去调用父类的signIn()后,添加自己的语句
class Manager extends Employee{
constructor(name,position,dept){
super(name,position);
this.dept = dept;
}
signIn(){//子类中写相同方法,覆盖父类中的signIn()方法
super.signIn();//去调用父类的signIn()
console.log('额外信息','经理打卡');//添加自己的语句
}
};
var manager = new Manager('王五', '经理','技术部');
console.log(manager);
manager.signIn();
//output
// index.js:145Manager {name: "王五", position: "经理", dept: "技术部"}
// index.js:84 王五打卡上班
// index.js:139 额外信息 经理打卡
//end
/** */
/*P77-面向对象-成员变量*/
//老师发布视频的时候说:从这小节开始,所讲的语法都还没有正式发布,部分浏览器支持,或者通过bable等编译工具才能够实现
//咱们使用示例的时候,保证chrome80以上【我现在使用的是360安全浏览器V10,Chrome/86.0.4240.198】
//成员变量是指:类里面定义的变量
/*创建类,不要构造函数
class Employee{
dept = '';
}
var emp = new Employee();
console.log(emp);//Employee {dept: ""}
//上面打印结果只有一个空的dept信息,我们只能在外面设置dept属性的值
emp.dept = '技术部';
console.log(emp);//Employee {dept: "技术部"}
/** */
/*创建类,使用构造函数
//成员变量与构造函数的区别是,构造函数可以添加一些初始化逻辑
//如下例:构造this.name属性的值时,可以在参数传入后前面加上‘员工姓名’
class Employee{
dept = '';
constructor(name){
this.name = '员工姓名:'+name;//VH:对this.name属性值进行加工
}
}
var emp = new Employee('峰华');
console.log(emp);//Employee {dept: "", name: "员工姓名:峰华"}
emp.dept = '技术部';
console.log(emp);//Employee {dept: "技术部", name: "员工姓名:峰华"}
emp.dept2 = '技术部2';
console.log(emp);
//构造函数方便初始化的时候一些逻辑操作,如例子中加上label(“员工姓名”),或其他复杂的逻辑操作
//成员变量dept=''的方式,只有在初始化的时候给一个值,操作逻辑只能在外面,每次创建对象的时候,都需要自己去操作这个逻辑
//2者各有利弊,使用的时候要根据自己的用途
//成员变量,构造函数中的属性,都可以在类的其他方法中使用
/** */
/*P78-面向对象-静态成员
//静态成员变量,是class级别的,只能通过类来访问。
//定义静态成员变量,定义静态成员方法,使用static关键字
class Page{//大小写问题,应该是和构造函数一样要求大写。
static count = 0;
static increaseViewCount(){
Page.count++;
}
}//似乎都没有分号,从开始到现在定义函数和类都没有符号在末尾
//只能通过Page.count来访问count的值
Page.count++;
console.log(Page.count);//1
//只能通过Page.increaseViewCount()来调用increaseViewCount()函数
Page.increaseViewCount();
console.log(Page.count);//2
//这样好处,跟全局的变量的区别,就是给它一个作用域Page{},或者给它一个包名或库名,然后防止它的命名冲突
//Page里面的变量或方法,只能通过Page.count,Page.increaseViewCount来访问
//假如后面还有一个count(比如定义一个count),防止这两个名字冲突。
//VH:我感觉这个静态成员虽然名字是static静态但是值可以变,看例子就知道。用const定义常量就不能改。比如const NUM = 2;
//结束语:还有其他的一些私有成员和私有成员方法,浏览器暂时还不支持,就先不演示了。等支持的时候,再把课程补上
/** */