构造函数:function Foo() {};

实例对象: let f1 = new Foo;

let o1 = new Foo;

一般函数都有prototype属性,除了window.Math和Function.prototype.bind()(该属性指向原型)等

一般对象都有__proto__属性,除了Object.create(null)等,该属性指向了创建该对象的构造函数的原型。其实这个属性指向了[[prototype]],但是[[prototype]]是内部属性,我们并不能访问到,所有采用__proto__来访问。总之,对象可以通过__proto__来访问不属于该对象的属性,__proto__将对象连接起来组成了原型链。

概念:

1.构造函数:用来初始化新创建的对象的函数是构造函数。上例中,Foo()函数是构造函数。

2.实例对象:通过构造函数的new操作创建的对象是实例对象。(可以用一个构造函数,构造多个实例对象)

function Foo(){};
var f1 = new Foo;
var f2 = new Foo;
console.log(f1 === f2);//false

3.原型对象及prototype:构造函数有一个prototype属性,指向对应实例对象的原型对象。通过同一个构造函数实例化的多个对象具有相同的原型对象。这个属性可以用来实现继承。

function Foo(){};
Foo.prototype.a = 1;
var f1 = new Foo;
var f2 = new Foo; console.log(Foo.prototype.a);//
console.log(f1.a);//
console.log(f2.a);//

4.constructor:原型对象有一个constructor属性,指向该原型对象对应的构造函数。由于实例对象可以继承原型对象的属性,所以实例对象也拥有constructor属性,同样指向原型对象对应的构造函数。

console.log(Foo.prototype.constructor === Foo);//true
console.log(f1.constructor === Foo);//true

5.__ptoto__:实例对象有一个__proto__属性,指向该实例对象对应的原型对象。

console.log(f1.__proto__ === Foo.prototype);//true

第一部分:Foo

1、实例对象f1是通过构造函数Foo()的new操作创建的。构造函数Foo()的原型对象是Foo.prototype;实例对象f1通过__proto__属性也指向原型对象Foo.prototype。

console.log(f1.__proto === Foo.prototype);//true

2、实例对象f1本身并没有constructor属性,但它可以继承原型对象Foo.prototype的constructor属性

console.log(Foo.prototype.constructor === Foo);//true
console.log(f1.constructor === Foo);//true
console.log(f1.hasOwnProperty('constructor'));//false

实例对象f1的控制台效果

第二部分:Object

1、Foo.prototype是f1的原型对象,同时它也是实例对象。实际上,任何对象都可以看做是通过Object()构造函数的new操作实例化的对象 所以,Foo.prototype作为实例对象,它的构造函数是Object(),原型对象是Object.prototype。相应地,构造函数Object()的prototype属 性指向原型对象Object.prototype;实例对象Foo.prototype的proto属性同样指向原型对象Object.prototype。
console.log(Foo.prototype.__proto__ === Object.prototype);//true

2、实例对象Foo.prototype本身具有constructor属性,所以它会覆盖继承自原型对象Object.prototype的constructor属性。

console.log(Foo.prototype.constructor === Foo);//true
console.log(Object.prototype.constructor === Object);//true
console.log(Foo.prototype.hasOwnProperty('constructor'));//true

下图是实例对象Foo.prototype的控制台效果

3、Object.prototype作为实例对象的话,其原型对象是null。

console.log(Object.prototype.__proto__ === null);//true

1、前面已经介绍过,函数也是对象,只不过是具有特殊功能的对象而已。任何函数都可以看做是通过Function()构造函数的new操作实例化的结果。如果把函数Foo当成实例对象的话,其构造函数是Function(),其原型对象是Function.prototype;类似地,函数Object的构造函数也是Function(),其原型对象是Function.prototype。
console.log(Foo.__proto__ === Function.prototype);//true
console.log(Object.__proto__ === Function.prototype);//true
2、原型对象Function.prototype的constructor属性指向构造函数Function();实例对象Object和Foo本身没有constructor属性,需要继承原型对象Function.prototype的constructor属性。
console.log(Function.prototype.constructor === Function);//true
console.log(Foo.constructor === Function);//true
console.log(Foo.hasOwnProperty('constructor'));//false
console.log(Object.constructor === Function);//true
console.log(Object.hasOwnProperty('constructor'));//false
3、所有的函数都可以看成是构造函数Function()的new操作的实例化对象。那么,Function可以看成是调用其自身的new操作的实例化的结果。所以,如果Function作为实例对象,其构造函数是Function,其原型对象是Function.prototype。
console.log(Function.__proto__ === Function.prototype);//true
console.log(Function.prototype.constructor === Function);//true
console.log(Function.prototype === Function.prototype);//true
4、如果Function.prototype作为实例对象的话,其原型对象是什么呢?和前面一样,所有的对象都可以看成是Object()构造函数的new操作的实例化结果。所以,Function.prototype的原型对象是Object.prototype,其原型函数是Object()。
console.log(Function.prototype.__proto__ === Object.prototype);//true

总结:

1、函数(Function也是函数)是new Function的结果,所以函数可以作为实例对象,其构造函数是Function(),原型对象是Function.prototype;

