解读:1.这里有一个Star的构造函数,ldh是Star这个类实例化的对象,它们的交互是通过原型进行沟通的。
2.如果ldh这个对象像Star寻求解决方法,如果Star的原型对象(prototype)解决不了,那么会向更高级的全局原型对象寻求帮忙,如果Object的原型对象(prototype)无法
提供解决方法,则返回null。
一。背景
es6之前的对象不是基于类创建的,而是一种称为构建函数的特殊函数来定义对象和特征的
构建对象通过以下三种方式
1 //1.对象字面量 2 var obj2 ={}; 3 //2.new Object() 4 var obj1 = new Object(); 5 //3.自定义构造函数 6 function Star(uname,age){ 7 this.uname = uanme ; 8 this.age = age ; 9 this.sing = function(){ 10 console.log('i love sing!') 11 } 12 }
这里主要讲述自定义构造函数,自定义构造函数中的new的作用:
//new会做以下四件事 //1.在内存中创建一个新的空对象 //2.让this指向这对象 //3.执行构造函数里面的代码,给这个新对象添加属性和方法 //自动返回这个新对象(所要构造函数里面不需要return)
(1)构造函数中的属性和方法我们称为成员,成员可以添加
成员添加的方式有两种:实例化成员添加和静态成员添加
1 function Star(name,age){ 2 this.name = name ; 3 this.age = age ; 4 this.sing = function(){ 5 console.log('i can speak english!') 6 } 7 } 8 var ldh = new Star('小明',18); 9 //1.实例成员 10 //实例成员就是构造函数内部通过this添加的成员,如上面的name ,age就是实例成员 11 //实例成员只能通过实例化的对象访问,如ldh.name 12 //2.静态成员,在构造函数本身直接添加的成员 13 Star.sex = 'man'; 14 console.log(ldh)
(2)原型对象为何会出现?
由于采用构造函数new出来的对象,如果不同成员调用构造函数里的函数所要表达的东西一样,那么未免会
造成内存浪费,所以如何减少内存浪费,实现函数共享,代码复用呢?
原型对象prototype实现函数共享(注意:每个构造函数都有原型对象)
Star.prototype由此出现
1 function Star(name,age){ 2 this.name = name; 3 this.age = age; 4 // this.sing = function(){ 5 // console.log('sing!'); 6 // }这样写会浪费内存,不能共享函数,因为每一次实例化对象都会为这个函数重新开辟内存,用来保存这个函数,但是这个函数在不同对象下所要表达的意义是一样的 7 } 8 Star.prototype.sing=function(){ 9 console.log('sing!') 10 } 11 var ldh = new Star('刘德华',18); 12 var zxy =new Star('张学友',19) 13 ldh.sing(); 14 console.log('所以原型的意义是来共享方法!')
(3)每个对象都有_proto_这个属性(_proto_称为对象原型,它指向prototype(原型对象))
//对象上都有对象原型:_proto_ //每一个对象都有一个属性_proto_ function Star(name,age){ this.name = name; this.age = age; } Star.prototype.sing=function(){ console.log('sing!') } var ldh = new Star('刘德华',18); ldh.sing();
ldh.sing()函数底层实现步骤:首先查找ldh这个对象的属性有没有sing这方法,如果没有,ldh的_proto_会去构造函数的prototype(原型对象)上面查找这个sing函数
(4)constructor用来让原型对象重新指向原来的构造函数
1 // constructor用来记录对象引用哪个构造函数 2 //他可以让原型对象重新指向原来的构造函数 3 function Star(name,age){ 4 this.name = name; 5 this.age = age; 6 } 7 //1.添加单个共享方法可以这样 8 // Star.prototype.sing=function(){ 9 // console.log('sing!') 10 // } 11 //2.添加多个共享方法 12 Star.prototype={ 13 //由于这里是采用对象覆盖的方式,需要添加constructor指向原来的Star,否则覆盖后没有构造函数这属性 14 constructor:Star, 15 sing:function(){ 16 console.log('sing!'); 17 }, 18 movie:function(){ 19 console.log('movie!'); 20 } 21 } 22 var ldh = new Star('刘德华',18); 23 var zxy =new Star('张学友',20);
总结:如果我们修改了原来的原型对象,并且给原型对象赋值的是一个对象,则必须手动利用construor指回原来的构造函数
总结:说白了构造函数与其构造函数实例化的对象是通过原型来进行交流的。