目录
-
JavaScript 原型和原型链的定义和使用
-
01 原型
-
原型定义
-
原型实例理解
-
书写方法1:属性单个定义
-
书写方法2:属性多个定义
-
02 原型链
-
原型链定义
-
原型链实例理解
-
最终原型问题
-
03 原型和原型链的使用
-
应用举例
JavaScript 原型和原型链的定义和使用
01 原型
原型定义
原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法(原型也是对象)。
属性
用法
描述
prototype
构造函数名.prototype
可以理解为函数的原型对象
__proto__
对象名.__proto__
指向该对象的原型
constructor
对象名.constructor
指向关联的构造函数,实例原型指向构造函数

原型实例理解
书写方法1:属性单个定义
1//书写方法1: 2函数名.prototype.属性名 = 属性值; 3函数名.prototype.方法名 = function () {···};
代码示例:
1Person.prototype.LastName = 'xiao'; 2Person.prototype.say = function () { 3 console.log('haha'); 4} 5function Person() {}//构造函数 6var person = new Person();//对象
控制台运行截图:

书写方法2:属性多个定义
1//书写方法2: 2函数名.prototype = { 3 属性名:属性值, 4 ··· 5 方法名:function () {···}, 6 ··· 7}
代码示例:
1Person.prototype = { 2 LastName: 'Zhang', 3 FirstName: 'San', 4 age: 12, 5 say: function () { 6 console.log('xixi'); 7 } 8} 9function Person() { 10// 若原型里有该属性,而自己也有属性,则选择自己的 11 this.LastName = 'Li'; 12} 13var person = new Person();
控制台运行截图:

02 原型链
原型链定义
当对象找不到需要的属性时,它会到这个对象的父对象上去找,以此类推,这就构成了对象的原型链。并且Object.prototype是对象的最终原型,绝大多数对象最终都会继承自Object.prototype,而Object.prototype的原型是null。

原型链实例理解
代码示例:
1Grand.prototype.LastName = 'wang'; 2function Grand() { 3 this.name = 'wanger'; 4} 5var grand = new Grand(); 6 7Father.prototype = grand; 8function Father() { 9 this.name = 'xiaoming'; 10} 11var father = new Father(); 12 13Son.prototype = father; 14function Son() { 15 this.hobbit = 'song'; 16} 17var son = new Son();
控制台运行截图:

在运行截图中,可以看到到从Son到Grand原型链后的最终原型是Object.prototype。
最终原型问题
在探讨最终原型问题之前,需要了解一种可以创建类对象的方法:
1var obj = Object.create(原型,特性(可省略)); 2//特性:属性的一些特性,如可读可写等
代码示例1:指定原型是对象(boss),则同其他方法创建对象方法一样,系统会有自带的__proto__属性。即当obj自己身上找不到属性的时候,就去boss身上找,因为obj的原型是boss。
1function Boss() { } //构造函数 2var boss = new Boss(); //对象 3var obj = Object.create(boss); //指定原型是对象,则同其他方法创建对象方法一样,系统会有自带的__proto__属性
控制台运行截图:

代码示例2:指定原型为null,则系统不会自动生成__proto__属性,就算后期添加该属性也没用。
var obj1 = Object.create(null); //指定原型为null,则系统不会自动生成__proto__属性,就算后期添加该属性也没用
控制台运行截图:

03 原型和原型链的使用
利用原型特点和概念,可以提取共有属性,减少代码冗余。而且可以通过XXX.prototype.方法名来对系统的自带方法进行重写或者在原型链上自定义一些方法。
Object.prototype.方法名
Number.prototype.方法名
Array.prototype.toString.方法名
Boolean.prototype.toString.方法名
String.prototype.toString.方法名
应用举例
实现数组去重功能,并且在原型链上编写。
1var arr = [1, 1, 3, 1, 2, 2, 3, 2, 4, 5, 3, 4] 2Array.prototype.unique = function() { 3 var temp = {}, 4 arr = [], 5 len = this.length; 6 for (var i = 0; i < len; i++) { 7 if (!temp[this[i]]) { 8 temp[this[i]] = 'true'; 9 arr.push(this[i]); 10 } 11 } 12return arr; 13}
控制台运行截图:

个人总结,欢迎大家交流探讨!