Bootstrap

ECMAScript-10 【原型-原型链-闭包立即执行函数-插件开发】

一.原型

(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

自己有的就不去访问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';
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();

同时实例出来的对象是无法CDUprototype的

(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()上面的

_proto_就是装原型的容器而已

_proto_是可以更改的:

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(){})()

这样写的目的就是为了不要忘记写分号,导致出错

;