加载笔记内容...
加载笔记内容...
构造函数在技术上是常规函数。不过有两个约定:
1function User(name) {
2 this.name = name;
3 this.isAdmin = false;
4}
5
6let user = new User("Jack");
7
8alert(user.name); // Jack
9alert(user.isAdmin); // false
当一个函数被使用 new
操作符执行时,它按照以下步骤:
this
。this
,为其添加新的属性。this
的值。在一个函数内部,我们可以使用 new.target
属性来检查它是否被使用 new
进行调用了。
对于常规调用,它为 undefined,对于使用 new
的调用,则等于该函数:
1function User() {
2 alert(new.target);
3}
4
5// 不带 "new":
6User(); // undefined
7
8// 带 "new":
9new User(); // function User { ... }
它可以被用在函数内部,来判断该函数是被通过 new
调用的“构造器模式”,还是没被通过 new
调用的“常规模式”。
我们也可以让 new
调用和常规调用做相同的工作,像这样:
1function User(name) {
2 if (!new.target) { // 如果你没有通过 new 运行我
3 return new User(name); // ……我会给你添加 new
4 }
5
6 this.name = name;
7}
8
9let john = User("John"); // 将调用重定向到新用户
10alert(john.name); // John
1function fakeNew() {
2 // 创建新对象
3 var obj = Object.create(null);
4 var Constructor = [].shift.call(arguments);
5 // 将对象的 __proto__ 赋值为构造函数的 prototype 属性
6 obj.__proto__ = Constructor.prototype;
7 // 将构造函数内部的 this 赋值为新对象
8 var ret = Constructor.apply(obj, arguments);
9 // 返回新对象
10 return typeof ret === "object" && ret !== null ? ret : obj;
11}
12
13function Group(name, member) {
14 this.name = name;
15 this.member = member;
16}
17
18var group = fakeNew(Group, "hzfe", 17);