说到prototype,就不得不先说下new的过程。
我们先看看这样一段代码:
var Person = function () { };
var p = new Person();
很简单的一段代码,我们来看看这个new究竟做了什么?我们可以把new的过程拆分成以下三步:
<1> var p={}; 也就是说,初始化一个对象p。
<2> p.__proto__=Person.prototype;
<3> Person.call(p);也就是说构造p,也可以称之为初始化p。
关键在于第二步,我们来证明一下:
var Person = function () { };
var p = new Person();
alert(p.__proto__ === Person.prototype);//true
这段代码会返回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”)的方法。
其余的也都是同样的道理。
这也就是原型链的实现原理。
最后,其实prototype只是一个假象,他在实现原型链中只是起到了一个辅助作用,换句话说,他只是在new的时候有着一定的价值,而原型链的本质,其实在于__proto__!
分享到:
相关推荐
js函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针__proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直...
主要介绍了JS原型prototype和__proto__用法,结合实例形式分析了JS原型prototype和__proto__使用方法及相关操作注意事项,需要的朋友可以参考下
且,构造函数的原型对象中有一个__proto__(隐式原型对象)指向Object的原型对象。 注2:Object函数的原型对象中也有一个属性__proto__(隐式原型对象).但这个隐式原型对象的值不再指向另一个原型对象,而是为null.
在Javascript中,如果我们有一个对象但是又不知道它的构造函数时,如何获取它的原型对象呢? 在Chrome中或是FireFox浏览器中,我们可以直接使用对象的__proto__属性获取它的原型对象。 代码如下: <!– lang: js ...
分析javascript中 prototype __proto__ constructor之间的关系
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。(这个对象下面有个属性,这个属性是另外一个对象的应用 ,这个属性就是一个对象...
这里讨论下对象的内部原型(__proto__)和构造器的原型(prototype)的关系。 一、所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function) 代码如下: Number.__proto__ === Function....
__proto__是内部原型,prototype是构造器原型(构造器其实就是函数) 构造器的原型(prototype)是一个对象 那什么是构造器呢? 要想创建一个对象,首先要有一个对象构造器,就像php里面一样,要想创建一个对象,...
主要介绍了JavaScript中的__proto__属性,对于JavaScript中所谓的对象来讲,它指向对象的原型prototype,需要的朋友可以参考下
1. 原型链的形成真正是靠__proto__ 而非 prototype,当 JS 引擎执行对象的 2. 一个对象的__proto__记录着自己的原型链,决定了自
判断属性是存在实例对象中,还是存在原型对象中的方法 获取或遍历对象中属性的几种方法 1、prototype 每个函数都有一个prototype属性,该属性是一个指针,指向一个对象。 而这个对象的用途是包含由特定类型的所有...
本文实例分析了Javascript原型链的原理。分享给大家供大家参考,具体如下: 一、JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一...
主要介绍了详解帮你彻底搞懂JS中的prototype、__proto__与constructor(图解),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
一、深入理解prototype...比如C.prototype = xxx,这样就会让使用new C()得到的对象的原型对象为xxx。当然使用obj.prototype也能够得到obj的原型对象。 getPropertyOf: Object.getPropertyOf(obj)是ES5中用来得到obj对
应该是上采样 tensor_proto.raw_data().empty() || !...# -*- coding: utf-8 -*- import onnx import os import time import cv2 import numpy as np net = cv2.dnn.readNetFromONNX(r'onnx_model/0.onnx')
本文实例讲述了JS学习笔记之原型链和利用原型实现继承。分享给大家供大家参考,具体如下: 原型链 原型链是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的 实例对象中有__proto__,是...
proto_db-master.zip proto_db-master.zip proto_db-master.zip 一个基于google protocol buffer 的orm
作为一名前端工程师,必须搞懂JS中的prototype、__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞懂它们。这里说明一点,__proto__...
prototype警告:学习了解原型模式前需先学习原型、原型链、prototype、__proto__、constructor等知识; 实现原型模式 ES5中的API:Object.create(prototype, optionalDescriptorObjects) Object.create()方法...