js构造函数
构造函数(Constructor Function)是 JavaScript 中创建对象的一种重要方式,它不仅让我们能够创建具有相似属性和方法的对象,还能充分利用 JavaScript 的原型继承机制,实现代码的高效复用。本文将深入探讨构造函数的原理、使用方法、与类的关系,以及一些高级用法和注意事项。
构造函数示例,用于创建 Person 对象
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
}
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);
person1.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.
person2.sayHello(); // 输出: Hello, my name is Bob and I am 25 years old.构造函数与普通函数区别
- 构造函数的,用来区分于普通函数(驼峰命名),此为约定俗成
- 构造函数内部使用的this对象,来指向即将要生成的实例对象,而普通函数中的this指向调用函数的对象(没有对象时默认为window)
- 构造函数,但也可以用return语句,返回值会根据return值的类型而有所不同。普通函数可使用return返回值
- 构造函数进行调用,普通函数直接调用
隐藏的构造函数
- var a={}是var a=new Object()的语法糖
- var a=[]是var a=new Array()的语法糖
- 的语法糖
new一个对象的过程
- 创建一个新对象
- this指向这个新对象
- 执行代码,即对this赋值
- 返回this
解析(以Person函数为例): 1.创建一个新对象p 2.将构造函数Person()中的this指向新创建的对象p 3.p的_proto_(隐式原型)属性指向Person函数的prototype(显示原型),创建构造函数与原型以及对象的关系 4.调用对象,执行Person内属性或方法
手写new函数
js中的new函数可以手写来测试,可以更好的了解new函数的执行流程
function newTest (constructFunction){
let obj = {};
obj.__proto__ = constructFunction.prototype;
return function(){
constructFunction.apply(obj,arguments);
return obj;
}
}构造函数与原型
每个函数在创建时,都会有一个 prototype 属性,这个属性是一个对象,包含了该构造函数实例共享的属性和方法。利用原型对象,我们可以避免在每次创建实例时都重新定义方法,从而节省内存。
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);
person1.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.
person2.sayHello(); // 输出: Hello, my name is Bob and I am 25 years old.
console.log(person1.sayHello === person2.sayHello); // 输出: true通过将 sayHello 方法添加到 Person.prototype,我们确保了所有 Person 实例共享同一个 sayHello 方法,而不是为每个实例创建一个新的方法。
构造函数与类(Class)
ES6 引入了类(class)语法,使得定义构造函数和原型方法更加简洁和易读。类实际上是构造函数的语法糖,本质上还是使用了原型机制。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);
person1.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.
person2.sayHello(); // 输出: Hello, my name is Bob and I am 25 years old.高级用法与注意事项
1. 使用 Object.create 进行继承
构造函数和原型可以结合 Object.create 方法实现继承:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
};
function Dog(name, breed) {
Animal.call(this, name); // 调用父构造函数
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
console.log(`${this.name} barks.`);
};
const dog = new Dog('Rex', 'Labrador');
dog.speak(); // 输出: Rex barks.通过 Object.create 方法,我们可以创建一个新的对象,并将其原型设置为指定的对象,从而实现继承。
2. 静态方法
构造函数也可以定义静态方法,静态方法是直接绑定在构造函数上的,而不是实例对象上:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.isAdult = function(age) {
return age >= 18;
};
console.log(Person.isAdult(20)); // 输出: true
console.log(Person.isAdult(16)); // 输出: false在 ES6 类语法中,可以使用 static 关键字定义静态方法:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
static isAdult(age) {
return age >= 18;
}
}
console.log(Person.isAdult(20)); // 输出: true
console.log(Person.isAdult(16)); // 输出: false