(一)为什么会有原型(原型的出现是为了解决什么问题)
我们一般在js里创建对象时,都会这么写:
/* 构造函数→人类 */
function Person(name, age) {
// 属性
this.name = name;
this.age = age;
// 方法
this.sayHi = function () {
console.log('大家好,我叫' + this.name);
}
}
// 创建对象
var p1 = new Person('张三', 17);
var p2 = new Person('李四', 18);
var p3 = new Person('王五', 16);
var p4 = new Person('赵六', 14);
var p5 = new Person('陈七', 15);
这样创建对象时,每当创建一个对象无论我们是否调用方法,都会重新创建一个方法。
-
分析
- 对象中属性的值是经常变化的。
- 对象中的方法的功能是一致的,所以没有必要每次创建对象时,都重新创建一个方法。 这样会浪费内存,影响程序的性能。
如果把方法从构造函数中抽取出来,让所有用构造函数创建的实例对象共享方法,那么这样就会大大的提高程序的性能,原型就是解决这个问题的办法。
(二)什么是原型
原型也称原型对象。 每个构造函数都有其对应的原型对象。
获取原型对象的方式: 构造函数名.prototype;
function Person(name, age) {
// 属性
this.name = name;
this.age = age;
// 方法
this.sayHi = function () {
console.log('大家好,我叫' + this.name);
}
}
var yx = Person.prototype;
console.log(yx);
// 原型对象的constructor属性可以获取对应的构造函数
console.log(yx.constructor);
注:原型对象,也是对象,是对象必然可以存放key→value
(三)原型的作用
原型对象中的键值可以被其对应的构造函数所创建的所有实例共享
一般情况下,原型对象中用来存放方法
function Person(name, age) {
// 属性
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
console.log('大家好,我叫' + this.name);
}
var p1 = new Person("李四",19);
p1.sayHi();
console.log(p1);
从上面代码中我们可以看到构造函数中并没有sayHi()方法,我们将sayHi()方法放入到构造函数Person()的原型中,这样p1就可以调用,并且打印p1的结果里面只有属性,并没有方法。
注:
存放到原型中,所有的实例对象可以共享一个方法。减少了内存的使用,提高程序性能。
(四) 构造函数、原型与实例
(五)原型链
在访问一个对象的属性,若该对象中没有,则会通过【__proto__】属性找到其原型对象,从原型对象中查找。
若原型对象中也没有,则再通过原型对象的【__proto__】属性找到原型对象的原型对象,依次类推就构成了原型链。
function Person(name, age) {
// 属性
this.name = name;
this.age = age;
}
// 给原先对象添加job 属性
Person.prototype.job ='teacher';
var p1 = new Person("李四",19);
//当访问对象属性或者方法时,首先先去构造函数里找
console.log(p1.name); //李四
//构造函数里面如果没有的话就去原型对象里找
console.log(p1.job); //teacher
//原型对象里没有的话可以去原型对象的原型里找如果没有就是undefined的啦
console.log(p1.hasOwnProperty(name)); // true
console.log(p1.sex); //undefined
//原型对象的原型对象的原型为空
console.log(p1.__proto__.__proto__.__proto__); // null;
console.log(p1);
注:
原型对象中的属性或方法,实例对象只能够获取,无法更改原型对象中的属性或方法 。实例对象若更改属性或方法时,仅仅是给对象本身添加了属性或方法,原型对象中的属性和方法并没有改变。
(六)为内置对象扩展方法
// 通过原型给数组对象扩展求和方法
Array.prototype.getSum = function () {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
};
// 创建一个数组对象
var arr = [10, 20, 30];
// 调用getSum方法
var sum = arr.getSum();
console.log(sum); // 60