在 ES5 中判断函数如何被调用
在 ES5 中判断函数是不是使用了 new 来调用(即作为构造器),最流行的方式是使用 instanceof , 例如:
function Person(name) {
if (this instanceof Person) {
this.name = name;
// 使用 new
} else {
throw new Error("You must use new with Person.")
}
}
var person = new Person("Nicholas");
var notAPerson = Person("Nicholas");
// 抛出错误
此处对 this 值进行了检查,来判断其是否为构造器的一个实例:若是,正常继续执行;否 则抛出错误。这能奏效是因为 [[Construct]] 方法创建了 Person 的一个新实例并将其赋值 给 this 。可惜的是,该方法并不绝对可靠,因为在不使用 new 的情况下 this 仍然可能 是 Person 的实例,正如下例:
function Person(name) {
if (this instanceof Person) {
this.name = name;
// 使用 new
} else {
throw new Error("You must use new with Person.")
}
}
var person = new Person("Nicholas");
var notAPerson = Person.call(person, "Michael");
// 奏效了!
调用 Person.call() 并将 person 变量作为第一个参数传入,这意味着将 Person 内部的 this 设置为了 person 。对于该函数来说,没有任何方法能将这种方式与使用 new 调用区 分开来。
new.target 元属性 为了解决这个问题, ES6 引入了 new.target 元属性。元属性指的是“非对象”(例如 new ) 上的一个属性,并提供关联到它的目标的附加信息。当函数的 [[Construct]] 方法被调用 时, new.target 会被填入 new 运算符的作用目标,该目标通常是新创建的对象实例的构造 器,并且会成为函数体内部的 this 值。而若 [[Call]] 被执行, new.target 的值则会是 undefined 。
【在 ES5 中判断函数如何被调用】通过检查 new.target 是否被定义,这个新的元属性就让你能安全地判断函数是否被使用 new 进行了调用。
function Person(name) {
if (typeof new.target !== "undefined") {
this.name = name;
// 使用 new
} else { throw new Error("You must use new with Person.") }
}
var person = new Person("Nicholas");
var notAPerson = Person.call(person, "Michael");
// 出错!
使用 new.target 而非 this instanceof Person , Person 构造器会在未使用 new 调用时 正确地抛出错误。 也可以检查 new.target 是否被使用特定构造器进行了调用,例如以下代码:
function Person(name) {
if (new.target === Person) {
this.name = name;
// 使用 new
} else { throw new Error("You must use new with Person.") }
}
function AnotherPerson(name) {
Person.call(this, name);
}
var person = new Person("Nicholas");
var anotherPerson = new AnotherPerson("Nicholas");
// 出错!
在此代码中,为了正确工作, new.target 必须是 Person 。当调用 new AnotherPerson(“Nicholas”) 时, Person.call(this, name) 也随之被调用,从而抛出了错误, 因为此时在 Person 构造器内部的 new.target 值为 undefined ( Person 并未使用 new 调用)。
推荐阅读
- 热闹中的孤独
- 你到家了吗
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 闲杂“细雨”
- 杜月笙的口才
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 赢在人生六项精进二阶Day3复盘
- 祖母走了