一、区别

隐式原型 __proto__ 是所有对象(包括函数都有的);
普通对象的__proto__指向创建该实例的构造函数的原型对象
**任何构造函数的 __proto__ 指向 Function.prototype **
假如 F 是任意的构造函数

F.__proto__ === Function.prototype;
Function.prototype.__proto__ === Object.prototype;
 
F instanceof Function; // true
F instanceof Object; // true

F 是任意的构造函数,所以 F 可以是 FunctionObject,上面隐含:所以

Function instanceof Function; // true
Object instanceof Function; // true
Function instanceof Object; // true
Object instanceof Object; // true
Number instanceof Function; // true

MathJSON 是以对象形式存在的,无需 new。它们的 protoObject.prototype

F 是任意构造函数,FF 是除 FunctionObject 之外的构造函数

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 的好处

  • 在函数上 prototype 属性定义的对象方法,是非静态方法
    • 通过类名 prototype 去访问该方法调用【内部不能使用 this】;
    • 实例化,通过实例调用,其方法内部可以 this 来引用对象自身中的其他属性;
  • 直接在函数定义对象方法,是静态方法
    • 只能通过类名去访问该方法调用【内部不能使用 this】;

先有的Object.prototypeObject.prototype构造出Function.prototype,然后Function.prototype构造出ObjectFunctionObject.prototype是鸡,ObjectFunction都是蛋。

普通对象的__proto__指向创建该实例的构造函数的原型对象
任何构造函数的__proto__指向Function.prototype

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