普通函数、构造函数、class区别

303 阅读2分钟

函数与构造函数区别

  1. 命名

普通函数声明通常小驼峰命名,构造函数大驼峰命名

  1. 调用方式

普通函数直接name(), 构造函数 new name()

  1. 作用

普通函数处理逻辑,构造函数用来新建实例对象

  1. 返回值

普通函数默认没有返回值,可以由return语句返回结果,构造函数默认返回一个实例对象,若构造函数中return语句,1、return基本数据类型,返回实例对象;2、return 引用类型数据 ,返回引用类型数据

function fn () {}
let res = fn();
console.log(res); // undefined

// 构造函数
function Test() {}
let res2 = new Test();
console.log(res2); // {}

// 构造函数中有return
function Test2() {
  // return 888 // 基本数据类型
  return {name: 'dwd'}
}
let res3 = new Test2();
console.log(res3); // 基本数据类型 : {}   引用类型 :{name: 'dwd'}
  1. 指向

构造函数默认this指向创建的实例,普通函数谁调用指向谁,默认指向window

构造函数与class区别

  1. class 无法变量提升
// class
new Test() // ReferenceError: Test is not defined
class Test {}

// 构造函数
new Fn(); // 变量提升
function Fn() {}
  1. class 类的内部所有定义的方法,都是不可枚举的
class Point {
  constructor(x, y) {
    // ...
  }

  toString() {
    // ...
  }
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"] constructor未定义默认也有

// 构造函数
var Point = function (x, y) {
  // ...
};

Point.prototype.toString = function () {
  // ...
};

Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]
  1. class 不用new 无法调用、构造函数可以直接调用
class Test{}
function Fn() {}

Test() // Test cannot be invoked without 'new'

Fn() 
  1. class 含有静态方法可以不被实例继承,但是可以被子类继承,静态方法通过类直接调用
// 静态方法不被实例继承
class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
// 子类继承静态方法
class Foo {
  static classMethod() {
    return 'hello';
  }
}

class Bar extends Foo {
}

Bar.classMethod() // 'hello'
// 子类super继承
class Foo {
  static classMethod() {
    return 'hello';
  }
}

class Bar extends Foo {
  static classMethod() {
    return super.classMethod() + ', too';
  }
}

Bar.classMethod() // "hello, too"

new 操作符做了什么

  1. 创建了一个空的js对象(即{})
  2. 将空对象的原型_proto_指向构造函数的原型prototype
  3. 将空对象作为构造函数的上下文(改变this指向)
  4. 对构造函数有返回值的判断
function create(that,...args){
  //1、创建一个空的对象
  let obj = {};
  //2、将空对象的原型_proto_指向构造函数的原型prototype
  obj.__proto__ = that.prototype
  //3、改变构造函数的上下文(this),并将剩余的参数传入
  let result = that.apply(obj, args);
  //4、在构造函数有返回值的情况进行判断
  return result instanceof Object ? result : obj;
}