js 构造函数 constructor(JS constructor)

什么是 构造函数constructor

  • 函数名首字母必须大写
  • 内部使用this对象,来指向将要生成的对象实例
  • 使用new操作符来调用构造函数,并返回对象实例

构造函数用来干什么

  • 所谓构造函数,就是提供了一个生成对象的模板并描述对象的基本结构的函数。一个构造函数,可以生成多个对象,每个对象都有相同的结构。总的来说,构造函数就是对象的模板,对象就是构造函数的实例。

每一个对象实例都可以通过constructor对象访问它的构造函数

let getConst={}
getConst.constructor
// Object() { [native code] } 这个可以看下js对象的解析过程
或
function getConst(){
   this.name="构造函数"
}
let newConst=new getConst();
newConst.constructor.name
//'getConst'


constructor不能被修改


class testObj { constructor() { console.log("testObj"); } }
testObj.constructor=function(){ console.log("new constructor") }
new testObj()
//testObj

一般来说构造函数不能修改的,为了避免原型链污染。在一个应用中,如果攻击者控制并修改了一个对象的 constructor,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。参考去年Lodash被爆出的重大漏洞。原型链污染有许多预防方式,说个简单粗暴适合前端团队Leader使用的:用Object.freeze(obj)冻结指定对象,使之不能被修改属性,也不可扩展。

参考:https://stackoverflow.com/questions/9267157/why-is-it-impossible-to-change-constructor-function-from-prototype




es6 class里的constructor和super

其中 constructor 方法是类的构造函数,是一个默认方法,通过 new 命令创建对象实例时,自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,一个默认的 consructor 方法会被默认添加。所以即使你没有添加构造函数,也是会有一个默认的构造函数的。一般 constructor 方法返回实例对象 this ,但是也可以指定 constructor 方法返回一个全新的对象,让返回的实例对象不是该类的实例。

constructor的作用

初始化变量

super

super 这个关键字,既可以当做函数使用,也可以当做对象使用。这两种情况下,它的用法完全不用。

1. 当做函数使用

class A {}
class B extends A {
  constructor() {
    super();  // ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。
  }
}

注:在 constructor 中必须调用 super 方法,因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,而 super 就代表了父类的构造函数。super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B,因此 super() 在这里相当于 A.prototype.constructor.call(this, props)。


class A {
  constructor() {
    console.log(new.target.name); // new.target 指向当前正在执行的函数
  }
}
 
class B extends A {
  constructor() {
    super();
  }
}
 
new A(); // A
new B(); // B
可以看到,在 super() 执行时,它指向的是 子类 B 的构造函数,而不是父类 A 的构造函数。也就是说,super() 内部的 this 指向的是 B。



参考:https://www.bbsmax.com/A/1O5E37Pbz7/



————————

什么是 构造函数constructor

  • Function names must be capitalized
  • Internally, this object is used to point to the object instance to be generated
  • Use the new operator to call the constructor and return an object instance

What are constructors for

  • The so-called constructor is a function that provides a template for generating an object and describes the basic structure of the object. A constructor can generate multiple objects, and each object has the same structure. In general, the constructor is the template of the object, and the object is the instance of the constructor.

Each object instance can access its constructor through the constructor object

let getConst={}
getConst.constructor
// Object() { [native code] } 这个可以看下js对象的解析过程
或
function getConst(){
   this.name="构造函数"
}
let newConst=new getConst();
newConst.constructor.name
//'getConst'


constructor不能被修改


class testObj { constructor() { console.log("testObj"); } }
testObj.constructor=function(){ console.log("new constructor") }
new testObj()
//testObj

一般来说构造函数不能修改的,为了避免原型链污染。在一个应用中,如果攻击者控制并修改了一个对象的 constructor,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。参考去年Lodash被爆出的重大漏洞。原型链污染有许多预防方式,说个简单粗暴适合前端团队Leader使用的:用Object.freeze(obj)冻结指定对象,使之不能被修改属性,也不可扩展。

参考:https://stackoverflow.com/questions/9267157/why-is-it-impossible-to-change-constructor-function-from-prototype




es6 class里的constructor和super

The constructor method is the constructor of the class. It is a default method. When creating an object instance through the new command, this method will be called automatically. A class must have a constructor method. If it is not explicitly defined, a default constructor method will be added by default. So even if you don’t add a constructor, there will be a default constructor. Generally, the constructor method returns the instance object this, but you can also specify the constructor method to return a new object so that the returned instance object is not an instance of this class.

constructor的作用

initialize variable

super

The keyword super can be used as either a function or an object. In both cases, its usage is completely unnecessary.

1. 当做函数使用

class A {}
class B extends A {
  constructor() {
    super();  // ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。
  }
}

注:在 constructor 中必须调用 super 方法,因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,而 super 就代表了父类的构造函数。super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B,因此 super() 在这里相当于 A.prototype.constructor.call(this, props)。


class A {
  constructor() {
    console.log(new.target.name); // new.target 指向当前正在执行的函数
  }
}
 
class B extends A {
  constructor() {
    super();
  }
}
 
new A(); // A
new B(); // B
可以看到,在 super() 执行时,它指向的是 子类 B 的构造函数,而不是父类 A 的构造函数。也就是说,super() 内部的 this 指向的是 B。



参考:https://www.bbsmax.com/A/1O5E37Pbz7/