封装
本文是在读JavaScript设计模式之封装之后的感悟篇
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype = {
showName: function(){
console.log(this.name)
}
}
var p1 = new Person("ccc", 20);
p1.showName();
这里首先是创建了一个Person构造函数,然后通过对this对象添加属性或者方法来实现对类添加属性和方法,然后给Person构造函数的prototype原型对象赋值了一个对象,这里还可以有另一种写法
//切记这两种方式不要混用,因为会发生覆盖
Person.prototype.showName = function(){
console.log(this.name)
}
然后用new操作符基于Person构造函数创建了一个实例对象赋值给了p1,这里发生了:
- 创建一个空对象
- 对象继承了Person.prototype
- 然后这个对象带着参数执行了Person构造函数,此时this被指向了这个新对象
- 执行完了后新对象赋值给了p1
到此时,p1对象就有了构造函数里的属性和构造函数prototype原型对象上的showName方法
由于name和age是在构造函数里的属性,所以每次实例化新对象的时候,name和age都会再次创建,但是showName方法是在构造函数prototype对象上的方法,是不会重复赋值的,showName方法是通过原型链来调用的,p1的 proto 和Person.prototype指向同一个引用地址
var CreateFunc = (function(){
//静态私有变量
var sum = 0;
//静态私有方法
function addPerson(){ ++sum;console.log(sum); }
//静态私有构造函数
function CreatePerson(name, age){
//创建对象的安全模式
//这里还有个问题:为什么this是CreatePerson的实例的时候不用return
if(this instanceof CreatePerson){
//私有变量
var color = "yellow";
//公共属性
this.name = "ccc";
this.age = 20;
//特权方法
this.setName = function(name){ this.name = name || this.name };
this.setAge = function(age){ this.age= age || this.age};
this.showName = function(){ console.log(this.name) };
this.setName(name);
this.setAge(age);
addPerson();
}else{
return new CreatePerson(name, age);
}
}
CreatePerson.prototype = {
//静态公共属性
isMan: false,
//静态公共方法
sayHi: function(){ console.log("hi") }
};
return CreatePerson;
})();
var you = new CreateFunc("you", 18);
var me = new CreateFunc();
//这两个对象可以访问特权方法、公共属性、静态公共属性、静态公共方法
关于上面构造函数返回值的发问,引用一下别人的回答请看这里
看完了后,自己总结一下: 构造函数里如果有return且返回值是个对象,就直接返回return后面写的对象,如果有return且返回值不是对象,就返回构造出来的这个对象。那上面的例子else里为何要return new….呢,如果不加return就相当是执行了一遍new CreatePerson()并返回了构造的对象,但是并没有从函数里返回出去,执行完了就销毁了,所以要主动的返回