JavaScript 原型和原型链的定义和使用

JavaScript 原型和原型链的定义和使用

01 原型

原型定义

原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法(原型也是对象)。

属性 用法 描述
prototype 构造函数名.prototype 可以理解为函数的原型对象
__proto__ 对象名.__proto__ 指向该对象的原型
constructor 对象名.constructor 指向关联的构造函数,实例原型指向构造函数

原型图解

原型实例理解

书写方法1:属性单个定义

//书写方法1:
函数名.prototype.属性名 = 属性值;
函数名.prototype.方法名 = function () {
    
    ···};

代码示例:

Person.prototype.LastName = 'xiao';
Person.prototype.say = function () {
    
    
	console.log('haha');
}
function Person() {
    
    }//构造函数
var person = new Person();//对象

控制台运行截图:
原型属性单个定义

书写方法2:属性多个定义

//书写方法2:
函数名.prototype = {
    
    
	属性名:属性值,
	···
	方法名:function () {
    
    ···},
	···
}

代码示例:

Person.prototype = {
    
    
	LastName: 'Zhang',
	FirstName: 'San',
	age: 12,
	say: function () {
    
    
		console.log('xixi');
	}
}
function Person() {
    
    
// 若原型里有该属性,而自己也有属性,则选择自己的
	this.LastName = 'Li';
}
var person = new Person();

控制台运行截图:
原型属性多个定义

02 原型链

原型链定义

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

原型链实例理解

代码示例:

Grand.prototype.LastName = 'wang';
function Grand() {
    
    
	this.name = 'wanger';
}
var grand = new Grand();

Father.prototype = grand;
function Father() {
    
    
	this.name = 'xiaoming';
}
var father = new Father();

Son.prototype = father;
function Son() {
    
    
	this.hobbit = 'song';
}
var son = new Son();

控制台运行截图:
原型链代码
在运行截图中,可以看到到从Son到Grand原型链后的最终原型是Object.prototype。

最终原型问题

在探讨最终原型问题之前,需要了解一种可以创建类对象的方法:

var obj = Object.create(原型,特性(可省略));
//特性:属性的一些特性,如可读可写等

代码示例1:指定原型是对象(boss),则同其他方法创建对象方法一样,系统会有自带的__proto__属性。即当obj自己身上找不到属性的时候,就去boss身上找,因为obj的原型是boss。

function Boss() {
    
     } //构造函数
var boss = new Boss(); //对象
var obj = Object.create(boss); //指定原型是对象,则同其他方法创建对象方法一样,系统会有自带的__proto__属性

控制台运行截图:
obj原型

代码示例2:指定原型为null,则系统不会自动生成__proto__属性,就算后期添加该属性也没用。

var obj1 = Object.create(null); //指定原型为null,则系统不会自动生成__proto__属性,就算后期添加该属性也没用

控制台运行截图:
obj1原型

03 原型和原型链的使用

利用原型特点和概念,可以提取共有属性,减少代码冗余。而且可以通过XXX.prototype.方法名来对系统的自带方法进行重写或者在原型链上自定义一些方法。

Object.prototype.方法名
Number.prototype.方法名
Array.prototype.toString.方法名
Boolean.prototype.toString.方法名
String.prototype.toString.方法名

应用举例

实现数组去重功能,并且在原型链上编写。

var arr = [1, 1, 3, 1, 2, 2, 3, 2, 4, 5, 3, 4]
Array.prototype.unique = function() {
    
    
	var temp = {
    
    },
	arr = [],
	len = this.length;
	for (var i = 0; i < len; i++) {
    
    
		if (!temp[this[i]]) {
    
    
			temp[this[i]] = 'true';
			arr.push(this[i]);
		}
	}
return arr;
}

控制台运行截图:
应用举例
个人总结,欢迎大家交流探讨!

猜你喜欢

转载自blog.csdn.net/Yuki_yuhan/article/details/108053224