JavaScript 面向对象设计二 构造函数模式
构造函数和普通函数的区别
在JavaScript中,构造函数和普通函数的区别在于函数的调用方式不同。
普通函数使用 function
声明,调用方式是 函数名()
。
而构造函数使用 function
声明,调用方式是使用 new
操作符来调用。
构造函数模式的基本使用方法
构造函数通常用来创建一个对象,并对对象进行初始化。
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
const person1 = new Person('张三', 18, '男');
console.log(person1); // {name: '张三', age: 18, gender: '男'}
const person2 = new Person('李四', 20, '女');
console.log(person2); // {name: '李四', age: 20, gender: '女'}
在上面的代码中,我们定义了一个构造函数 Person
,它有3个参数 name
,age
,gender
。当我们使用 new
操作符来调用这个函数时,它会创建一个新的对象,并将这个对象的属性设置为传入的参数,最后返回这个新的对象。
构造函数内部的this指向
在构造函数内部,this
指向新创建的对象。
function Person(name, age, gender) {
console.log(this); // Person {}
this.name = name;
this.age = age;
this.gender = gender;
}
const person = new Person('张三', 18, '男');
console.log(person); // {name: '张三', age: 18, gender: '男'}
上面的代码中,当我们在 Person
构造函数内部使用 console.log(this)
输出 this
时,它指向一个空对象 {}
。这是因为在使用 new
操作符调用 Person
函数时,它会将 this
指向一个新的空对象,然后再将这个新对象返回。
构造函数中的方法和属性
在构造函数中,我们可以定义方法和属性。方法和属性可以对创建的对象进行操作,也可以通过对象来访问和修改。
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayHello = function () {
console.log(`Hello, my name is ${this.name},I am ${this.age} years old.`);
}
}
const person = new Person('张三', 18, '男');
console.log(person); // {name: '张三', age: 18, gender: '男'}
person.sayHello(); // Hello, my name is 张三,I am 18 years old.
在上面的代码中, Person
构造函数中定义了一个 sayHello
方法,用来打印对象的 name
和 age
。在 person
对象上使用 sayHello()
方法时,它将输出 Hello, my name is 张三,I am 18 years old.
。
构造函数模式的缺陷
构造函数模式也存在一些缺陷。
- 每个函数都有自己的方法和属性,造成内存的浪费。
- 所有方法都得在函数内部定义,导致代码重复,不利于代码维护。
可以使用原型链模式对其进行改进。
构造函数模式和原型链模式的结合
可以将对象的方法和属性定义在构造函数的原型上,从而让所有对象共享这些方法和属性,减少代码量,提高效率。
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.sayHello = function () {
console.log(`Hello, my name is ${this.name},I am ${this.age} years old.`);
}
const person = new Person('张三', 18, '男');
console.log(person); // {name: '张三', age: 18, gender: '男'}
person.sayHello(); // Hello, my name is 张三,I am 18 years old.
示例:创建一个图形对象
function Shape(x, y) {
this.x = x;
this.y = y;
}
Shape.prototype.move = function (x, y) {
this.x += x;
this.y += y;
console.log(`Shape moved to (${this.x}, ${this.y})`);
}
function Rectangle(x, y, width, height) {
Shape.call(this, x, y);
this.width = width;
this.height = height;
}
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
Rectangle.prototype.draw = function() {
console.log('Drawing a Rectangle');
}
const rect = new Rectangle(0, 0, 100, 100);
rect.move(10, 10); // Shape moved to (10, 10)
rect.draw(); // Drawing a Rectangle
在上述示例中,我们定义了一个 Shape
构造函数,它包含两个属性 x
和 y
,还有一个 move
方法。
然后我们创建了一个 Rectangle
构造函数,它继承自 Shape
构造函数,包含 width
和 height
两个属性,还有一个 draw
方法。
我们使用 Object.create
方法来定义 Rectangle
构造函数的原型对象,并将其设置为 Shape.prototype
。这样 Rectangle
就可以继承到 Shape
的所有方法和属性。
最后我们创建了一个 rect
对象,它调用了 move
和 draw
方法。
示例:创建一个按钮对象
function Button(config) {
this.width = config.width || 150;
this.height = config.height || 50;
this.color = config.color || 'red';
this.text = config.text || 'Click me!';
this.$el = document.createElement('button');
}
Button.prototype.render = function (target) {
this.$el.style.width = this.width + 'px';
this.$el.style.height = this.height + 'px';
this.$el.style.background = this.color;
this.$el.innerHTML = this.text;
target.appendChild(this.$el);
}
const button = new Button({ width: 200, height: 60, color: 'blue', text: 'Submit' });
button.render(document.body);
在上述示例中,我们定义了一个 Button
构造函数,它通过传入一个配置对象来设置按钮的一些属性。然后我们在构造函数中创建了一个 HTML 按钮元素,并定义了一个 render
方法将按钮元素渲染到指定的页面元素上。
最后我们创建了一个 button
对象,将它渲染到页面上。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript面向对象设计二 构造函数模式 - Python技术站