prototype 和 __proto__ 和 constructor的联系

关系和联系
  • 每一个方法都有prototype属性,
  • 每一个prototype都有constructor属性,
  • 每一个实例都有___proto____属性

一个实例的___proto____指向他的构造函数的prototype

一个构造方法的prototype下的constructor指向构造方法本身

示例
var Obj = function(){   
}
var obj = new Obj();

obj.__proto__ === Obj.prototype;  //true
Obj.prototype.constructor === Obj; //true;
obj.__proto__.constructor === Obj //true
  • prototype的存在是为了方法的实例有一些公用的变量和方法
var Obj = function(){
   this.name = "bitch"
}

Obj.prototype.say = function(){
    console.log("sun of beach")
}
var obj1 = new Obj();
var obj2 = new Obj();
obj1.say() // bitch
obj2.say() // bitch
  • 疑问:为什么不直接在声明类的时候用的时候创建共有的变量和方法呢?

下面来看这组代码

function Obj(){
       this.a=[]; //实例变量
       this.fn=function(){ //实例方法

       }
  }
  var o1=new Obj();
   o1.a.push(1);
   o1.fn={};
   console.log(o1.a); //[1]
   console.log(typeof o1.fn); //object

   var o2=new Obj();
   console.log(o2.a); //[]
   console.log(typeof o2.fn); //function

大家会发现虽然两个实例都是同一个类实例化的。但是实际上他们各自都只是复制了一次类的方法和变量,并不是真正的指向这些方法和变量。这时候我们就需要用prototype来实现真正的共有化了。

  • 补充
    实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回,如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。

你可能感兴趣的:(prototype 和 __proto__ 和 constructor的联系)