es5里面没有专门定义类的用法,如果要定义类,使用function
比如简单的类定义, 类名称: 首字母大写
function Person() { this.name = "张三"; this.age = 20; }
调用的时候要实例化
// 通过实例化调用函数 var p = new Person(); console.log(p.name); // 调用类属性
添加类方法
function Person() { this.name = "张三";// 定义类属性 this.age = 20; // 定义类方法 this.run = function() { console.log(this.name+"运动"); } } // 通过实例化调用函数 var p = new Person(); console.log(p.name); // 调用类属性 p.run(); // 调用类方法
通过原型链添加属性和方法
function Person() { this.name = "张三"; this.age = 20; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 通过原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; // 通过实例化调用函数 var p = new Person(); console.log(p.name); // 调用属性 p.run(); // 调用类方法 p.work(); // 调用原型链的方法
执行结果
张三 张三运动 张三是一个boy [Done] exited with code=0 in 0.086 seconds
要注意的是:原型链的属性和方法会被多个实例共享, 构造函数就不会
function Persion() { this.name = "张三"; this.age = 20; } var p = new Persion(); Persion.sex = "男"; console.log(p.sex); // 输出 undefined var k = new Persion(); console.log(p.sex); // 输出 undefined
function Persion() { this.name = "张三"; this.age = 20; } var p = new Persion(); Persion.prototype.sex = "男"; // 使用原型链定义 console.log(p.sex); // 输出 男 var k = new Persion(); console.log(p.sex); // 输出 男
类里面的静态方法
实例方法,需要通过new来调用方法, 如果是静态方法,直接使用类名.方法名,就可以调用了
function Persion() { this.name = "张三"; this.age = 20; } Persion.getInfo = function() { console.log("我是静态方法"); } // 调用静态方法 Persion.getInfo();
ES5的继承
ES5里面的继承,我们一般用原型链继承,或者使用对象冒充,最常见的是使用“原型链”+”对象冒充“的组合方式
function Person() { this.name = "张三"; this.age = 20; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; // 定义一个Web类继承Persion function Web() { Person.call(this); // 对象冒充实现继承 } var w = new Web(); w.run(); // 使用父亲(Person)的run方法 输出 张三运动
对象冒充可以继承到构造函数里面的属性和方法,但是没有继承原型链的属性和方法
function Person() { this.name = "张三"; this.age = 20; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; // 定义一个Web类继承Persion function Web() { Person.call(this); // 对象冒充实现继承 } var w = new Web(); w.run(); // 使用父亲(Person)的run方法 输出 张三运动 w.work(); // 调用原型链里面的方法 输出: TypeError: w.work is not a function
使用对象冒充调用原型链的方法出错了
使用原型链继承,可以继承构造函数里面的属性和方法也可以继承原型链的属性和方法
function Person() { this.name = "张三"; this.age = 20; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; // 使用原型链继承 function Web() { } Web.prototype = new Person(); // 让Person的属性和方法,都挂载到Web的原型链里面 var w = new Web(); w.run(); // 构造函数的方法 输出: 张三运动 w.work();// 原型链的方法 输出: 张三运动
但是原型链继承也是有问题的,比如构造函数的参数不是写死的,而是实例化的时候传进去的
function Person(name, age) { this.name = name; this.age = age; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; var p = new Person("张三", 20); p.run();// 输出张三在运动
function Person(name, age) { this.name = name; this.age = age; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; function Web(name, age) { } Web.prototype = new Person(); // 使用原型链继承 var w = new Web("赵四", 22); var w1 = new Web("王五", 21); w.run(); // 应该打印赵四在运动 输出: undefined运动 w1.run(); // 应该打印王五在运动 输出: undefined运动
使用原型链继承的时候,实例化子类无法给父类传参数
原型链+构造函数的组合模式的继承
function Person(name, age) { this.name = name; this.age = age; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; function Web(name, age) { Person.call(this, name, age); // 对象冒充继承, 实例化子类可以给父类传参 } Web.prototype = new Person(); // 使用原型链继承 var w = new Web("赵四", 22); var w1 = new Web("王五", 21); w.run(); // 构造函数方法 输出: 赵四运动 w.work();// 原型链方法 输出: 赵四是一个boy w1.run(); // 输出: 王五运动 w1.work();// 输出: 王五是一个boy
组合方法继承可以使用原型链的方法和给父类传参数了
原型链+对象冒充的另外一种写法,对象冒充已经继承构造函数里面的属性和方法,我们只需要继承原型链的属性和方法,我的原型链继承只需要继承父类的原型链就好了
function Person(name, age) { this.name = name; this.age = age; // 定义类方法 this.run = function () { console.log(this.name + "运动"); }; } // 原型链定义属性和方法 Person.prototype.sex = "boy"; // 原型链定义属性 Person.prototype.work = function () { console.log(this.name + "是一个" + this.sex);// 这里也可以调用原来的属性或方法 }; function Web(name, age) { Person.call(this, name, age); // 对象冒充继承,可以继承父类的里面的属性和方法 实例化子类可以给父类传参 } Web.prototype = Person.prototype; // 继承父类的prototype, var w = new Web("赵四", 22); w.run(); // 构造函数方法 输出: 赵四运动 w.work();// 原型链方法 输出: 赵四是一个boy