在大多数面向对象编程语言中,都有三个共同而显著的特征:封装、继承、多态!
类和实例是大多数面向对象编程语言的基本概念。
但是,在JavaScript 中,不区分类和实例的概念,而是通过原型(prototype)
来实现面向对象编程。
例如:
var Student = {
name: "Robot",
height: 1.2,
run: function () {
alert(this.name + ' can dance and sing');
}
};
var mary = {
name: "Mary"
};
mary.name; // Mary
mary.run(); // TypeError: mary.run is not a function
// 当加上这句话后
xiaoming.__proto__ = Student;
mary.run(); // Mary can dance and sing
很奇怪,最后一行代码可知,mary
对象并没有定义run()
方法, 为啥会有响应呢?
倒数第二行代码把mary
的原型指向了对象Student
,看上去mary
仿佛是从Student
继承下来的
通过 __proto__
指定对象的原型,就可以拥有原型的属性和方法
JavaScript 的原型链和
Java
的Class
区别就在,它没有“Class”
的概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已。
如果你把mary
对象的原型指向其他对象:
var Bird = {
fly: function() {
alert(this.name + "flying...");
}
}
mary.__proto__ = Bird;
mary.fly(); // Mary flying...
obj.__proto__
去改变一个对象的原型,用于演示目的,实际开发中,用关键字new
来调用这个函数,并返回一个对象
JavaScript对每个创建的对象都会设置一个原型,指向它的原型对象。
创建对象
当我们用obj.xxx
访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype
对象,最后,如果还没有找到,就只能返回undefined
。
例如,创建一个Array
对象:
var arr = [1, 2, 3];
其原型链是:
arr ----> Array.prototype ----> Object.prototype ----> null
当我们创建一个函数时:
function foo() {
return 0;
}
函数也是一个对象,它的原型链是:
foo ----> Function.prototype ----> Object.prototype ----> null
构造函数创建对象
首先用构造函数的方法来创建对象
function Student(name) {
this.name = name;
this.hello = function () {
alert(“Hello, ” + this.name + "!"");
}
}
用关键字new来调用这个函数,并返回一个对象
var vivian = new Student('Vivian');
vivian.name; // "vivian"
vivian.hello(); // Hello, Vivian!
注意,如果不写new
,这就是一个普通函数,它返回undefined
。但是,如果写了new
,它就变成了一个构造函数,它绑定的this
指向新创建的对象,并默认返回this
,也就是说,不需要在最后写return this
;
新创建的vivian
对象的原型链是:
vivian ----> Student.prototype ----> Object.prototype ----> null
注意:调用构造函数千万不要忘记写new