明确函数的多重用途

 

上述函数,没有通过new关键字来调用Person(),最终返回undefined。

原因:

JavaScript函数有两个不同的内部方法: [[Call]] 和 [[Construct]]

(1)当通过new关键字调用函数时,执行的是[[Construct]]函数,它负责创建一个通用被称作实例的新对象,

然后执行函数体,将this绑定到实例上

(2)如果不通过new关键字调用函数,则执行[[Call]]函数,从而执行代码中的函数体

具有[[Construct]]方法的函数统称为构造函数,

不是所有的函数都有[[Construct]]方法,因此不是所有的函数都可以通过new来调用,例如箭头函数

 

在ECMAScript5 中判断函数被调用的方法

如果想判断一个函数是否通过new关键字调用,或者作为构造函数被调用,如下:

通常来说,上述通过instanceof来判断调用者是否为Person实例是正确的,但是还有一种不依赖于new关键字的方法也可以把this绑定到Person实例上

没有报错

这样在Person函数里将this设置成了person实例,对于函数本身,无法区分是通过Person.call() 还是new关键字得到的Person实例

 

元属性new.target

为了判断函数是否通过new关键字调用的 问题,ECMAScript6 引入了new.target这个元属性,指的是非对象的属性,可以提供非对象目标的补充信息,比如new

当调用函数的[[Construct]]方法时,new.target被赋值为new操作符的目标,通常是新创建的对象实例,也就是函数体内this的构造函数

如果调用[[Call]] 方法,则new.target的值为undefined,这样可以安全地检测函数是否通过new调用了

我们还可以检测new.target 是否被某个特定构造函数调用,举例:

如果程序可以正确运行,则new.target属性必须为Person

anotherPerson 通过 call来 调用 Person构造函数,  没有使用new  new.target为undefined

另外:在函数外,使用new.target是语法错误

posted @ 2018-10-15 16:04  你今天学习了吗  阅读(277)  评论(0)    收藏  举报