函数与构造函数区别
- 命名
普通函数声明通常小驼峰命名,构造函数大驼峰命名
- 调用方式
普通函数直接name(), 构造函数 new name()
- 作用
普通函数处理逻辑,构造函数用来新建实例对象
- 返回值
普通函数默认没有返回值,可以由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'}
- 指向
构造函数默认this指向创建的实例,普通函数谁调用指向谁,默认指向window
构造函数与class区别
- class 无法变量提升
// class
new Test() // ReferenceError: Test is not defined
class Test {}
// 构造函数
new Fn(); // 变量提升
function Fn() {}
- 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"]
- class 不用new 无法调用、构造函数可以直接调用
class Test{}
function Fn() {}
Test() // Test cannot be invoked without 'new'
Fn()
- 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 操作符做了什么
- 创建了一个空的js对象(即{})
- 将空对象的原型_proto_指向构造函数的原型prototype
- 将空对象作为构造函数的上下文(改变this指向)
- 对构造函数有返回值的判断
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;
}