关于js中__proto__和prototype的一些理解<转>
var Person = function (name) { this .name = name; } var p = new Person(); new 操作符的操作是 var p = {} p.__proto__ = Person.prototype Person.call(p) |
var p={}; 也就是说,初始化一个对象p。
p.__proto__ = Person.prototype;
Person.call(p);也就是说构造p,也可以称之为初始化p。
关键在于第二步,我们来证明一下:
var Person = function () {} var p = new Person(); alert(p.__proto__ = Person.prototype) |
这段代码会返回true。说明我们步骤2的正确。
那么__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。
按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。
好,概念说清了,让我们看一下下面这些代码:
var Person = function () { }; Person.prototype.Say = function () { alert( "Person say" ); } var p = new Person(); p.Say(); |
这段代码很简单,相信每个人都这样写过,那就让我们看下为什么p可以访问Person的Say。
首先var p=new Person();可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性,于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了Person.prototype.Say=function(){}; 于是,就找到了这个方法。
好,接下来,让我们看个更复杂的。
var Person = function () { }; Person.prototype.Say = function () { alert( "Person say" ); } Person.prototype.Salary = 50000; var Programmer = function () { }; Programmer.prototype = new Person(); Programmer.prototype.WriteCode = function () { alert( "programmer writes code" ); }; Programmer.prototype.Salary = 500; var p = new Programmer(); p.Say(); p.WriteCode(); alert(p.Salary); |
我们来做这样的推导:
var p=new Programmer()可以得出p.__proto__=Programmer.prototype;
而在上面我们指定了Programmer.prototype=new Person();我们来这样拆分,var p1=new Person();Programmer.prototype=p1;那么:
p1.__proto__=Person.prototype;
Programmer.prototype.__proto__=Person.prototype;
由根据上面得到p.__proto__=Programmer.prototype。可以得到p.__proto__.__proto__=Person.prototype。
好,算清楚了之后我们来看上面的结果,p.Say()。由于p没有Say这个属性,于是去p.__proto__,也就是Programmer.prototype,也就是p1中去找,由于p1中也没有Say,那就去p.__proto__.__proto__,也就是Person.prototype中去找,于是就找到了alert(“Person say”)的方法。
其余的也都是同样的道理。
再来一张stackoverflow上的图:
个人认为prototype可以当成是一个指针,当new一个方法的时候,指向的都是一个内存区域。
看完这些,感觉对原型链的了解应该差不多了吧。
_proto_实际上是指向某个对象实例的属性,而prototype这是其构造器函数的属性,所以两者并不等价;
转自 http://www.cnblogs.com/zzcflying/archive/2012/07/20/2601112.html
关于js中__proto__和prototype的一些理解<转>的更多相关文章
- js中__proto__和prototype的区别和关系?
_proto__(隐式原型)与prototype(显式原型)1.是什么 显式原型 explicit prototype property: 每一个函数在创建之后都会拥有一个名为prototype的属性 ...
- 说一说js中__proto__和prototype以及原型继承的那些事
在面试中遇到过,问js如何实现继承,其实最好的方式就是构造函数+原型,今天在讨论中,发现自己以前理解上的一些误区,特地写出来,最近都比较忙,等手上的项目做完,可以来做个总结. 先说我以前没有认识到位的 ...
- js中 __proto__ 和 prototype
js中的对象都有__proto__属性存在[隐式原型],注意是两个_, 1,javascript对象的__proto__指向的是该对象的构造函数的原型对象,即constructor.prototype ...
- 理解js中__proto__和prototype的区别和关系
首先,要明确几个点:1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点.即:对象具有属性__proto ...
- [转载]js中__proto__和prototype的区别和关系
首先,要明确几个点:1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点.即:对象具有属性_ ...
- js中__proto__和prototype constructor 的区别和关系
https://www.zhihu.com/question/34183746 javaScript原型.原型链的定义? prototype:每个函数都有一个prototype(显式原型),这个属性是 ...
- js中__proto__, property, prototype, 对象自身属性方法和原型中的属性方法的区别
__proto__: 这个属性是实例对象的属性,每个实例对象都有一个__proto__属性,这个属性指向实例化该实例的构造函数的原型对象(prototype). proterty:这个方法是对象的属性 ...
- js中__proto__和prototype的区别和关系
首先,要明确几个点:1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点.即:对象具有属性_ ...
- (转)js中__proto__和prototype的区别和关系
作者:doris链接:https://www.zhihu.com/question/34183746/answer/58155878来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
随机推荐
- Qt 之 QtConcurrent
本文以 Qt 中的 QtConcurrent::run() 函数为例,介绍如何将函数运行在单独的某一个线程中. 1 QtConcurrent::run() QtConcurrent 是一个命名空间, ...
- 【转载】AngularJS监听路由变化
一.Angular 路由状态发生改变时可以通过' $stateChangeStart '.' $stateChangeSuccess '.' $stateChangeError '监听,通过注入'$l ...
- C++ 11 - STL - 函数对象(Function Object) (中)
我们再来看一个复杂的例子 需求: 我们需要对集合内每个元素加上一个特定的值 代码如下: AddInt.h class AddInt { private: int theValue; // the va ...
- vagrant box各种命令汇总
最近在研究laravel,中间用到了vagrant 虚拟机管理工具,学习一下他的命令 vagrant box命令 用于管理boxes的命令,比如添加.删除等等. 此命令的功能主要通过以下子命令完成: ...
- oracle 对系统日期sysdate进行格式化:to_date(sysdate,'yyyy-MM-dd')
oracle 对系统日期sysdate进行格式化:to_date(sysdate,'yyyy-MM-dd') CreateTime--2018年5月17日10:11:34 Author:Maryd ...
- 30、Arrays工具类
1.查询元素 int binarySearch(type[] a,type key):使用二分法查询key元素值在a数组中出现的索引:如果a数组不包含key元素,则返回负数.调用该方法时要求数组中元素 ...
- 位(bit)与字节(byte)
bit就是位,也叫比特位,是计算机表示数据最小的单位. byte就是字节,1byte=8bit,1byte就是1B: 一个字符=2字节: 1KB=1024B 一个英文字母,无论大写和小写都是一个字符: ...
- 【php写日志】php将日志写入文件
php 写内容到文件,把日志写到log文件 <?php header("Content-type: text/html; charset=utf-8"); /******** ...
- HQL的select new map ···语法
通常hibernate查询出的结果集是类似于 List<T> 或 List<Object[]> 的类型 类似于下面这个方法 public List<SfJmsfT> ...
- PHP - MAC下PhpStorm安装调试环境xdebug
今天下午一直在捣鼓如何用PhpStorm进行调试,查找了许多资料,零零碎碎的,所以自己弄篇文章记录一下步骤. 安装xdebug 使用brew安装xdebug,语法如下 brew install hom ...