一、Node.js “实体类” 的定义//定义类Person 有参构造方法function Person(name, sex, age, addr, salary) { this.name = name; this.sex = sex; this.age = age; this.addr = addr; this.salary = salary;}二、定义set 方法以设置 实体类Person 的属性值//set 方法Person.prototype.setName=function (name) { this.name=name;};Person.prototype.setSex=function (sex) { this.sex=sex;};Person.prototype.setAge=function (age) { this.age=age;};Person.prototype.setAddr=function (addr) { this.addr=addr; console.log(“Person setAddr”);};Person.prototype.setSalary=function (salary) { this.salary=salary;};三、定义get 方法以获取 实体类Person 的属性值//get 方法Person.prototype.getName=function(){ return this.name;};Person.prototype.getSex=function(){ return this.sex;};Person.prototype.getAge=function(){ return this.age;};Person.prototype.getAddr=function(){ return this.addr;};Person.prototype.getSalary=function(){ return this.salary;};四、构造Person实例对象//使用new 全参构造方法 获取实例对象let Kirito=new Person( “桐人”, “男”, 18, “SAO”, 999999999);//控制台打印Person实例console.log(Kirito);console.log("——————————————————-" + “\n\n”);//使用get方法 获取Person属性值console.log(Kirito.getName());console.log(Kirito.getSex());console.log(Kirito.getAge());console.log(Kirito.getAddr());console.log(Kirito.getSalary());console.log("——————————————————-" + “\n\n”);//使用new 无参构造方法 获取实例对象let Ausua = new Person();//使用set方法 设置Person属性值Ausua.setName(“亚丝娜”);Ausua.setSex(“女”);Ausua.setAge(18);Ausua.setAddr(“SAO”);Ausua.setSalary(999999999);//控制台打印Person实例console.log(Ausua);console.log("——————————————————-" + “\n\n”);五、Node.js 实例化的函数调用 工作流程//Node.js 实例化的函数调用 工作流程//let person =new Person();流程//每一个函数对象都有自己的prototype对象 : function Person() 有自己的prototype对象//这个prototype对象是一个字典表 可以定义自己的方法 : Person.prototype.set/get方法的定义//把这个函数对象看做一个类 使用new 来创建类的实例//这个实例产生时 key—>proto//将函数的prototype 浅复制 至实例中 作为value//这样就建立了__proto__ : prototype 关联关系//实例创建完成后 绑定到这个函数的this里面//在后续的函数调用过程中 这个实例通过this进行传递//this传递的实例在函数的方法体中进行一系列初始化等运算//创建完实例,通过实例进行调用函数,其顺序是:先找自己方法体中的字典表 ,在去__proto__里面找//实现在类中定义好了key—value与函数方法后 再new出来的实例对象也具备相同的方法//我们可以通过调用这些函数方法来进行对类对象、属性的一系列操作console.log("——————————————————-" + “\n\n”);六、Node.js继承的实现//Node.js extendsconsole.log(“继承”);let Lady=function(){};//继承方式://1、不可用//Lady.prototype=Person.prototype;//这2个prototype指向了同一个对象 若扩充Lady的方法 Person也会随之更改//2、在原来基类的prototype上进行浅复制let Super= function(){};Super.prototype=Person.prototype;Lady.prototype=new Super();//定义子类Lady新的方法Lady.prototype.setHobby=function(hobby){ this.hobby=hobby;};Lady.prototype.getHobby=function(){ return this.hobby;};//实例化子类Lady对象ladylet lady= new Lady();//设置子类继承的属性lady.setName(“Illyasviel”);lady.setSex(“女”);lady.setAge(18);lady.setAddr(“Fate”);lady.setSalary(999999999);//设置子类特有的属性lady.setHobby(“Kiss you GoodBye”);console.log(lady);console.log("——————————————————-" + “\n\n”);//3、使用util.inherits实现集成let util =require(“util”);//定义子类Studentlet Student =function(cno,cname){ this.cno=cno; this.cname =cname;};//子类属性对应的set get 方法Student.prototype.setCno=function(cno){ this.cno=cno;};Student.prototype.setCname=function(cname){ this.cname=cname;};Student.prototype.getCno=function(){ return this.cno;};Student.prototype.setCname=function(){ return this.cname;};//继承Personutil.inherits(Student,Person);let student =new Student(1,“动漫一班”);student.setName(“Sakura”);student.setSex(“女”);student.setAge(18);student.setAddr(“Fate”);student.setSalary(999999999);console.log(student);console.log("——————————————————-" + “\n\n”);七、方法的重写//方法的重写console.log(“方法的重写—override”);//lady的prototype中setAddr函数//key:setAddr没变 但是value:setAddr的function已经改变//覆盖掉原Person.prototype.setAddrLady.prototype.setAddr=function(addr){ this.hobby=addr; console.log(“override setAddr”);};lady.setAddr(“Fate Stay Night”);console.log("——————————————————-" + “\n\n”);//如方法重写后要调用基类Person的setAddr 那么需要显示传递thisconsole.log(“方法重写后调用基类Person的setAddr”);Lady.prototype.setAddr=function(addr){ Person.prototype.setAddr.call(this);};lady.setAddr(“Fate/Zero”);八、总结与思考// 总结与思考://// 因为Node.js中没有Java等高级语言中class类的概念 故出现了__proto__ 与 prototype// 与java相比 其两者的关系类似于继承:// 函数创建时,Node.js会为这个函数自动添加prototype属性,值是空的字典表对象{}// 在let person=new Person();时 ,此时function Person(){} 就是一个构造函数(constructor)// 那么JS就会帮你创建该构造函数的实例// 该实例 会继承 构造函数内 已定义的 prototype指向的所有属性和方法// 该实例 通过 设置自己的__proto__ 指向构造函数的 prototype来实现这种继承// Node.js通过__proto__和prototype的合作实现了原型链、对象的继承// Node.js是单继承的,Object.prototype是原型链的顶端,类似于Java的Object类// 构造函数,通过prototype来存储要共享的属性和方法,也可以设置prototype指向现存的对象来继承该对象// 对象的__proto__指向自己构造函数的prototype// console.log(Ausua.proto==Person.prototype); 返回true// 注意:prototype 函数的内置属性 显示修改对象的原型的属性// proto 实例对象的内置属性 JS内部使用寻找原型链的属性// ES规范定义对象字面量的原型就是Object.prototype// 最后// 引用《JavaScript权威指南》的一段描述:// Every JavaScript object has a second JavaScript object (or null , but this is rare) associated with it.// This second object is known as a prototype, and the first object inherits properties from the prototype.