javascript prototype __proto__区别
2013-07-27 10:49 youxin 阅读(1919) 评论(0) 编辑 收藏 举报An Object's __proto__
property references the same object as its internal [[Prototype]]
(often referred to as "the prototype"), which may be an object or, as in the default case of Object.prototype.__proto__,
null
. This property is an abstraction error, because a property with the same name, but some other value, could be defined on the object too. If there is a need to reference an object's prototype, the preferred method is to use Object.getPrototypeOf
.
A __proto__
pseudo property has been included in §B.3.1 of the draft ECMAScript ed. 6 specification (note that the specification codifies what is already in implementations and what websites may currently rely on).
var proto = obj.__proto__;
一个对象的__proto__
属性和自己的内部属性[[Prototype]]指向一个相同的值
(通常称这个值为原型),原型的值可以是一个对象值也可以是null
(比如说Object.prototype.__proto__的值就是null
).该属性可能会引发一些错误,因为用户可能会不知道该属性的特殊性,而给它赋值,从而改变了这个对象的原型. 如果需要访问一个对象的原型,应该使用方法Object.getPrototypeOf
.
__proto__
属性已经被添加在了ES6草案 §B.3.1中.
不要认为__proto__和prototype相等。
Description
When an object is created, its __proto__
property is set to reference the same object as its internal [[Prototype]]
(i.e. its constructor's prototype
object). Assigning a new value to __proto__
also changes the value of the internal [[Prototype]]
property, except where the object is non–extensible.
To understand how prototypes are used for inheritance, see the MDN article Inheritance and the prototype chain.
当一个对象被创建时,它的 __proto__
属性和内部属性[[Prototype]]指向了相同的对象
(也就是它的构造函数的prototype
属性).改变__proto__
属性的值同时也会改变内部属性[[Prototype]]的值
,除非该对象是不可扩展的.
想要知道如何使用原型来实现继承,查看MDN文章继承和原型链.
Example
In the following, a new instance of Employee
is created, then tested to show that its __proto__
is the same object as its constructor's prototype
.
// 声明一个函数作为构造函数function Employee() { /* 初始化实例 */ } // 创建一个Employee实例 var fred = new Employee(); // 测试相等性 fred.__proto__ === Employee.prototype; // true
这是, fred
继承了 Employee
, 但是如果给fred.__proto__
赋另外一个对象值,则会改变它的继承对象:
// Assign a new object to __proto__ fred.__proto__ = Object.prototype;
现在,fred不在继承于
Employee.prototype
, 而是直接继承了Object.prototype
, 也就丢失了所有从Employee.prototype
继承来的属性.
可是,这只适用于可扩展的 对象,一个不可扩展的对象的 __proto__
属性是不可变的:
var obj = {}; Object.preventExtensions(obj); obj.__proto__ = {}; // throws a TypeError
Note that even Object.prototype
's __proto__
property can be redefined as long as the chain leads to null:
var b = {}; Object.prototype.__proto__ = { hi: function () {alert('hi');}, __proto__: null }; b.hi();
If Object.prototype
's __proto__
had not been set to null
, or had not been set to another object whose prototype chain did not eventually lead explicitly to null
, a "cyclic __proto__ value" TypeError would result since the chain must eventually lead to null
(as it normally does on Object.prototype
).
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
上面的
bject.prototype.__proto__不能改成
bject.prototype.prototype.
为什么?
我们可以:
function func(){};
alert(typeof Object.prototype);//Object,不是Function
alert(typeof func); //Function。
可以看出Object.prototype是一个object,没有prototype属性.alert( Object.prototype.prototype);显示undefined。
(从这里我们可以看出Object 是 一个function,typeof Object 为function。)
prototype
is a property of a Function object. It is the prototype of objects constructed by that function.
只有函数才有prototype属性,对象没有。
我们可以看stackoverflow上的一个问题:
This figure again shows that every object has a prototype. Constructor function Foo also has its own
__proto__
which is Function.prototype, and which in turn also references via its__proto__
property again to the Object.prototype. Thus, repeat, Foo.prototype is just an explicit property of Foo which refers to the prototype of b and c objects.
var b =new Foo(20);var c =new Foo(30);
What are the __proto__
and the prototype
properties?
(要仔细理解这幅图 typeof Object=='function' 为true,说明Object类型为function。
Foo.prototype.__proto__ === Object.prototype 为true。
(个人理解:上面的b->Foo.prototype-->Object.prototype组成了一条链,但b没有在自己中找到相应的属性和方法时,就会向上去寻找 。我们可以这么理解,继承与prototype无关,而与__proto__有关。?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。
参考:http://www.cnblogs.com/youxin/archive/2013/03/08/2950751.html
可以看到,Function.prototype是函数Foo的__proto__。我们只要在Function.prototype增加了一个方法,所有的函数都可以调用这个方法,如《javascript精粹》中的一个例子:
Function.prototype.method=function(name,func){ if(!this.prototype[name]){ this.prototype[name]=func; } return this; }; Foo.method("say2",function(){alert("say2");}); //和上面的话作用一样:Foo.prototype.say2=function(){alert("say2");}; var c=new Foo(); c.say2();
)
下面的这段代码是我编的。
function Foo(){}
var b=new Foo();
alert(Foo.prototype==Foo.__proto__); //false
alert( Foo.__proto__); //function Empty(){}
alert(Foo.prototype); //[object object]
alert(Foo.prototype.constructor); //function Foo(){}
与上图对应的代码:
// a constructor function function Foo(y) { // which may create objects // by specified pattern: they have after // creation own "y" property this.y = y; } // also "Foo.prototype" stores reference // to the prototype of newly created objects, // so we may use it to define shared/inherited // properties or methods, so the same as in // previous example we have: // inherited property "x" Foo.prototype.x = 10; // and inherited method "calculate" Foo.prototype.calculate = function (z) { return this.x + this.y + z; }; // now create our "b" and "c" // objects using "pattern" Foo var b = new Foo(20); var c = new Foo(30); // call the inherited method b.calculate(30); // 60 c.calculate(40); // 80 // let's show that we reference // properties we expect console.log( b.__proto__ === Foo.prototype, // true c.__proto__ === Foo.prototype, // true // also "Foo.prototype" automatically creates // a special property "constructor", which is a // reference to the constructor function itself; // instances "b" and "c" may found it via // delegation and use to check their constructor b.constructor === Foo, // true c.constructor === Foo, // true Foo.prototype.constructor === Foo // true b.calculate === b.__proto__.calculate, // true b.__proto__.calculate === Foo.prototype.calculate // true );
具体参考:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
答案1:
__proto__
is internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(O)
method, though de facto standard __proto__
is quicker.
You can find instanceof
relationships by comparing a function's prototype
to an object's__proto__
chain, and you can break these relationships by changing prototype
.
function Point(x, y) { this.x = x; this.y = y; } var myPoint = new Point(); // the following are all true myPoint.__proto__ == Point.prototype myPoint.__proto__.__proto__ == Object.prototype myPoint instanceof Point; myPoint instanceof Object;
Here Point
is a constructor function, it builds an object (data structure) procedurally. myPoint
is an object constructed by Point()
so Point.prototype
gets saved to myPoint.__proto__
at that time.
答案2:
__proto__
is the actual object that is used in the lookup chain to resolve methods, etc. prototype
is the object that is used to build __proto__
when you create an object with new
:
(new Foo).__proto__ ===Foo.prototype
(newFoo).prototype ===undefined
转自:http://stackoverflow.com/questions/9959727/what-is-the-difference-between-proto-and-prototype-in-javascript
看以前写的: