一.原型
(1).prototype定义
console.log(Handphone.prototype);
原型prototype是函数中的一个属性,打印出来其实也是对象
这个prototype是定义构造函数构造出的每个对象的公共祖先
function Handphone(color,brand){
this.color=color;
this.brand=brand;
this.screen='18:9';
this.system='Android';
}
Handphone.prototype.rom="64G";
Handphone.prototype.ram='6G';
var hp1=new Handphone('red','小米');
var hp2=new Handphone('black','华为');
console.log(hp1.rom);//64g
console.log(hp2.ram);//6g
function Handphone(color,brand){
this.color=color;
this.brand=brand;
this.screen='18:9';
this.system='Android';
}
Handphone.prototype.rom="64G";
Handphone.prototype.ram='6G';
Handphone.prototype.screen='16:1';
var hp1=new Handphone('red','小米');
var hp2=new Handphone('black','华为');
console.log(hp1.screen);//18:9
console.log(hp2.screen);//18:9
(2).解除冗余
用参数改变的写在属性中,固定的就写在原型上,属性是写在属性中,方法中挂在原型上,解决冗余
function Handphone(color,brand){
this.color=color;
this.brand=brand;
}
Handphone.prototype.rom="64G";
Handphone.prototype.ram='6G';
Handphone.prototype.screen='16:1';
Handphone.prototype.call=function(){
console.log('I am calling somebody')
};
var hp1=new Handphone('red','小米');
var hp2=new Handphone('black','华为');
console.log(hp1.screen);//18:9
console.log(hp2.screen);//18:9
hp2.call();
(3).对象的书写方式
Handphone.prototype={
rom:'64',
call:function(){
console.log('I am calling somebody')
}
}
二.原型链
(1).constructor
可以通过constructor强行更改HandPhone的指向
function Telephone(){}
function Handphone(color,brand){
this.color=color;
this.brand=brand;
}
Handphone.prototype={
constructor:Telephone
}
(2)._proto_
function Car(){
var this={
//_proto_:Car.prototype
}
}
Car.prototype.name="Benz"
var car =new Car();
console.log(car);
当this下面有name属性时就取用,但是没有的话就会在本身的this当中的_proto_属性中调用。也就是说是在实例化对象上面的,并不是在Car()上面的
function Person(){}
Person.prototype.name='张三';
var p1={
name:'李四'
}
var person=new Person();
console.log(person.name);//张三
person._proto_=p1;
console.log(person.name);//李四
(3).经典示例:
Car.prototype.name='Benz';
function Car(){}
var car=new Car();
Car.prototype={
name:'Mazda'
}
console.log(car.name);
//function Car(){
// var this={
// _proto_:Car.prototype={
// name:'Benz'
// }
// }
//}
//输出的是Benz,因为实例化完了已经没有用了
Car.prototype.name='Benz';
function Car(){}
Car.prototype={
name:'Mazda'
}
var car=new Car();
console.log(car.name);
//这时候理所应当是Mazda
在实例化之前Car()中就已经有一个constructor了,指向的是构造器本身,然后里面有prototype属性,你给他赋值了,接下来如图一实例化对象了,这个对象中的this直接把constructor的prototype赋值给自己了,这时输出的肯定是之前的值,可是后面又执行更改prototype属性了,但是没有实例化所以不输出,而图二恰巧就是经过了两次的constructor的prototype属性后才实例化对象输出的,所以肯定是最后一个值。这里的prototype是属于实例化对象的可以理解为从constructor中取出来赋值给自己
但是如果为下面这种方式就不同了,只是更改了属性相当于修改覆盖,并没有将constructor重写所以输出的就是Mazda了
Car.prototype.name='Benz';
function Car(){}
var car=new Car();
Car.prototype.name='Mazda'
console.log(car.name);
三.闭包立即执行函数
(1).window写闭包
function test(){
var a=1;
function add(){
a++;
console.log(a);
}
window.add=add;
}
test();
add();
add();//输出2 3
(2).立即执行函数闭包
var add=(function(){
var a=1;
function add(){
a++;
console.log(a);
}
return add;
})();
add();
add();//2 3
(3).构造函数闭包
四.插件开发
(1).插件书写格式
(function(){
function Test(){}
window.Test=Test;
})();
var test =new Test();)
(2).其他书写格式
;(function(){})()
;(function(){})()