对象原型链是必须掌握的一项重要知识点,尤其是在分析对象方法继承的时候,往往会因为看起来过于复杂而无从下手,这就是原型链基础不够牢固而造成的,作为js初学者,我将开始对对象原型链基础进行一次初步总结,欢迎指正
一.对象创建
首先,我们知道对象有三种创建方式
1.直接量方式
顾名思义,直接创建对象以及它的属性名,属性值
var PC = {//使用var声明一个对象
cpu:'i5-11260H',//直接定义对象中的属性以及其属性值
gpu:'RTX3050',
ram:'16GB',
SSD:'1TB',
price:'$4850'
}
2.工厂模式
即采用function函数设置形参,并通过获取返回值的方式创建对象
function createPC(cpu,gpu,ram,SSD,price){
//使用function创建一个函数createPC,形参为cpu,gpu,ram,SSD,price
var com = {};//在函数中创建一个空对象com
com.cpu = cpu;//将形参被传值后所变为的实参传值给com的cpu属性
com.gpu = gpu;//同上,属性为gpu
com.ram = ram;//同上, 属性为ram
com.SSD = SSD;//同上, 属性为SSD
com.price = price;//同上, 属性为price
return com;//返回被传值后的对象com
}
var pc1 = createPC('R5-5500','GTX750ti','8GB','4TB','$2000')
//执行赋值,createPC传入实参,随后执行函数,最后返回的则是对象com的属性和属性值作为之前被var声明对象pc1的值
var pc2 = createPC('i5-11260H','RTX3050','16GB','1TB','$4850')
//执行赋值,createPC传入实参,随后执行函数,最后返回的则是对象com的属性和属性值作为之前被var声明对象pc2的值
3.自定义构造函数创建对象
function student(id,age,hobby){//使用function创建构造函数student,形参为id,age和hobby
/* new 关键字做了什么
1. 创建了一个新对象
2. 将构造函数的this指向了这个新对象
3. 将新对象的__propto__指向了构造函数的prototype
4. 执行构造函数的代码
5. 返回this */
this.id = id?id:999;//这里包括以下的this可以理解为指向的都是student构造函数使用new创建出来的对象
this.age = age?age:2.5;
this.hobby = hobby?hobby:'basketball';
}
var ikun = new student();//使用student创建一个对象
var ikun = new student(1,2,'football')//也可以传入实参
注意,工厂函数与构造函数不要混合使用,容易产生一些隐患,这里不作赘述
二.构造函数对象原型链:
从new关键字步骤的第三步中,我们知道了新对象的__proto__属性指向了构造函数的prototype属性,这就引出了原型链的概念,就我的理解来说是一种对象属性方法继承的可抽象化的概念:
1. 新对象都有一个属性 叫__proto__
2. 构造函数都有一个属性 叫prototype
3. 构造函数的原型对象上有一个属性 叫constructor 指向构造函数
4. 所有的原型对象都是Object函数对象构造出来的(除Object本身的原型对象之外)
下面我用自己总结的一张图来完整展示一下原型链的基本方式

如上图所示我们可知,被创建的对象的__proto__指向的是构造函数的原型对象,而原型对象自然也具有自己的创建者,即object原型对象,因此它的__proto__指向的是object原型对象,而object原型对象的__proto__一定指向的是null
下面我们用js程序来表达这一顺序
这里用function举例,因为所有函数都是function函数对象构造的,也包括object函数
而function由于是最顶层,因此它是自己构造了自己,而其他构造函数则都是function构造的
//所有的函数都是Function函数对象构造的
console.log(Person.__proto__ === Function.prototype); // true
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Function.prototype.__proto__.__proto__ === null); // true
console.log(Person.__proto__.__proto__.__proto__ === null); // true
// 2. Function顶层没有人构造 自己构造了自己
console.log(Function.__proto__ === Function.prototype); // true
// console.log(Function.prototype.__proto__ === Object.prototype);
console.log(Function.__proto__.__proto__ === Object.prototype); // true
console.log(Object.__proto__ === Function.prototype); // true
// console.log(Function.prototype.__proto__ === Object.prototype);
console.log(Object.__proto__.__proto__ === Object.prototype); // true
console.log(Object.__proto__.__proto__.__proto__); // null
console.log(Function.__proto__.__proto__.__proto__); // null
三.内置构造函数的原型链:
比较常用的有 Number String Boolean Array Function这些,而如果要引用它们中的方法就一定要搞清楚其中的原型链,否则无法引用
var n = 999;
console.log(n.__proto__ === Number.prototype); // true
console.log(Number.prototype.__proto__ === Object.prototype);
console.log(n.__proto__.__proto__ === Object.prototype);
console.log(n.__proto__.__proto__.__proto__ === null);
var str = '999';
console.log(str.__proto__ === String.prototype);
console.log(str.__proto__.__proto__ === Object.prototype);
console.log(str.__proto__.__proto__.__proto__ === null);
var bl = true;
console.log(bl.__proto__ === Boolean.prototype);
console.log(bl.__proto__.__proto__ === Object.prototype);
console.log(bl.__proto__.__proto__.__proto__ === null);
var arr = [];
console.log(arr.__proto__ === Array.prototype);
console.log(arr.__proto__.__proto__ === Object.prototype);
console.log(arr.__proto__.__proto__.__proto__ === null);
var fn = function () {};
console.log(fn.__proto__ === Function.prototype);
console.log(fn.__proto__.__proto__ === Object.prototype);
console.log(fn.__proto__.__proto__.__proto__ === null);
var ikun = new fn();
console.log(fnshili.__proto__ === fn.prototype);
console.log(fnshili.__proto__.__proto__ === Object.prototype);
console.log(fnshili.__proto__.__proto__.__proto__ === null);
而对于这些内置构造函数本身而言,它们的原型链则差别不大
console.log(Number.__proto__ === Function.prototype);
console.log(Number.__proto__.__proto__ === Object.prototype);
console.log(Boolean.__proto__ === Function.prototype);
console.log(Boolean.__proto__.__proto__ === Object.prototype);
console.log(String.__proto__ === Function.prototype);
console.log(String.__proto__.__proto__ === Object.prototype);
console.log(Array.__proto__ === Function.prototype);
console.log(Array.__proto__.__proto__ === Object.prototype);
console.log(Date.__proto__ === Function.prototype);
console.log(Date.__proto__.__proto__ === Object.prototype);
//以上结果都为true
本文是作者对JavaScript对象原型链的初步总结,探讨了对象的创建方式,包括直接量、工厂模式和构造函数。重点讲解了构造函数对象原型链的概念,强调新对象的__proto__属性与构造函数的prototype的关系,以及原型链中的constructor和Object函数的作用。最后,提到了内置构造函数如Number、String等的原型链特点,指出理解原型链对于正确引用方法的重要性。
5万+

被折叠的 条评论
为什么被折叠?



