{…}语法允许创建一个对象,但如果需要创建多个类似的对象,则我们需要使用构造函数和“new”操作符。
构造函数技术上就是正常的函数,但一般有两个约定:
1、他们的名称第一个字母大写。
2、他们应该仅仅使用new操作符执行。
示例:
function User(name) { this.name = name; this.isAdmin = false; } let user = new User("Jack"); alert(user.name); // Jack alert(user.isAdmin); // false
我们来看执行new User()
时背后到底做了什么?
1、首先创建一个空对象,然后赋值给this。
2、执行函数,通常修改this对象,增加一些新的属性。
3、this被返回。
换句话说,new User()
内容如下代码所示:
function User(name) { // this = {}; (implicitly) // we add properties to this this.name = name; this.isAdmin = false; // return this; (implicitly) }
所以 new User("Jack")
的结果和下面代码一致:
let user = { name: "Jack", isAdmin: false };
现在我们想创建其他对象,我们可以使用new User("Ann")
,new User("Alice")
等。比每次使用文字描述对象方式更简短,且易读。
这时构造函数的主要目的——————实现创建对象的代码重用。
让我们再次注意:
技术上,任何函数都可以用作构造器,即任何函数都可以使用new调用,并且也执行上面描述的算法。
首字母大写只是一个常规约定,使其更清晰说明其为构造韩式,应该使用new调用。
new function(){…}
如果我们有多行代码,用于创建一个复杂对象,我们可以包装他们使用构造函数,代码如下:
let user = new function() { this.name = “John”; this.isAdmin = false; // ...other code for user creation // maybe complex logic and statements // local variables etc };
该构造器不能被再次调用,因为没有被保存,仅仅被调用创建对象。这个技巧的母的只是为了封装单个复杂对象代码。
函数内部,我们可以检查其调用方式是否使用new方式。使用一个特殊的属性new.target
可以。
普通调用其值为空,通过new调用其值为该函数。
function User() { alert(new.target); } User(); // undefined new User(); // function User { ... }
下面代码可以实现使用常规方式和new操作方式效果一致。
function User(name) { if (!new.target) { // if you run me without new return new User(name); // ...I will add new for you } this.name = name; } let john = User("John"); // redirects call to new User alert(john.name); // John
这个方法在一些库中使用,为了使代码更加灵活。但到处使用并非好事,对熟悉User对象内部情况不够明显。
通常构造器无需返回值语句。它的任务是往this对象中写一些必要内容,然后自动返回之。
但如果有return语句,那么规则很简单:
- 如果return返回一个对象,那么则代替this被返回。
- 如果return返回原始类型,则被忽略,仍然返回this。
也就是说,return要么返回对象,要么返回this,下面示例代替this返回对象,示例如下:
function BigUser() { this.name = "John"; return { name: "Godzilla" }; // <-- returns an object } alert( new BigUser().name ); // Godzilla, got that object
这个示例return空,或在写原始类型,其实都不影响。
function SmallUser() { this.name = "John"; return; // finishes the execution, returns this // ... } alert( new SmallUser().name ); // John
大多数构造函数无需返回,这里提醒这种特殊行为,仅仅为了知识完整性。
忽略括号
顺便说下,调用构造函数是,如果没有参数,我们可以省略对象标识后面的括号。
let user = new User; // <-- no brackets // same as let user = new User();
忽略括号并不是一个好的代码风格,但规范中是允许的。
使用构造函数创建对象提供了很大的灵活性,提供参数可以定义不同的对象。
当然,我们不仅给this增加属性,也可以增加方法。
下面示例创建对象,使用name参数,并增加一个方法sayHi:
function User(name) { this.name = name; this.sayHi = function() { alert( "My name is: " + this.name ); }; } let john = new User("John"); john.sayHi(); // My name is: John /* john = { name: "John", sayHi: function() { ... } } */
构造函数或简称构造器,是普通函数,但有一般约定,名称第一个字母大写。
构造函数使用new调用,即开始创建一个空this对象,然后返回填充内容的this。
我们能使用构造函数创建多个类似对象,当日内容不仅这些,后面进一步说明。
Javascript给一些内置对象提供了构造函数,如日期的Date,集合Set等。
Atas ialah kandungan terperinci JavaScript中构造函数与new操作符的实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!