面向对象编程
JavaScript 不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。
一 创建对象
var arr = [1, 2, 3];
其原型链是:
arr ----> Array.prototype ----> Object.prototype ----> null
(1)构造函数
function Student(name) {
this.name = name;
this.hello = function () {
alert('Hello, ' + this.name + '!');
}
}
var xiaoming = new Student('小明');
xiaoming.hello(); // Hello, 小明!
注意,如果
不写new,这就是一个
普通函数,它返回undefined。但是,如果写了
new,它就变成了一个构造函数,它绑定的this指向新创建的对象,并默认返回this,也
就是说,不需要在最后写return this;
红色箭头是原型链。注意,Student.prototype
指向的对象就是xiaoming
、xiaohong
的原型对象,这个原型对象自己还有个属性constructor
,指向Student
函数本身。
二 原型继承
原型链为:
new PrimaryStudent() ----> PrimaryStudent.prototype ----> Student.prototype ----> Object.prototype ----> null
理解:先让一个委托人来管理财产,之后再由儿子来管理
function
Student
(
name
){
this
.
name
=
name
;
this
.
hello
=
function
(){
return
"hello,"
+
this
.
name
+
"!"
;
}
}
//构造函数
function
PrimaryStudent
(
props
){
Student
.
call
(
this
.
props
);
this
.
grade
=
props
.
grade
||
1
;
}
//空函数
function
F
(){
}
//把F的原型Student.prototype
F
.
prototype
=
Student
.
prototype
;
//把PrimaryStudent 的原型指向一个新的F对象
PrimaryStudent
.
prototype
=
new
F
();
//把PrimaryStudent 原型的构造函数修复为 PrimaryStudent
PrimaryStudent
.
prototype
.
constructor
=
PrimaryStudent
;
//继续在 PrimaryStudent 原型(就是new F()对象)上定义方法;
PrimaryStudent
.
prototype
.
getGrade
=
function
(){
return
this
.
grade
;
}
继承这个动作用一个inherits()
函数封装起来,还可以隐藏F
的定义,并简化代码:
function inherits(Child, Parent) {
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}
(1)JavaScript的原型继承实现方式就是:
- 定义新的构造函数,并在内部用call()调用希望“继承”的构造函数,并绑定this;
- 借助中间函数F实现原型链继承,最好通过封装的inherits函数完成;
- 继续在新的构造函数的原型上定义新方法。
三 class继承
继承这个动作用一个inherits()
函数封装起来,还可以隐藏F
的定义,并简化代码:
function inherits(Child, Parent) {
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}