JS难点剖析-原型&原型链

 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>

你能够本身试试这段代码,并想一下其输出结果,为何?下面让咱们掰扯掰扯这段代码:程序员

  1. 关于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

  2. 关于原型和原型链对象

          在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属性是为子类服务的,是子类建立的核心,决定了子类的数据类型

 

        这篇博文是本身试验加上阅读其余大神的博客总结出来的,若是您阅读的过程当中发现其中存在问题或者有指教的地方,欢迎拍砖,共同进步!

相关文章
相关标签/搜索