prototype,__proto__,constructor这几个你知道什么意思了嘛?

本文深入探讨JavaScript中对象的分类,包括普通对象与函数对象的定义方式,以及它们之间的区别。详细解释了函数对象的prototype属性和普通对象的__proto__属性,阐述了原型链的形成原理和作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,JavaScript中万物皆对象。

然后,其中对象分为两种:普通对象和函数对象。Object ,Function 是JS自带的函数对象。

普通对象和函数对象:

// 普通对象的定义方法
	let a = new Object();   // typeof a === object
	let b = {}:            // typeof b === object
	let c = new Person();  // typeof c === object
// 函数对象
	let a2 = function() {};                            // typeof a2 === function
	let b2 = new Function('str', 'console.log(str)');  // typeof b2 === function
	function c2() {}                                   // typeof c2 === function

typeof Object === function
typeof Function === function

总结:

凡是通过new Function() 创建的对象就是函数对象,其他都是普通对象。Object, Function 也是由new Function创建的

函数对象有prototype属性,该属性指向一个对象,就是我们所说的原型对象
普通对象有__proto__属性,该属性指向创建它的函数对象的原型对象(prototype)
prototype对象里面包含constructor构造器,该构造器是对函数对象的引用。这是一种循环引用。

也就是说:

// 举个例子
var Person = function(name){
	this.name = name
};

Person.prototype.getName = function(){
	return this.name;
};

var zjh = new Person('zhangjiahao’);
zjh.getName(); //zhangjiahao

Person.prototype.constructor === Person; //true

原型对象(prototype)是一个普通对象,它也会有__proto__属性的,(Function.prototype除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性)),那么这个属性具体干嘛呢?

__proto__就是我们经常说的原型链的继承的关键所在。

有两点需要注意:
(1)注意Object.constructor===Function;//true 本身Object就是Function函数构造出来的
(2)如何查找一个对象的constructor,就是在该对象的原型链上寻找碰到的第一个constructor属性所指向的对象

原型链

JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype

zjh.__proto__ === Person.prototype; // true  

同样,Person.prototype对象也有__proto__属性,它指向创建它的函数对象(Object)的prototype;

Person.prototype.__proto__ === Object.prototype; // true

继续,Object.prototype对象也有__proto__属性,但它比较特殊,为null;

Object.prototype.__proto__ === null; // true

Object是函数对象,是通过new Function()创建,所以Object.__proto__指向Function.prototype。

Object.__proto__ === Function.prototype // true

Function 也是对象函数,也是通过new Function()创建,所以Function.__proto__指向Function.prototype。

Function.__proto__ === Function.prototype // true
Function.prototype.__proto__ ===  Object.prototype //true

Function.prototype是个函数对象,理论上他的proto应该指向 Function.prototype,就是他自己,自己指向自己,没有意义。
JS一直强调万物皆对象,函数对象也是对象,给他认个祖宗,指向Object.prototype。Object.prototype.proto === null,保证原型链能够正常结束。

var animal = function(){};
var dog = function(){};

animal.price = 2000;
dog.prototype = animal;
var tidy = new dog();

console.log(dog.price) //undefined
console.log(tidy.price) // 2000

这说明什么问题呢,执行dog.price的时候,发现没有price这个属性,虽然prototype指向的animal有这个属性,但它并没有去沿着这个“链”去寻找。同样,执行tidy.price的时候,也没有这个属性,但是__proto__指向了animal,它会沿着这个链去寻找,animal中有price属性,所以tidy.price输出2000。
由此得出,原型链的真正形成是靠的__proro__,而不是prototype。
因此,如果在这样指定dog.proto = animal。那dog.price = 2000。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值