admin管理员组文章数量:1794759
【Javascript】判断函数被调用的方法
前情提要
ES5及早期版本中函数具有多重功能,可以结合new使用,函数内的this值将指向一个新对象,在ES6中,函数混乱的双重身份有一些改变。
Javascript函数有两个不同的内部方法:[[Call]]和[[Construct]],当遇到通过new关键字调用函数时,执行的是[[Construct]]函数,它负责创建一个通常被称作实例的新对象,然后再执行函数体,将this绑定到实例上。否则将执行[[Call]]函数,从而直接执行代码中的函数体。具有[[Construct]]方法的函数被统称为构造函数。
注:不是所有函数都有construct方法,例如箭头函数,所以也不是所有方法都可以通过new来调用。
ES5判断函数被调用的方法在ES5中要想确定一个函数是否通过new关键字被调用,最流行的方式是使用instanceof
function Person (name) { if(this instanceof Person){ this.name = name } else { throw new Error('未通过new调用') } } //var person1 = new Person('Hello') //正常 var person2 = Person('Hello') //抛出异常由于construct方法会创建一个Person实例,并将this绑定到新实例上,所以可以通过检查this值是否是构造函数的实例,如果是则代码可以正常运行,如果不是则抛出异常。
但这种方法并不是可靠的,再看一个例子
function Person (name) { if(this instanceof Person){ this.name = name } else { throw new Error('未通过new调用') } } var person1 = new Person('Hello') var person2 = Person.call(person1,'Hello') //正常执行使用call方法将this设为person1的实例,对于函数本身,无法通过区分Person.call还是new关键字得到Person的实例。
ES6判断函数被调用的方法ES6引入了new.target这个元属性。原属性是指非对象的属性。
描述:通常"new."的作用是提供属性访问的上下文,但这里"new."其实不是一个真正的对象。不过在构造方法调用中,new.target指向被new调用的构造函数,所以"new."成为了一个虚拟上下文。
当调用函数construct方法时,new.target被赋值为new操作符的目标,通常是新创建对象的实例。如果调用call方法,则new.target的值是Undefined。
function Person(name) { if(typeof new.target !== 'undefined') { this.name = name; } else { throw new Error('未通过new关键字调用') } } var person = new Person('Hello') var Notperson = new Person.call('Hello') //抛出错误也可以使用new.target是否被某个特定构造函数所调用
function Person(name) { if(new.target === Person) { this.name = name; } else { throw new Error('未使用new关键字调用') } } function AnotherPerson(name) { Person.call(this, name) } var person = new Person('Hello') var anotherPerson = new AnotherPerson('Hello')注:在函数外使用new.target是一个语法错误。
本文标签: 函数方法JavaScript
版权声明:本文标题:【Javascript】判断函数被调用的方法 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686495552a73924.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论