在这篇博客中,作者说以下函数是一个构造函数:
function Cat(name, color) {
this.name = name;
this.color = color;
}
Cat.prototype.age = 0;
var catC = new Cat("Fluffy", "White");
Cat
函数的实例具有名称和颜色属性。这是普通函数和 构造函数 之间唯一的区别吗?
在这篇博客中,作者说以下函数是一个构造函数:
function Cat(name, color) {
this.name = name;
this.color = color;
}
Cat.prototype.age = 0;
var catC = new Cat("Fluffy", "White");
Cat
函数的实例具有名称和颜色属性。这是普通函数和 构造函数 之间唯一的区别吗?
new
操作符会将函数中的上下文(this
)设为新的实例,从而使其具有两个属性并返回该新实例。如果没有new
操作符,上下文将是外部上下文(在松散模式下的全局作用域中为window
,在严格模式下为undefined
)。也就是说,如果省略了new
。var catC = Cat("Fluffy", "White");
如果您未启用严格模式,则该函数“运行”,但会产生两个不同的结果:
catC
未定义,因为您的函数没有返回任何内容name
和 color
现在是外部作用域的属性整个魔法都在new 运算符中:
执行代码 new foo(...) 时,会发生以下事情:
新对象将被创建,并从 foo.prototype 继承。
构造函数 foo 将使用指定的参数并将 this 绑定到新创建的对象来调用。new foo 等效于 new foo(),即如果未指定参数列表,则不带参数地调用 foo。
由构造函数返回的对象成为整个 new 表达式的结果。如果构造函数未显式返回对象,则使用在步骤 1 中创建的对象。(通常构造函数不返回值,但如果它们想要覆盖正常的对象创建过程,则可以选择这样做。)
当我说它是一个普通函数时,我忽略了一件事:开发人员的意图。通常情况下,您定义函数要么被称为构造函数(即使用 new
),要么不是。在第一种情况下,您通常使用参数来初始化实例的字段(使用 this.name = ...
),然后您经常跟随通过添加函数到原型(就像您所做的那样),以使它们对于所有实例都可用。为了明确您的意图,惯常做法是将构造函数命名以大写字母开头。
让我们举一个例子来理解Javascript中构造函数的产生。假设您被要求创建一个员工对象,它应该有4个属性:firstName,lastName,gender和designation。好吧!你说没问题。
var employee1={};
employee1.firstName="Anoop";
employee1.lastName="Rai";
employee1.gender="M";
employee1.designation="Software Engineer";
上面是最简单的方式,首先创建一个空对象,然后将所有4个属性关联到该对象(当然,您也可以通过内联方式创建相同的内容)。如果再次要求创建具有相同属性的另一个员工对象,该怎么办。var employee2={};
employee1.firstName="Ram";
employee1.lastName="Kumar";
employee1.gender="M";
employee1.designation="Associate Software Engineer";
看起来一切都没问题。如果现在有人问你,总共有100名员工,而你只创建了其中2个,那么你需要再创建另外98个员工对象。现在你不会像上面那样繁琐地手动创建对象了。注意了!我们可以创建一个工厂方法,它将被调用任意次数,并创建对象,然后返回给我们。是的!只需编写一次,即可多次使用。
function createEmployeeObject(firstName, lastName, gender, designation){
var employee={};
employee.firstName=firstName;
employee.lastName=lastName;
employee.gender=gender;
employee.designation=designation;
return employee;
}
var employee3=createEmployeeObject("Harry", "Dsouza", "M", "Project Manager");
非常便捷的方式,没有重复的代码。只需使用您的参数调用createEmployeeObject函数,然后您就可以得到您的对象。如果我们有若干种类型的对象,比如部门,那么我们也会有一个函数来创建一个部门对象并返回它。
那么,在这些函数中有什么共同点呢?它们是:
var myObj = {};
return myObj;
创建空对象并返回对象是创建对象的所有函数中都具有的共同点。Javascript已经创建了一种快捷方式,让您在使用创建对象函数时不必编写这些行。做到这一点的方法是使用构造函数。
在Javascript中,使用函数创建对象是相当普遍的,因此Javascript提供了一种快捷方式,让您编写创建对象的函数。这些特殊的函数称为构造函数。构造函数是一种让您填充需要创建的对象的函数。
function createEmployeeObject(firstName, lastName, gender, designation){
this.firstName=firstName;
this.lastName=lastName;
this.gender=gender;
this.designation=designation;
}
var employee4=new createEmployeeObject("Alan", "Marks", "F", "Business Analyst");
您必须了解这个关键字,它指向当前对象。请记住,在构造函数中,Javascript会为我们创建一个空对象,所以这实际上只指向那个对象。Javascript构造函数在填充完对象后会自动返回该对象。现在如何告诉Javascript一个函数是以构造函数模式调用的呢?就是使用new关键字,它告诉Javascript将一个函数视为构造函数。每次需要对象时,请使用new关键字调用函数,然后该函数会为我们准备一个对象并返回它。
即使Javascript不是基于类的,您也必须注意构造函数名称。不要使用驼峰命名法,使用常规命名法更好。
function Employee(firstName, lastName, gender, designation){
this.firstName=firstName;
this.lastName=lastName;
this.gender=gender;
this.designation=designation;
}
var employee5=new Employee("Mark", "Watson", "M", "DBA");
Dystroy已经掌握了它。
换句话说,当使用new
运算符调用函数时,该函数就会成为一个“构造函数”,并且会创建一个新的类实例。
这也是提到函数名称中大写字母的约定原因,以便其他开发人员可以看出它是一个构造函数,并且符合当前命名类
的惯例。
var catC = new Cat("Fluffy", "White");
创建了构造函数类 Cat
的一个新实例。