构造函数
//构造函数
function Point(x,y){
    this.x = x;
    this.y = y;
}
var point = new Point(1,2);
console.log(point);// Point {x: 1, y: 2}
console.log(point.x,point.y);//输出 1 2

我们知道,构造函数和普通函数一样,唯一的区别是,构造函数是通过操作符new来调用。
如果一不小心没有new,直接当普通函数用了呢?

//普通函数
function Point(x,y){
    this.x = x;
    this.y = y;
}
var p = Point(3,4);
console.log(p);//输出 undefined
console.log(window.x,window.y);//输出 3 4

可以看到,Point(3,4)返回的是undefined,并不是预期的Point实例,而且xy被误添加到window对象上了。

作用域安全的构造函数

呃,那有啥办法能避免这种不小心么?
有的,作用域安全的构造函数,它能保证:不论你new抑或不new,都会返回一个新实例。

呃,作用域安全的构造函数 长啥样?
其实,我们有很多机会与它相遇。比如,new Vue(options),函数Vue就是 作用域安全的构造函数。

  function Vue (options) {
    if (!(this instanceof Vue)
    ) {
      warn('Vue is a constructor and should be called with the `new` keyword');
    }
    //...
  }

又比如,http.createServer(options),函数Server也是 作用域安全的构造函数。

function createServer(opts, requestListener) {
  return new Server(opts, requestListener);
}
function Server(options, requestListener) {
  if (!(this instanceof Server)) return new Server(options, requestListener);
  //...
}

这种构造函数首先会甄别this是不是当前类的一个实例,是,OK,继续往下走;不是,Sorry,先new一个吧,然后才往下走。

照葫芦画瓢,我们把之前的例子改造一下。

function Point(x,y){
    if(!(this instanceof Point)){
        return new Point(x,y);
    }
    this.x = x;
    this.y = y;
}
var point = new Point(1,2);
console.log(point);// 输出 Point {x: 1, y: 2}
console.log(point.x,point.y);// 输出 1 2

var p = Point(3,4);
console.log(p);// 输出 Point {x: 3, y: 4}
console.log(p.x,p.y);//输出 3 4

可以看到,不论是通过new来调用,还是当作普通函数来使用,最后都会返回一个Point实例

Logo

前往低代码交流专区

更多推荐