2、对象(函数也是对象)是new Object的结果,所以对象可以作为实例对象,其构造函数是Object(),原型对象是Object.prototype;

3、Object.prototype的原型对象是null。

JavaScript的原型(prototype、__proto__、constructor)的更多相关文章

  1. Javascript Prototype __proto__ constructor 三者的关系

    JavaScript三大毒瘤 --- this,原型链,作用域 在我等菜鸟一步一步升级中的过程中,这三个概念总是困扰这我们(可能只有我吧,我比较蠢).这三个东西往往都很绕,今天我就来分享一下我对原型. ...

  2. javascript中的prototype和constructor

    构造函数 我们知道,ECMAScript5中的Object.Array.Date.RegExp.Function等引用类型都是基于构造函数的,他们本身就是ECMAScript5原生的构造函数.比如,我 ...

  3. 简单理解javascript的原型prototype

    原型和闭包是Js语言的难点,此文主要讲原型. 每一个方法都有一个属性是 prototype 每一个对象都有一个属性是 _proto_ 一旦定义了原型属性或原型方法,则所有通过该构造函数实例化出来的所有 ...

  4. 悟透Javascript之 原型prototype

    构造函数的Prototype上定义的方法确实可以通过对象直接调用,而且代码是共享的.我表示我不懂.太难理解了,艹.在Javascript中,prototype不但能让对象共享自己的财富,而且proto ...

  5. [js高手之路]一步步图解javascript的原型(prototype)对象,原型链

    我们接着上文继续,我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉. function CreateObj(uName) { this ...

  6. JavaScript中的 prototype 和 constructor

    prototype属性  任何js函数都可以用作构造函数, 而构造函数需要用到prototype属性, 因此, 每个js函数F(除了ES5的Function.bind()方法返回的函数外) 都自动拥有 ...

  7. JavaScript 面向对象 原型(prototype) 继承

    1.对象的概念:无需属性的集合,属性可以为数值,对象或函数,ECMAscript中没有类的概念,这点是javascript与其他面向对象(OO)语言不同的地方. //创建一个自定义对象 var per ...

  8. javascript进阶-原型prototype

    一.javascript原型认识 很多编程语言都有类的概念,我们可以拿原型和类进行比较,看看它们之间的区别以及相同点在哪里. 1.类:类是一个具体事物的抽象所以类是一个抽象的东西,在面向对象中类可以用 ...

  9. JavaScript:Function/Object/prototype/__proto__

    console.log(Object.__proto__===Function.prototype); //true console.log(Object.prototype.__proto__); ...

  10. js in depth: Object & Function & prototype & __proto__ & constructor & classes inherit

    js in depth: Object & Function & prototype & proto & constructor & classes inher ...

随机推荐

  1. Visual Studio 安装OpenCV及问题总结

    1.VS安装OpenCV基本步骤 1)安装Visual Studio 下载网址https://opencv.org/releases.html# 2)安装OpenCV 下载网址https://www. ...

  2. C# 深入理解String

    关于C#中的类型 在C#中类型分为值类型和引用类型,引用类型和值类型都继承自System.Object类,几乎所有的引用类型都直接从System.Object继承,而值类型具体一点则继承System. ...

  3. 读《Wireshark网络分析就这么简单》读书笔记

    晚上花了两个多小时看完这本书,记录下一些看书过程中的笔记. 一.问题:A和B 是否能正常通信? 两台服务器A和服务器B的网络配置 A                                  ...

  4. 在windows上用netsh动态配置端口转发

    使用多个虚拟机,将开发环境和工作沟通环境分开(即时通,办公系统都只能在windows下使用…),将开发环境的服务提供给外部访问时,需要在主机上通过代理配置数据转发. VirtualBox提供了端口转发 ...

  5. tomcat常用技巧

    1. 修改Tomcat的名称 适用场景: 在测试服务器资源有限或是在本机服务器部署多套应用系统时,由于要启动多个TOMCAT服务,且TOMCAT服务没有用名称去区分,会造成维护使用上存在一定晨读的不方 ...

  6. python发送邮件(带附件)

    python通过stmp发送qq邮件,带附件 import smtplib from email.mime.multipart import MIMEMultipart from email.mime ...

  7. sass(混合mixin的调用、@content)

    sass中使用@mixin声明混合,可以传递参数,参数名以$符号开始,多个参数以逗号分开,也可以给参数设置默认值.声明的@mixin通过@include来调用 1.无参数mixin scss.styl ...

  8. vue.extend与vue.component的区别和联系

    一味的闷头开发,却对基础概念缺乏理解,是个大坑... 查阅官网后现对自己的理解记录一下,用于日后复习巩固 Vue.extend({}) 简述:使用vue.extend返回一个子类构造函数,也就是预设部 ...

  9. CSS深入理解学习笔记之padding

    1.padding与容器尺寸之间的关系 对于block水平元素:①padding值暴走,一定会影响尺寸:②width非auto,padding影响尺寸:③width为auto或box-sizing为b ...

  10. C++基础--static的用法

    首先,看看变量的存储: int global ; int main() { int stackStore ; int heapStore* = (int *)malloc(sizeof(int)); ...