什么是构造函数
下面就是一个构造函数
//构造函数
function Student(name, age) {
this.name = name;
this.age = age;
this.say=function (){}
}
// 根据构造函数 创建实例对象
var p1 = new Student("张三", 11);
var p2 = new Student("李四", 22);
构造函数的特点
- 构造函数的作用是专门用来创建某一类型的实例对象的
- 构造函数其实就是普通的函数,但是构造函数习惯上首字母大写
- 普通函数调用方式是直接调用的,构造函数需要使用
new关键字来调用(构造函数的执行过程其实就是new的调用过程) - 构造函数的函数名与类名相同,
Student既是函数名,也是类名 - 构造函数会自动返回一个实例对象,普通函数没有写
return则会返回undefind - 构造函数有原型对象
prototype,prototype里面有constructor,指向构造函数本身。 - 构造函数创建的实例对象有
__proto__(没有prototype),__proto__指向构造函数的原型对象prototype;
构造函数的缺点
JS通过构造函数来生成实例对象,这样就会有一个问题,在构造函数中通过this赋值的属性或者方法,是每个实例自己的属性和方法,它是无法共享公共属性和方法的。
所以又设计出了一个原型对象(prototype),来存储这个构造函数的公共属性以及方法。这样就结局也了共享属性和方法的问题
//添加到到原型上的方法 会被所有实例对象共享
Student.prototype.show = function () {
console.log("造化钟神秀");
}
所以这就是原型链设计的初衷
构造函数用来干什么
对js比较熟悉的小伙伴肯定知道到 JS 一直到 ES6才有类(class)这个概念的,在es6之前,那JS的继承怎么来实现呢?
是JS的设计者使用了构造函数来实现继承机制。而且ES6的class其实只是一个语法糖,只是让写法更加清晰而已(继承后面再讲)
注意:
function Person(name, age) {
this.name = name;
this.age = age;
};
Person.ww = 'ww';
var p1 = new Person("aa", 11);
console.log( Person.ww); // ww
console.log( p1.ww); // undefined
添加 ww 属性的是 构造函数本身 ,而不是实例对象。
类
-
类(class): 具备共同特征(属性和方法)事物的抽象,叫类
例如: 人类、动物类、车类。。。。。一个大的分类
ES6引入了类的概念,这是一种更简洁、更易于阅读和理解的面向对象编程方式。类是一种特殊的函数,用于创建对象。es6通过class关键字来定义一个类,与构造函数不同的是,类的定义中包含了构造函数以及其他方法和属性的定义。class关键字从语法上模拟了真正面向对象的语法。 -
实例对象(object): 具体的一个实物,如: 李寻欢、大众辉腾、灰猫。。。。
//父类 class Person { //构造器 也就是构造函数 constructor(name, age) { this.name = name; this.age = age; } // 原型方法 固定写法 eat() { console.log('父类原型方法,吃!!!'); } } // 子类 class Student extends Person { // 构造函数(器) constructor(name, age, No) { super(name, age); // 继承父类属性 this.No = No; // 自己的属性 } // 子类的原型方法 study() { console.log('我爱学习!'); } } // console.log(Person); var s1 = new Student("王五", 16, 22); // 实例对象 var s2 = new Student("赵六", 18, 23); console.log('s1', s1); console.log('s2', s2); console.log('s1.study===s2.study', s1.study === s2.study); // true console.log('s1.eat===s2.eat', s1.eat === s2.eat); // true console.log(s1.study()); // 我爱学习! console.log(s1.eat()); // 父类原型方法,吃!!! console.log(s1 instanceof Student); // true console.log(s1 instanceof Person); // true console.log(s1 instanceof Object); // trueconstructorconstructor就相当于之前的构造函数了,负责初始化对象及接受参数。它是类的默认方法,通过new命令生成对象实例,自动调用该方法。一个类必须有constructor方法,如果没有显示定义,会被默认添加。// 定义了一个空的类Student, class Student { // JavaScript引擎会自动为它添加一个空的constructor方法 } // 等同于 // class Student { // constructor() { } // }类既解决了构造函数的过载,又不再显式的通过原型对象去共享方法和属性。子类还可以通过
extends关键字来 继承 父类为了实现继承,实例化时,传入参数首先被子类的
constructor执行,但是,从语法上,应该时主类的constructor先执行,因此引入super()方法来调用主类的constructor。
static
static 关键字, static 表示定义静态方法。不能在类的实例上调用静态方法,而应该通过类本身调用。
class Person {
//构造函数(构造器) 也就是构造函数
constructor(name, age) {
this.name = name;
this.age = age;
}
// 原型方法 固定写法
eat() {
console.log('父类原型方法,吃!!!');
}
static game() {
console.log('打高尔夫');
}
static run() {
this.game();
console.log('我跑的很快');
}
}
var s1 = new Person("王五", 16, 22);
console.log('Person.run()', Person.run()); // 打高尔夫 我跑的很快
console.log('s1.eat()', s1.eat()); // 父类原型方法,吃!!
console.log('s1.game()', s1.game()); // undefined