JavaScript基础-构造函数模式

370 阅读3分钟

这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

基于构造函数创建自定义类(constructor)

  1. 在普通函数执行的基础上"new xxx()",这样就不是普通函数执行了,而是构造函数执行,当前的函数名称之为“类名”,接收的返回结果是当前类的一个实例
  2. 自己创建的类名,最好第一个单词首字母大写
  3. 这种构造函数设计模式执行,主要用于组件、类库、插件、框架等的封装,平时编写业务逻辑一般不这样处理
function Fn() {}
Fn(); // => 普通函数执行
var f = new Fn(); // => Fn是类 f是类的一个实例
var f2 = new Fn(); // => f2也是Fn的一个实例,f2和f是独立分开的,互不影响

JS 中创建值有两种方式

  1. 字面量表达式
var obj = {};
  1. 构造函数模式
var obj = new Object();

不管是哪一种方式创造出来的都是 Object 类的实例,而实例之间是独立分开的,所以 var xxx={} 这种模式就是 JS 中的单例模式

创建基本类型

基本数据类型基于两种不同的模式创建出来的值是不一样的

  • 基于字面量方式创建出来的值是基本类型值
var num1 = 12;
console.log(typeof num1); // => "number"
  • 基于构造函数创建出来的值是引用类型
var num2 = new Number(12);
console.log(typeof num2); // => "object"

函数的执行

function Fn(name, age) {
  var n = 10;
  this.name = name;
  this.age = age + n;
}

image.png

普通函数的执行

Fn();
  1. 形成一个私有的作用域
  2. 形参赋值
  3. 变量提升
  4. 代码执行
  5. 栈内存释放问题

构造函数执行

var f1 = new Fn("xxx", 20);
var f2 = new Fn("aaa", 30);

console.log(f1 === f2); //=> false:两个不同的实例(两个不同的堆内存地址)
console.log(f1.age); // => 30
console.log(f2.name); // => 'aaa'
console.log("name" in f1); // => true name&age在两个不同的实例都有存储,但是都是每个实例自己私有的属性
console.log(f1.n); // => undefined 只有this.xxx=xxx的才和实例有关系,n是私有作用域中的一个私有变量而已(this是当前类的实例)*/

构造函数执行,不写 RETURN

构造函数执行,不写 RETURN,浏览器会默认返回创建的实例,但是如果我们自己写了 RETURN?

  1. return 是的一个基本值,返回的结果依然是类的实例,没有受到影响

  2. 如果返回的是引用值,则会把默认返回的实例覆盖,此时接收到的结果就不在是当前类的实例了 => 构造函数执行的时候,尽量减少 RETURN 的使用,防止覆盖实例

function Fn() {
  var n = 10;
  this.m = n;
  // return;//=>这样 RETURN 是结束代码执行的作用,并且不会覆盖返回的实例
  // console.log(1);
}
var f = new Fn(); //=> new Fn; 在构造函数执行的时候,如果 Fn 不需要传递实参,我们可以省略小括号,意思还是创建实例(和加小括号没有区别)
console.log(f);