简单地说,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) // true
console.log(p2.__proto__ === Person.prototype) // false
console.log(p2.__proto__ === Person.prototype.constructor) // true

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

浅谈prototype和__proto__的更多相关文章

  1. JavaScript中toStirng()与Object.prototype.toString.call()方法浅谈

    toStirng()与Object.prototype.toString.call()方法浅谈 一.toString()是一个怎样的方法?它是能将某一个值转化为字符串的方法.然而它是如何将一个值从一种 ...

  2. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

  3. 浅谈javascript的原型及原型链

    浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为 ...

  4. javascript中的prototype和__proto__的理解

    在工作中有时候会看到prototype和__proto__这两个属性,对这两个属性我一直比较蒙圈,但是我通过查阅相关资料,决定做一下总结加深自己的理解,写得不对的地方还请各位大神指出. 跟__prot ...

  5. JS function 是函数也是对象, 浅谈原型链

    JS function 是函数也是对象, 浅谈原型链 JS 唯一支持的继承方式是通过原型链继承, 理解好原型链非常重要, 我记录下我的理解 1. 前言 new 出来的实例有 _proto_ 属性, 并 ...

  6. 浅谈JavaScript之原型

    上一篇谈new关键字也是给这一篇写关于原型的文章买个伏笔,我对原型的理解可能会有偏差,如有错误,望指正一定修改,望各位道友如果想真正的理解原型的概念一定要再看完各方言论再回归教材. 言归正传谈原型,首 ...

  7. 浅谈JavaScript浮点数及其运算

    原文:浅谈JavaScript浮点数及其运算     JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题 ...

  8. 浅谈 js 字符串 search 方法

    原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是 ...

  9. 车大棒浅谈jQuery源码(二)

    前言 本来只是一个自己学习jQuery笔记的简单分享,没想到获得这么多人赏识.我自己也是傻呵呵的一脸迷茫,感觉到受宠若惊. 不过还是有人向批判我的文章说,这是基本知识点,完全跟jQuery源码沾不上边 ...

随机推荐

  1. 转:js,jQuery 排序的实现,网页标签排序的实现,标签排序

    js,jQuery 排序的实现: 重点: 想要实现排序,最简单的方法就是 先把标签用jQuery读进对象数组 用js排序好对象数组 (针对对象数组进行排序, 不要试图直接对网页的内容进行直接更改) 用 ...

  2. web中关于垃圾回收的一些观点

    感觉dom大神的解惑 关于引用计数法,注意引用的方向性就行.  A.addEventListner(B.func), 那么是增加了A对B的引用.如果A是不可回收的对象,比如全局的Stage,或者单例. ...

  3. 手机自动化测试:Appium源码之api(1)

    手机自动化测试:Appium源码之api(1)   AppiumDriver getAppStrings() 默认系统语言对应的Strings.xml文件内的数据. driver.getAppStri ...

  4. 在IIS上部署你的ASP.NET Core项目

    概述 与ASP.NET时代不同,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角色转发请求到Kest ...

  5. Android 开发之错误整理 [2014-04-28 09:22:28 - XXXX] Unable to resolve target 'android-18'

    在开发的时候难免会导入项目,那么怎么经常会遇到这个错误: [2014-04-28 09:22:28 - XXXX] Unable to resolve target 'android-18' targ ...

  6. git clone时出现 error:inflate:data stream error(incorrect data check)

    git clone时出现 error:inflate:data stream error(incorrect data check) fatal:serrious inflate inconsiste ...

  7. C语言本身并不提供输入输出语句

    C语言本身并不提供输入输出语句,输入和输出操作是由函数来实现的.在C标准函数库中提供了一些输入输出函数,例如,printf函数和scanf函数.在使用他们时,千万不要误认为他们是C语言提供的“输入输出 ...

  8. java多线程基本概述(一)——线程的基本认知

    1.1.概念: 进程:进程是操作系统结构的基础,是一次程序的执行:是一个程序及其数据再处理器上顺序执行时所发生的活动:是程序再一个数据集合上运行的过程,它是系统进行系统资源分配和调度的最小单元. 线程 ...

  9. salt-stack部署

    saltstack部署   环境准备 [root@server elasticsearch]# cat /etc/redhat-release CentOS release 6.6 (Final)[r ...

  10. Zepto 添加手势判断拓展方法(思路+原理)

    一.前言 这几个月事情比较多,写了一些博客都没有来得及整理发布,今天刚好有一位同事在开发前端页面的时候用到了手势判断.所以翻出了之前写的 demo,顺便整理一下作为记录. 手势判断在各种应用中都十分常 ...