欢迎!从2017年开始,将慢慢的不在xmind上写总结了,全部转到博客中!这里将不再随便写写,将继承在xmind的精神,继续前行!!!

JS prototype与__proto__的联系与区别

关于这俩货,看了网上不少资料,概念好绕!!

https://blog.csdn.net/fivedoumi/article/details/51282593 读了这篇文章,感觉有点清晰,划个重点:

1、JavaScript里没有类的概念,一些需求也催生了JavaScript想模仿类这个概念,必然会涉及到一些继承问题,prototype与__proto__就催生了。

2、JavaScript没有类的概念,它里面的所有东西都是对象,但他的对象是有类型的

    基本上每本教科书上都会列举的很清楚,分两种,原始类型(Primitive Types)与引用类型(Reference Types)

    原始类型(5种):Boolean、Number、String、Null、Underfined

    引用类型(6种):Array、Date、Error、Function、Object、RegExp (其实也不止这些)

3、用typeof操作符判断一个变量的类型,

   5种原始类型都可以用它判断出来(除了Null,Null类型返回object),但对于引用类型,只有两种返回值:function和object,本质上说明引用类型根本上只有两种,那就是Function和Object

4、Function能做但Object做不了的事情

  4.1Fuction可以被执行。这是函数最基本的特征

  4.2Fuction可以被当做Object的构造函数。当我们使用new操作符后面跟着一个Function类型的变量时,这个Function变量会被当成构造函数返回一个Object对象

function Foo () {    console.log("我是个Function");}  
foo = new Foo();
console.log(typeof Foo); //function console.log(typeof foo); //object

  4.3Function有内置的prototype属性,而Object没有(prototype只有Function才有)

        var a = {}
        var b = function() {}
        console.log(a.prototype) // undefined  
        console.log(b.prototype) // {}

5、在考虑javascript的继承的时候,不应该去分别Function和Object,我们只需要统一把它们都看做对象即可

6、javascript是通过__proto__来明确继承关系的。__proto__不同于prototype,prototype只有在Function中有,而__proto__在Function和Object中都有

7、最简单的话来描述javascript中继承的本质:一个对象A的__proto__属性  所指向的  那个对象B  就是  它的原型对象(或者叫上级对象、父对象),对象A可以使用对象B中定义的属性和方法,同时也可以使用对象B的原型对象C的属性与方法,以此递归,这也就是所谓的原型链。

__proto__,可称为隐式原型,一个对象的隐式原型 指向 构造该对象的   构造函数  的  原型(这话有点绕)

var A = {name:"wangyunok"};  
var B = {weibo:"http://weibo.com/wangyunok"};  
var C = {github:"https://github.com/wangyunok"}  
  
B.__proto__ = C;  
A.__proto__ = B;  
  
console.log(A.name);    //wangyunok  
console.log(A.weibo);   //http://weibo.com/wangyunok  
console.log(A.github);  //https://github.com/wangyunok  

//这就实现了最简单的继承。

8、问:通过7中的例子 可以看出,__proto__一个东西把继承问题就都解决了么,那要prototype做甚?

     答:prototype这个东西真正发挥作用的时候,是你把一个Function当做构造函数使用时,而所谓的与继承有关系,不过是因为__proto__并非官方标准中定义的属性,所以他们借助prototype这个属性模仿Java中类与类之间继承的模式

9:最精简的总结

     __proto__是真正用来查找原型链去获取方法的对象。

    prototype是在用new创建对象时用来构建__proto__的对象。

 

在最后,再来提一遍 new过程的实质(上篇文章有过):

//模仿类  
function Foo(name,weibo,github)  
    {      
        this.name = name;      
        this.weibo = weibo;      
        this.github = github;  
    }  
      
Foo.prototype.whoami = function(){ console.log("I'm wangyunok, a coder of javascript!") }  
  
//创建对象  
var foo = new Foo('wangyunok','http://weibo.com/wangyunok','https://github.com/wangyunok');  
  
console.log(foo.name);      //wangyunok  
console.log(foo.weibo);     //http://weibo.com/wangyunok  
console.log(foo.github);    //https://github.com/wangyunok  
  
foo.whoami();               //I'm wangyunok, a coder of javascript!  

第一步,Foo函数被执行。Foo函数在foo的作用域下被执行,所以这里this指代的就是foo,这样name、weibo、github三个属性才会被当做foo的属性被创建,如果你在函数Foo中写一个console.log()语句,它也会在结果中打印出来,见上面代码2。

第二步,将foo.__proto__指向Foo.prototype。这才是javascript构造函数的精髓所在,foo就继承了Foo.prototype中(以及其原型链上)的属性与方法。下面代码可以佐证:

console.log(foo.__proto__ === Foo.prototype)//true
(通过这个理解 7中  构造该对象的构造函数的原型,即 Foo 构造了 foo对象,此时foo的 __proto__ 就指向Foo的 原型

这样一个鲜活的foo就被创建出来了。

 

 

 

 

666

posted @ 2018-06-27 16:12  拐进web的奋斗者  阅读(261)  评论(0编辑  收藏  举报