constructor的解释:构造函数是一个函数,用来创建和初始化对象。每个构造函数都有一个关联的原型对象,用来实现继承和共享属性。
举例子说明,比如
- var A = function (){};
- var a = new A();
- console.log(a.constructor) // 此时输出的就是A的函数体,即function(){}
从逻辑上来说,实例a的class是A, 它的构造函数是个匿名函数function(){}, 根据输出可能我们还不能判断a.constructor到底是不是指向。于是,重新执行代码:
- console.log(a.constructor === A); //true
这次验证了我们的判断,实例a的constructor就是指向A.
而A.prototype.constructor又是指向谁呢?这个不难判断,因为实例a.constructor默认就是指向A.prototype.constructor,即
- console.log(a.constructor === A.prototype.constructor); //true
- console.log(A.prototype.constructor === A);//true
通过上面的测试,可以判断轻松判断javascript一些内置对象的construcor比如[1,2,4]它的constructor是Array, true的constructor是Boolean等。
- var arr ={1,2,4}
- console.log(arr.constructor); //function Array() { [native code] }
- console.log(arr.constructor === Array); //true
- var bool = true;
- console.log(bool.constructor);//function Boolean() { [native code] }
于是也得到了验证。
看到a.constructor的输出结果,可能会有种想法,就是用constructor来判断这个对象的类型,因为在内置对象的constructor.toString()之后,都有字符串反映出这个对象的类型,比如上面的例子,arr.constructor的输出为function Array() { [native code] }, 我们可以截取“Array”, 'Boolean' 部分就可以获取到对象的类型。
constructor
这种情况下是可以的,但是就像第一个里面,如果一些自定义的类,它的实例的constructor的输出的结果是个匿名函数,所以我们没法判断类型。其实也是可以解决的,既然没名字,那就取个名字,比如:
- var C = function C(){}
- var c = new C();
- console.log(c.constructor);//function C(){}
发现拿到了我们想要的东西,但是会不会影响C的功能呢,其实是不会的,可以自己验证下。
到这里貌似用constructor来判断对象类型已经完美了,其实还有一种情况没考虑到,如果prototype变了,constructor还是不是我们想要的呢。
- var D = function D(){};
- D.prototype = {};
- var d = new D();
- console.log(d.constructor); //function Object() { [native code] }
发现不是我们期望的function D(){}
这是因为实例的的constructor指向原型的constructor, 而这里的D的原型已经被{}覆盖了,{}的构造器显然是function Object() { [native code] }。
那怎么修复构造器被改的问题呢,可以重新修复下。
- var D = function D(){};
- D.prototype = {constructor: D}; //修复
- var d = new D();
- console.log(d.constructor); //function D(){}
这回可以了。。
其实这个判断类型的思路,只是为了介绍constructor,在javascript不需要详细的判断每个自定义Class实例是什么类型,一般情况只需要判断出内置对象的类型比如,Array、Function、RegExp等等,具体方法这里不做介绍。