如果丢失构造函数,可以使用哪些线程?

时间:2018-08-06 08:35:49

标签: javascript

我有这样的例子

function test1(){this.a = 1;}
function test2(){this.b = 2;}
function test3(){this.c = 3;}
test2.prototype = Object.create(test1.prototype);
test2.prototype.constructor = test2;
test3.prototype = Object.create(test1.prototype); // lose constructor
var q = new test2();//we can find constructor test2 in __proto__
var q2 = new test3();//there is no such field in __proto__

enter image description here

q2中的

到构造函数test3的链接丢失。

为什么以及如何以不良方式产生影响?

2 个答案:

答案 0 :(得分:3)

通常,您会避免这种情况,但我建议您不要这样做。 (尤其是因为如果您要使用构造函数的层次结构,而不是ES5样式的模式,并且我class会自动为您正确设置,则建议您使用class语法。)

长期以来,尽管JavaScript为其设置给函数constructor的默认对象上的prototype属性进行了设置,但并未使用。但是用户级代码有时会这样做,其目的很明显:获取(可能)构造一个对象的构造函数。从ES2015开始,JavaScript本身也使用constructor属性,用于从现有对象创建新对象的地方,例如现有数组中的新数组(例如slice) ,或来自现有RegExp的新RegExp(当您在String#split中使用正则表达式时,它会在幕后进行),即来自现有Promise(例如{ {3}})等。

因此,如果您使用错误的有效constructor属性保留层次结构,则期望该属性正确的操作将失败。但是,如果您不对内置函数进行子类化(并且再次使用class)并且不编写使用constructor的代码,那么实际上无法使用该操作明确地,它将不会被用于任何用途。

答案 1 :(得分:1)

让我们举个例子。 我们可以通过4种方式获得新的1,2,3数组;

  1. [1,2,3]
  2. 新数组(1,2,3)
  3. Array(1,2,3)
  4. 新Array.prototype.constructor(1,2,3)

在最后一个变体中,我们使用 constructor 。因此,如果我们想要新的数组来创建反向实例,那么我们将从Array继承,但是如果我们丢失了构造函数,则第4个将以另一种方式进行操作。

const myArray = function(){ 
   const args = Array.prototype.slice.call(arguments); 
   return args.reverse();    
};    
myArray.prototype = Object.create(Array.prototype);
console.log(new myArray(1, 2, 3, 4, 5)); //reversed
const newMyArray = new myArray.prototype.constructor(1,2,3,4,5); //not reversed