面向对象是JS的重点与难点,但也是走向“控制JS”的必经之路,有很多的文章或书本中都对其举行了细致的形貌,本没有必要再写这些,然则关于进修来讲,讲给他人听对本身来讲是一种更好的受益体式格局。我想经由历程简约的言语来形貌建立对象的要领以及这类要领的优瑕玷。
本系列内容:
基本建立情势
对象字面量建立对象
工场情势
组织函数情势
更新时刻
2015年12月6日:建立
2017年7月8日:精简内容,修改毛病
一、建立对象
建立对象的要领有很多,各有利弊。知其然,做到会用;知其所以然,做到为何用这类要领。才是真正的控制。
1.1 基本建立情势
var person = new Object();
person.name = "张三";
person.job = "门生";
person.viewName = function(){
console.log(this.name);
}
这是一种最基本的建立对象的要领,运用新建Object
的要领建立对象,并且为其增加属性和要领。
但这类体式格局有个不好的处所是重复运用了多个person
变量,而且没有任何的封装性可言,因而就涌现了更受开发人员喜欢的对象字面量情势。
1.2 对象字面量建立对象
var person = {
name: "张三",
job: "门生",
viewName: function(){
console.log(this.name);
}
}
这类体式格局的优点不言而喻,就是处理了之前的瑕玷。
但在现实需求中,须要建立一批相似的对象就有些力不从心了。比方一个小组有六个成员,我要基于每一个组员举行对象实例化,那末我要写6遍以上的代码,并且为其命名为person1~person6。假如能够像流水线平常建立对象就好了:给其供应质料(名字和职务),让其自动建立出组员,运用函数正好能做到。
1.3 工场情势
var person = function(name, job){
var o = new Object();
o.name = name;
o.job = job;
o.viewName = function(){
console.log(this.name);
}
return o;
};
var person1 = person("张三","门生");
var person2 = person("李四","门生");
工场情势应用”建立对象函数”构成流水线的情势,使其流程化,将建立的历程都封装到函数中,对外只暴露每一个对象的特征(经由历程参数的情势传入)。
详细的完成流程是:在函数内建立了一个对象,将传入的参数作为对象的属性,在末了将其返回。挪用函数,函数就会返回具有特定属性的对象。
工场情势流程化了建立对象的要领,使其建立对象变得异常轻便,但个中出了一个题目,既然person1和person2都运用person函数建立,那末,有什么要领能够证实person1和person2″师出同门”呢?或许用JS的话说是如何处理对象辨认题目,答案是工场情势不能证实。因而又涌现了组织函数情势,用此情势能够肯定person1和person2的关联。
1.4 组织函数情势
var Person = function(name, job){
this.name = name;
this.job = job;
this.viewName = function(){
console.log(this.name);
}
}
var person1 = new Person("张三","门生");
var person2 = new Person("李四","门生");
与之前工场情势的要领对照:
Person变量名首字母大写了
在函数内没有显式的建立及返回对象而运用了this
建立时运用了
new
关键字。
Person变量首字母大写是为了辨别一般函数,除此之外,别无它用。既然Person的首字母大写只是为了让本身一眼辨别出他是组织函数,在功能上是雷同的。那末写成person固然能够,只是如许不引荐(没法辨别一般函数与组织函数)。
运用new操作符必需阅历四个步骤
建立一个新的对象
将组织函数的作用域赋值给新对象
实行组织函数的代码:为其增加属性和要领
返回新的对象
运用new操作符建立的对象都有一个constructor
属性,该属性指向组织函数。
person1.constructor == Person; // true
person1.constructor === person2.constructor;// true
console.log(person1.constructor);// 返回组织函数
//function (name, job){
// this.name = name;
// this.job = job;
// this.viewName = function(){
// console.log(this.name);
// }
//}
在测试的时刻发明一个题目:不运用new关键字建立Object对象为何constructor有值?
同享要领
再回到本来的需求,小组有两个人,我要建立两个对象,对象的名字和职位能够不一样,然则打印每一个人的名字这个要领是一样的。
关于以上几种情势建立的对象。
person1.viewName === person2.viewName;// false
我每次建立一个对象,都建立一次viewName,然则每次都不相称(person1.viewName == person2.viewName返回false)。且假如有一天我们想把viewName要领改成return返回name值,我要每一个对象都改吗?我们只要把这个要领做成对象公用的就好了,我们能够如许:
var Person = function(name, job){
this.name = name;
this.job = job;
this.viewName = viewName;
}
function viewName(){
console.log(this.name);
}
var person1 = new Person("张三","门生");
var person2 = new Person("李四","门生");
然则这又涌现了一个题目,没有封装性可言啊,viewName明显是Person的私有要领,然则放在表面,变成了谁都能够挪用,原型函数情势处理了这个题目。