一:区别
隐式原型__proto__是所有对象(包括函数都有的);
普通对象的__proto__指向创建该实例的构造函数的原型对象
任何构造函数的__proto__指向Function.prototype
F是任意的构造函数;
F.__proto__ === Function.prototype;
Function.prototype.__proto__ === Object.prototype;
F instanceof Function; // true
F instanceof Object; // true
因为F可以是Function,Object, 上面隐含:
所以:
Function instanceof Function; // true
Object instanceof Function; // true
Function instanceof Object; // true
Object instanceof Object; // true
Number instanceof Function; // true
…
Math,JSON是以对象形式存在的,无需new。它们的proto是Object.prototype
F是任意构造函数,FF是除Function, Object之外的构造函数
F instanceof FF; // false
FF instanceof FF; // false;
prototype只有函数有;
所有构造器都继承了·Function.prototype·的属性及方法。如length、call、apply、bind、callee(函数引用)、caller(函数的调用者)
callee 返回一个正在被执行函数的引用 (这里常用来递归匿名函数本身 但是在严格模式下不可行)
二:原型链是什么?
原型链是针对构造函数的。通过new创建函数,new出来的函数就会继承创建他的函数的属性。如果访问new函数的某个未在当前函数中定义的变量,他就会往上查找(像创建他的函数),这个查找的过程就叫做原型链;
例:
var Person=function(){
Person.prototype.say=function(){
alert('hello word!')
}
};
var p = new Person();
p.say(); //alert('hello word!')
三:说明 prototype与proto的关系
var Person=function(){ };
var p = new Person();
看看new 做了什么??
var p={ }; //第一步:创建一个对象
p.__proto__=Person.prototype;//第二步
Person.call(p);//第三步:构造p(初始化p);
验证下第二步
var Person=function(){ };
var p = new Person();
console.log(p.proto=Person.prototype) // true
例子:
var Person = function () {};
Person.prototype.alert= function () {
alert("Person alert");
}
Person.prototype.time= 50000;
var Programmer = function () {};
Programmer.prototype = new Person();
//var p1=new Person();Programmer.prototype=p1
//p1.__proto__=Person.prototype;
//Programmer.prototype.__proto__=Person.prototype;
Programmer.prototype.prompt = function () {
alert("programmer prompt something");
};
Programmer.prototype.time= 500;
var p = new Programmer();//p.__proto__=Programmer.prototype;
p.alert();// alert("Person alert");
p.prompt ();// alert("programmer prompt something");
alert(p.time);//500
/
/根据上面得到
p.__proto__=Programmer.prototype。
//得到
p.__proto__.__proto__=Person.prototype。
//其实prototype只是一个假象,他在实现原型链中只是起到了一个辅助作用,原型链的本质,其实在于__proto__
四:使用场景
prototype:写一个js类,需要继承的你都放这个属性下
__proto__你基本不会去用,js引擎实现原型链用的,原型链看上面。
五:对象使用prototype的好处
1)不使用prototype属性定义的对象方法,是静态方法,只能直接用类名进行调用!另外,此静态方法中无法使用this变量来调用对象其他的属性!
2)使用prototype属性定义的对象方法,是非静态方法,只有在实例化后才能使用!其方法内部可以this来引用对象自身中的其他属性!
先有的Object.prototype, Object.prototype构造出Function.prototype,然后Function.prototype构造出Object和Function。Object.prototype是鸡,Object和Function都是蛋。
普通对象的__proto__指向创建该实例的构造函数的原型对象
任何构造函数的__proto__指向Function.prototype