接触JavaScript一段时间以后,想写一写比较好的代码封装,有利于之后的扩展,因此就有了本篇的文章。
内容学习源自 阮一峰老师的博客
,自己又梳理了一遍,在此特别感谢阮一峰老师的博客文章,写的非常棒,值得大家学习。
js里声明对象一个简单的方式是:
var person = {};
person.name = ‘xxx';
person.gender = ‘male';
这种字面量方式让我们可以轻松的创建对象,但是对于不同的person来说,显然有不同的name和gender,此时我们就会像如下这样创建不同的人:
var person1 = {};
person1.name = ‘Jack’;
person1.gender = ‘male’;
var person2 = {};
person2.name = ‘Losy';
person2.gender = ‘female’;
这样写有很多重复的地方,因此我们想到了用函数方式去做。
function Person(name, gender) {
return {
name: name,
gender: gender
};
}
var person1 = Person(‘Jack’, ‘male’);
var person2 = Person(‘Losy’, ‘female');
函数方式让我们更快的创建对象,
这种方式不能反映出对象之间的源自同一个原型对象的实例。
解决不同对象源自同一个原型对象的实例,js提供了一种构造函数模式(Constructor)。
function Person(name, gender) {
this.name = name;
this.gender = gender;
}
var person1 = new Person(‘Jack’, ‘male’);
var person2 = new Person(‘Losy’, ‘female');
构造函数模式和函数方式从形式上的区别仅仅是定义的时候用了this,实例化对象的时候用了new,但是从本质上还是有区别的:
console.log(person1 instanceof Person);// true
console.log(person2 instanceof Person);// true
console.log(person1.constructor == person2.constructor);// true
构造函数模式解决了实例化对象后能够充分的体现原型对象,并且能够避免重复的定义。但是这种方式带来了问题是:
function Person(name, gender) {
this.name = name;
this.gender = gender;
this.type = '哺乳动物';
this.eat = function() {
return ‘粮食';
};
}
var person1 = new Person(‘Jack’, ‘male’);
var person2 = new Person(‘Losy’, ‘female');
person1.type == person2.type;// true
person1.eat() == person2.eat();// true
person1.eat == person2.eat;// false
若为这个原型对象(类)添加一个方法时,势必会在每个实例化对象中都生成,这就会占用多余的内存。
有没有让实例化的对象共有一些方法,避免每次实例化对象时也实例化了具体的方法,答案是:原型模式(Prototype)。
function Person(name, gender) {
this.name = name;
this.gender = gender;
}
Person.prototype.type = '哺乳动物’;
Person.prototype.eat = function() {
return ‘粮食';
};
var person1 = new Person(‘Jack’, ‘male’);
var person2 = new Person(‘Losy’, ‘female');
person1.type == person2.type;// true;
person1.eat() == person2.eat();// true;
person1.eat == person2.eat;// true;
验证实例对象与某个Prototype对象之间的关系:
Person.prototype.isPrototypeOf(person1);// true
判断某个属性是本地实例化属性还是继承自prototype对象的属性:
person1.hasOwnProperty(name);// true
person1.hasOwnProperty(type);// false