博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
prototype和__proto__
阅读量:4605 次
发布时间:2019-06-09

本文共 1787 字,大约阅读时间需要 5 分钟。

简单地说,prototype就是原型对象的一个开放接口,让我们可以为对象的实例扩展属性和方法。

先看一下对象的静态方法和实例方法。

function Person () {};Person.sayHello = function () { //定义一个静态方法  console.log("Hello!");};var p = new Person();Person.sayHello(); // Hello!p.sayHello(); // p.sayHello is not a function

由此可以看出,对象的静态方法不能被对象实例调用。例如String对象的fromCharCode()方法,正确的调用方法应该是 String.fromCharCode(),而使用 myString.fromCharCode()会报错。

如果我们想给对象的实例添加方法,可以在构造函数中使用"this"来定义:

var Person = function () {  this.sayHello = function () {    console.log("Hello!");  }};var p = new Person();p.sayHello(); // Hello!

构造函数模式虽然好用,但有个很大的缺点,那就是每个方法都会在每个实例上重新创建一遍。例如,我们创建两个Person实例,p1和p2都有一个名为sayHello()的方法,但这两个方法不是同一个Function的实例。

var Person = function () {  this.sayHello = function () {    console.log("Hello!");  }};var p1 = new Person();var p2 = new Person();console.log(p1.sayHello == p2.sayHello); // false

因为JavaScript中函数也是对象,因此每定义一个函数就会实例化一个Function对象,造成了不必要的内存开销。另外,使用this创建实例方法也并不总是可行的。例如我们想给Date对象实例扩展一个format()方法,我们总不能直接修改Date的源码吧,而用prototype就很简单了:

Date.prototype.format = function () {  //do something...}var time = new Date();time.format();

下面说一下__proto__。当调用构造函数创建一个新实例后,该实例内部会包含一个指针,指向构造函数的原型对象。这个指针在ECMA-262第5版上叫[[Prototype]],虽然没有标准方式访问[[Prototype]],但在Firefox、Safari和Chrome等浏览器上都实现了一个__proto__属性来访问它。当解析器查找实例上的某个属性时,如果没有查找到,就会在__proto__上查找,而__proto__指向构造函数的原型对象,这就是多个对象实例共享原型的属性和方法的基本原理。

简单的说就是,p.__proto__ === p.constructor.prototype

但也有例外,那就是使用Object.creat创建对象的时候。

function Person () {};var p1 = new Person();var p2 = Object.create(Person)console.log(p1.__proto__ === Person.prototype) // trueconsole.log(p2.__proto__ === Person.prototype) // falseconsole.log(p2.__proto__ === Person.prototype.constructor) // true

一般情况下,对象的__proto__等于其构造函数的prototype ,而使用Object.create()创建的对象,其__proto__等于其原型对象的构造函数。

转载于:https://www.cnblogs.com/huanglei-/p/6798227.html

你可能感兴趣的文章
【Ant】Ant实例(1)一个Java文件依赖于某jar包,需要打包部署
查看>>
event
查看>>
第一篇自己完成的宏汇编
查看>>
jQuery Ajax验证实例
查看>>
局部内部类访问局部变量,会有什么想象?为什么?(jdk1.8以下)
查看>>
HDU 2647 Reward(拓扑排序+判断环+分层)
查看>>
前端访问Tornado跨域问题
查看>>
react 父组件与子组件双向绑定
查看>>
[HDU](3746)Cyclic Nacklace ---KMP(串)
查看>>
爬虫之scrapy框架的crawlspider
查看>>
HttpServletRequest对象方法的用法
查看>>
Android布局学习
查看>>
实时通讯与非实时通讯
查看>>
jQuery中事件绑定与解绑
查看>>
js原生Ajax的封装与使用
查看>>
周总结6
查看>>
PostgreSQL 务实应用(二/5)插入冲突
查看>>
一种公众号回复关键词机制
查看>>
java多线程入门学习(一)
查看>>
基于 Web 的 Go 语言 IDE - Wide 1.1.0 公布!
查看>>