(一)、原型
原型prototype其实就是function对象的一个属性,它也是对象
function Handphone(){
}
console.log(Handphone.prototype); //{constructor:f}
//原型prototype其实就是function对象的一个属性
//打印出来看了一下,结果它也是对象
这个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.protitype.screen = '16:9';
var hp1 = new Handphone('red','小米');
var hp2 = new Handphone('black','华为');
console.log(hp1.rom); //64G
console.log(hp2.ram); //6G
console.log(hp1.screen); //18:9
consolr.log(hp2.screen); //18:9
在实例化对象的时候总有一些写死的值,这些写死的值,每次new的时候都要走一边流程
当我们需要用参数去传值的时候就写到this里面去,当需要写死值的时候就写到原型上去
每当看到别人写插件的时候 , 有一些写到原型链上,有一些写到构造函数中
往往所有的方法会写到原型中,只有部分属性会写到构造函数中,因为往往属性都是配置项都要传参数去配置
function Handphone(color,brand){
this.color = color;
this.brand = brand;
}
Handphone.prototype.rom = '64G';
Handphone.prototype.ram = '6G';
Handphone.prototype.screen = '16:9';
Handphone.prototype.system = 'Android';
Handphone.prototype.call = function(){
console.log('I am calling somebody');
}
var hp1 = new Handphone('red','小米');
var hp2 = new Handphone('black','华为');
hp2.call();
prototype是一个对象
function Handphone(color,brand,system){
this.color = color;
this.brand = brand;
this.system = system;
}
Handphone.prototype = {
rom: '64G',
ram: '6G',
screen: '18:9',
call: function(){
console.log('I am calling somebody');
}
}
var hp1 = new Handphone('black','iphone','IOS');
console.log(hp1);
constructor构造器对应的是构造函数, 默认指向构造函数本身
function Handphone(color,brand,system){
this.color = color;
this.brand = brand;
this.system = system;
}
console.log(Handphone.prototype);
function Telephone(){}
function Handphone(color,brand,system){
this.color = color;
this.brand = brand;
this.system = system;
}
Handphone.prototype = {
constructor: Telephone
}
console.log(Handphone.prototype);
__proto__是实例化以后的结果,_proto_属于的是对象实例
prototype原型是属于实例化对象的而不是构造函数
__proto__就是一个容器,就是通过这个键名去访 问prototype
function Car(){
}
Car.ptototype.name = 'Benz';
var car = new Car();
console.log(car);
__proto__ 是可以更改的
function Person(){}
Person.prototype.name = '张三';
var p1 = {
name: '李四'
}
var person = new Person();
console.log(person.__proto__);
console.log(person.name); //张三
person.__proto__ = p1;
console.log(person.__proto__);
console.log(person.name); //李四
Car.prototype.name = 'Mazda';
function Car(){}
var car = new Car();
Car.prototype.name = 'Benz'; // 这是给prototype的name属性赋值,不属于重写
console.log(car.name); // Benz
Car.prototype.name = 'Benz';
function Car(){}
var car = new Car();
Car.prototype = {
name: 'Mazda'
}
console.log(car.name); //Benz
console.log(car);
-----------------------------
重新写的这个prototype是在实例化对象之后写的,
跟现在实例化的prototype没有关系。
function Car(){
var this = {
__proto__: Car.prototype = {
name: 'Benz'
}
}
}
Car.prototype.name = 'Benz';
function Car(){}
Car.prototype = {
name: 'Mazda'
}
var car = new Car();
console.log(car.name); //Mazda
(二)、闭包和立即执行函数
(1)、闭包
function test(){
var a = 1;
function plus1(){
a++;
console.log(a)
}
return plus1;
}
var plus = test();
plus() //2
plus() //3
plus() //4
(2)、window
function test(){
var a = 1;
function add(){
a++;
console.log(a);
}
window.add = add;
}
test();
add(); // 2
add(); // 3
add(); // 4
(3)、立即执行函数
var add = (function(){
var a = 1;
function add(){
a++;
console.log(a);
}
return add;
})();
add(); //2
add(); //3
add(); //4
(4)、立即执行函数+window
(function(){
var a = 1;
function add(){
a++;
console.log(a);
}
window.add = add;
})();
add(); //2
add(); //3
add(); //4
(三)、插件开发
js插件的写法 立即执行函数可以有效的隔离全局的作用域,es5没有块级作用域,只能用立即执行函数这种形式去隔离。
(function(){
function Test(){}
Test.prototype = {}
window.Test = Test;
})();
var test = new Test();
立即执行函数后面要加分号 不加分号会报错,有时候会忘记在后面加分号,所以可以把分号加在前面
前面写+也可以,但是一般都加;这是一种习惯。
;(function(){})()
;(function(){})()