彻底深刻理解js原型链之prototype,__proto__以及constructor(一)

简介: 以下概念请花费一定的时间彻底理解,才能进行下一步,思考题一定要思考,这样才能彻底掌握原型链的知识点,教程中如果有任何的错误不足请指正!

前言

以下概念请花费一定的时间彻底理解,才能进行下一步,思考题一定要思考,这样才能彻底掌握原型链的知识点,教程中如果有任何的错误不足请指正!

函数对象

由function创造出来的函数,比如:


    function a(){};
    var b=function(){};
    

系统内置的函数对象

Function,Object,Array,String,Number

只有函数对象才有 prototype属性 ,重要的事情说三遍!

思考: js的引用数据类型都属于函数对象吗?

普通对象

除开函数对象之外的对象都是普通对象

var b='qwe'; // b 是字符串类型,属于普通对象
var c=123;; // c 是数字类型,属于普通对象

思考:js有五种基本类型:Undefined,Null,Boolean,Number和String,他们都是属于普通对象吗?

原型对象

prototype属性也叫原型对象,主要是为了实现继承和共享属性;

可以说我们的每一次编程,内在都有原型对象来发挥着作用,如果你没有掌握原型对象的含义,那么你的js还没有真正的入门!

function a(){};

首先对象 a 是由Function创造出来,是函数对象;那么根据我们以上的教程,a 就有了prototype属性,那么这个原型对象是怎么创造出来的呢?
来看下面这个例子:

var temp = new a();
a.prototype=new Object();
a.prototype = temp;

那么a的prototype属性就是这样创造出来的;

思考:原型对象prototype 属于函数对象吗?

指针__proto__

JavaScript中,万物皆对象!所有的对象obj都具有proto属性(null和undefined除外),可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型

请看以下例子帮助理解:

function a(){};
var obj=new a();
console.log(a.__proto__===Function.prototype); //true
console.log(a.prototype.__proto__===Object.prototype); //true
console.log(obj.__proto__===a.prototype); //true

思考一下,var obj={}; obj.prototype.__proto__指向谁?

构造函数属性constructor

假设 obj 是由函数对象 a 由new运算创造出来的,那么obj的constructor 的属性就存放着一个对 a 的引用,通过这个构造函数,我们还可以为 a添加其他属性和方法,
这个属性的最初设计是为了检测对象的数据类型,不过后来人们通过此属性的特性做了更多的事情

请看以下例子:

function a(){};
var obj=new a();
obj.constructor.b=`我是a的新的属性`;
console.log(a.b); //我是a的新的属性
console.log(a.constructor===Function); //true
console.log(a.prototype.constructor===a); //true
console.log(obj.constructor===a); //true

函数a是由Function创造出来,那么它的constructor指向的Function,obj是由new a()方式创造出来,那么obj.constructor理应指向a

思考:a.prototype.__proto__.constructor指向谁?

思考题解答

函数对象思考题解答

思考: js的引用数据类型都属于函数对象吗?

引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象

那么数组,普通对象,函数对象都算是引用数据类型,引用数据类型范围包含函数对象的范围

普通对象思考题解答

思考:js有五种基本类型:Undefined,Null,Boolean,Number和String,他们都是属于普通对象吗?

基本类型值:指的是保存在栈内存中的简单数据段;除开函数对象之外的对象都是普通对象,那么普通对象范围是包含基本数据类型的

事实上(函数对象,普通对象)以及(基本数据类型,引用数据类型)是在不同角度对js变量进行的定义

原型对象思考题解答

思考:原型对象prototype 属于函数对象吗?

事实上 这个问题要进行分别回答:

Function.prototype 属于函数对象,其他对象的prototype属于普通对象

function a(){};
console.log(typeof Function.prototype); // function
console.log(typeof a.prototype); //object

前面说过prototype的创造过程

    var temp = new a();
    a.prototype = temp;

这里temp当然就是普通对象啦,但是看下Function的prototype创造过程

var a = new Function();
Function.prototype = a;

看明白了把,Function的prototype为什么是函数对象了吧?回忆一下函数对象的定义吧!

指针__proto__思考题解答

思考一下,var obj={}; obj.prototype.__proto__指向谁?

这里分步思考:
1, obj只是一个普通对象
2, 什么类型的对象是有prototype属性的?当然是函数对象
3, 所以obj是没有prototype属性的
4, 所以obj.prototype===undefined
5, 所以此题的最终问题是:undefined.proto指向什么
6, 所有的对象obj都具有proto属性(null和undefined除外)!所以答案是 js报错(有没有一种被我坑了的感觉)

构造器constructor思考题解答

思考:a.prototype.__proto__.constructor指向谁?

function a(){};

这里继续分解题目:
1, a.prototype指向a的一个实例,我们已经多次强调了,而且属于普通对象
2, __proto__定义为:指向创造obj对象的函数对象的prototype属性,所以看下谁创造了a.prototype,因为a.prototype是普通对象,类型为object,那么是Object创造了它,
3, 那么显而易见a.prototype.__proto__指向了Object.prototype
4, 那么题目简化为Object.prototype.constructor指向谁
5, 继续分解题目,Object.prototype为基本对象,那么就是Object创造了它,那么它的constructor就指向了Object

Object.prototype.constructor===Object //true

不知道你晕不晕,我有点晕,这产生了蛋生鸡还是鸡生蛋的问题啦~

放心,还是有尽头的 :

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

这个例子告诉我们是 是null创造了一切““这不就是易经中的:道生一,一生二,二生三,三生万物!

相关文章
|
1月前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
2月前
|
JavaScript 前端开发 开发者
理解JavaScript中的原型链:基础与实践
【10月更文挑战第8天】理解JavaScript中的原型链:基础与实践
|
1月前
|
JavaScript 前端开发
JavaScript 原型链的实现原理是什么?
JavaScript 原型链的实现原理是通过构造函数的`prototype`属性、对象的`__proto__`属性以及属性查找机制等相互配合,构建了一个从对象到`Object.prototype`的链式结构,实现了对象之间的继承、属性共享和动态扩展等功能,为 JavaScript 的面向对象编程提供了强大的支持。
|
1月前
|
JavaScript 前端开发
原型链在 JavaScript 中的作用是什么?
原型链是 JavaScript 中实现面向对象编程的重要机制之一,它为代码的组织、复用、扩展和多态性提供了强大的支持,使得 JavaScript 能够以简洁而灵活的方式构建复杂的应用程序。深入理解和熟练运用原型链,对于提升 JavaScript 编程能力和开发高质量的应用具有重要意义。
|
1月前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
2月前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
39 1
|
2月前
|
JavaScript 前端开发 开发者
深入理解JavaScript原型链:从基础到进阶
【10月更文挑战第13天】深入理解JavaScript原型链:从基础到进阶
35 0
|
2月前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
41 0
|
2月前
|
JavaScript 前端开发 安全
深入理解JavaScript原型链:从基础到进阶
【10月更文挑战第13天】深入理解JavaScript原型链:从基础到进阶
30 0
|
2月前
|
JavaScript 前端开发
JavaScript - 测试 Prototype
JavaScript - 测试 Prototype
17 0