咱们本次的解释,主要经过下图java
粗看该图,估计你不必定能看明白。不过接下来让我逐行向你解释。函数
- 最左侧:意思是,有两个对象f1和f2,他们是经过new Foo()出来的。
- 中间:Foo()就是最左侧用到的Foo()
- 最右侧:表示,函数Foo()的prototype属性!
JS_Object和Function的区别javascript
咱们本次的解释,主要经过下图java
粗看该图,估计你不必定能看明白。不过接下来让我逐行向你解释。函数
function Foo() { } var f1 = new Foo(); alert(f1.__proto__ == Foo.prototype);?function Object(){[native code]}//Javascript自带,不是自定义的,能够近似认为是基类
function Function(){[native code]}//Javascript自带,不是自定义的,能够近似认为是基类prototype
?code
这里的这两个function,分别走两个方向,
Object做为了众多object(实例,new出来的)的基类型
Function做为众多function(主要是那些function出来的,就是定义出来的函数)的基类型htm
?对象
在开始下面更细致的解释先,咱们约定一些内容,Object表明这里所说的Object,object表明实例对象
,Function表明这里说的Function,function是关键字。对于Object与object的区别很好理解,一个是function,一个是new出来。blog
?ip
如今让咱们思考两个问题:
第一个,当咱们扩展Object原型时,new出来的Function,是否会被扩展?
第二个,当咱们扩展Function原型时,因为Object也是个Function,那么其实例object是否会被扩展get
?
先看第一个问题.eg.
?
Object.prototype.test4extend="123";//扩展Object的原型 document.write("Function:"+Function.test4extend);//在Function中出现了test4extend属性 document.write("<br>") document.write("Object:"+Object.test4extend);//在Object中出现了test4extend属性,此时Object仍是个Function document.write("<br>") var obj=new Object; document.write("Object instance:"+obj.test4extend);//在obj中扩展了test4extend,此时的obj是object document.write("<br>") function Foo() { } var foo = new Foo; document.write("foo object:"+foo.test4extend);//foo对象上扩展上了test4extend属性 document.write("<br>") document.write("Foo Function:"+Foo.test4extend);//函数上也扩展上了test4extend属性 document.write("<br>") console.log("Object", Object); console.log("Function", Function);?注释已经写得很清晰了,经过以上几点咱们很容易发现如下几点:
?
一、Object扩展了全部的object(obj,foo),与object扩展自Object是相符的。在这里更加验证了。接下来看看第二个问题
Function.prototype.test4extend="123";//扩展Function的原型 document.write("Function:"+Function.test4extend);//在Function中出现了test4extend属性 document.write("<br>") document.write("Object:"+Object.test4extend);//在Object中出现了test4extend属性,注意此时Object是个Function document.write("<br>") var obj=new Object; document.write("Object instance:"+obj.test4extend);//在obj中没有扩展上test4extend,此时的obj是object document.write("<br>") function Foo() { } var foo = new Foo; document.write("foo object:"+foo.test4extend);//foo对象上没有扩展上test4extend document.write("<br>") document.write("Foo Function:"+Foo.test4extend);//Function扩展上了test4extend属性 document.write("<br>")
??
?这说明Function只管没有被实例化得,被实例化的,他是没有办法管的。与Object不一样,Object是不管是否实例化都管的。
接下来解释这个图:
先看最左侧的__proto__虚线,表示Foo.__proto__至关于Function.prototype,这里和Object状况差很少,只是属性一致而已,并非指真正的那个Function
中间的下部的__proto__虚线,表明Function.__proto__等于Function.prototype,这里但是真的就是,和前面的至关于不一样。
alert(Function.__proto__===Function.prototype);//true
?右侧左上的__proto__虚线,表明Object.__proto__等于Function.prototype,这里但是真的就是,和前面的至关于不一样。
alert(Object.__proto__===Function.prototype);//true
?
?右侧右上的__proto__虚线,表明Function.prototype.__proto__至关于Object.prototype,只是属性一致而已,并非真的。
先让咱们总结下__proto__和prototype的区别和关系。
区别:从实际效果上来讲,能够认为__proto__是用来扩展Function的,扩展出来的函数,能够直接调用,不须要new出对象才能用,同时对象是不会扩展经过__proto__扩展的方法或属性的
function Foo() { } Foo.__proto__.test = "__proto__ test property found";// 经过__proto__扩展 Foo.__proto__.addextend = function() { document.write("Foo add extend by __proto__"); document.write("<br>"); } Foo.addextend();// 能够执行 var foo = new Foo; document.write("Foo:" + Foo.test);// 能够访问 document.write("<br>"); document.write(foo.addextend);// 未定义 document.write("<br>"); document.write("Foo instance:" + foo.test);// 未定义 document.write("<br>");?
?
?对于prototype来讲,它是针对对象的,也就是Function是没法使用的,只有new出来的才能有效
?
function Foo() { } Foo.prototype.test="prototype test property found"; Foo.prototype.addextend=function(){ document.write("Foo add extend by prototype"); document.write("<br>");} document.write(Foo.addextend());//未定义 document.write("<br>") var foo=new Foo; document.write("Foo:"+Foo.test);//没法访问 document.write("<br>") foo.addextend();//能够执行 document.write("foo instance:"+foo.test);//找到了 document.write("<br>"?
?
Object.__proto__.test4extend="123";//扩展Object的原型 ? alert("Function:"+Function.test4extend);//在Function中出现了test4extend属性 ? alert("Object:"+Object.test4extend);//在Object中出现了test4extend属性,此时Object仍是个Function ? var obj=new Object; alert("Object instance:"+obj.test4extend);//未定义 ? function Foo() { ? } ? var foo = new Foo; alert("foo object:"+foo.test4extend);//未定义 ? alert("Function:"+Foo.test4extend);//函数上也扩展上了test4extend属性?
?【总结】
Function扩展自Object,可是Function对Object又有影响,这是经过Object.__proto__就是(===)Function.prototype创建的联系。记住这个联系后,咱们还要记住__proto__和prototype的区别,前者扩展的只能够被Function直接调用,后者扩展的只能够经过其实例调用。另外,还要注意__proto__和prototype的链的概念,这是由于,他们能够互相关联,访问到Function或Ojbect的内容。