js的原型&原型链&闭包,在不少人看来是区分JS程序员水平的关键知识点,固然对这句话我不是十分赞同。可是掌握这几个核心知识点老是没错滴!javascript
直接上代码:java
<script type="text/javascript"> //所有为函数对象类型(function) function f1(){} var f2 = function(){} var f3 = new Function() //所有都是普通对象类型(object) var o1 = {} var o2 = new Object() var o3 = new f1() console.info( typeof f1, typeof f2, typeof f3, typeof o1, typeof o2, typeof o3 ) //function function function object object object var obj = new f1(); f1.prototype.name = 'banyoukang'; console.info(obj.__proto__.name)//banyoukang console.info(f1.prototype)// f1 { name="banyoukang"} console.info(obj.__proto__)//f1 { name="banyoukang"} </script>
你能够本身试试这段代码,并想一下其输出结果,为何?下面让咱们掰扯掰扯这段代码:程序员
关于JavaScript对象
在JavaScript中,一切都是对象,可是和Java不一样的是:这些对象是分类型的。主要分为function(函数对象)和object(普通对象)。闭包
//所有为函数对象类型(function) function f1(){} var f2 = function(){} var f3 = new Function() //所有都是普通对象类型(object) var o1 = {} var o2 = new Object() var o3 = new f1()
<1>在这里,f1应该是咱们开发中最经常使用法,f2用的应该也挺多,只是多了一个引用罢了。可是,f3这种写法却是很少见的,其实f1,f2在建立的时候,JS会自动经过new Function()的方式来构建这些对象,因此都是f1,f2,f3本质上并无什么区别。注:(函数
var f3 = new Function('var temp = 100; this.temp = 200; return temp + this.temp;');this
alert(f3())spa
//弹出300,()将会执行引号中的内容,相似于eval函数)prototype
<2>关于o1和o2咱们均可以理解(对象字面量、使用new表达式来建立对象),可是o3虽然是f1函数new出来的,可是和f1缺不是一个类型的,看打印结果能够发现,一个是函数对象一个是普通对象。code
关于原型和原型链对象
在JavaScript中,每个对象都有一些属性,包括prototype和__proto__,其中prototype就是原型对象(prototype其实就是函数的一个属性),其做用就是保存对象的一些属性和方法(你能够经过f1.prototype.show = function(){} 给f1的prototype赋值一个方法),可是prototype对于对象自己是隐藏起来的,由于它是原型对象prototype的属性而不是对象自己的属性(你能够经过f1.prototype.show()来调用,可是不能经过f1.show()来调用)。关于__proto__,这才是原型链真正起做用的地方,它在普通对象和函数对象中都存在, 它的做用就是保存父类的prototype对象,JS在经过new 表达式建立一个对象的时候,一般会把父类的prototype赋值给新对象的__proto__属性,这样,就造成了一代代传承...
function f2(){} f2.prototype.name='banyoukang'; var test = new f2(); console.info(test.name)//banyoukang
注:能够经过test.__proto__来查看原型链
_proto_保存着父类的prototype的属性,当查找一个属性的时候,先看看本身有没有这个属性,若是没有就顺着原型链往上依次查找(注:不会查找自身的prototype属性)。
3.总结
<1>prototype就是对象的一个属性,这个属性也是一个对象(相似Java类中把其余类的对象定义成一个成员变量),专门用于储存准备传递到子类的方法和属性。
<2>__proto__就是prototype中属性和方法的实际传递者,当你new一个对象的时候,会把父类的prototype赋值给新对象的__proto__属性,这样你在子类的__proto__属性中就能够拿到父类传给你的属性和方法。
<3>不一样的对象的原型链是大相径庭的,好比父类和子类:
function f1(){}
var test = new f1()
f1的原型链:f1->Function.prototype->Object.prototype->null
test的原型链:test->f1.prototype->Object.prototype->null
从上面的实例咱们能够看到:对象的prototype属性是为子类服务的,是子类建立的核心,决定了子类的数据类型
这篇博文是本身试验加上阅读其余大神的博客总结出来的,若是您阅读的过程当中发现其中存在问题或者有指教的地方,欢迎拍砖,共同进步!