__proto__(隐式原型)和prototype(显式原型)

一:区别

隐式原型__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

你可能感兴趣的:(javascript,js,prototype)