1. JavaScript创建对象的几种方式
JavaScript中创建对象有几种方式:
1.1 工厂模式
定义:工厂模式是指定义一个对象创建工厂方法,工厂方法可以接受参数,根据不同的参数创建不同的对象。
function createPerson(name, age, gender) {
let person = {};
person.name = name;
person.age = age;
person.gender = gender;
person.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
return person;
}
let person1 = createPerson('Alice', 28, 'female');
let person2 = createPerson('Bob', 30, 'male');
上述代码中,我们定义了一个createPerson工厂方法,可以用来创建Person对象。通过传入不同的参数,可以创建出不同的Person对象。在这个工厂中,我们使用了字面量的方式创建了一个空对象,然后给这个对象添加了name、age、gender属性和sayHello方法,并返回这个对象。创建Person对象的时候,我们直接调用createPerson方法,将返回的对象赋值给不同的变量。
1.2 构造函数模式
定义:在JavaScript中,构造函数模式是常用的一种创建对象的方式,它可以用于创建多个相似对象(如Person、Animal等)。构造函数与普通函数的区别在于构造函数名字通常以大写字母开头,而且构造函数必须通过new关键字来调用。
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);
};
}
let person1 = new Person('Alice', 28, 'female');
let person2 = new Person('Bob', 30, 'male');
上述代码中,我们定义了一个Person构造函数,通过new关键字来调用这个函数,就可以创建出Person对象。在构造函数中,我们使用了this来表示当前新创建的对象,并给这个对象添加了name、age、gender属性和sayHello方法。在创建Person对象的时候,我们直接调用Person构造函数,并将返回的对象赋值给不同的变量。
1.3 原型模式
定义:原型模式是一种创建对象的模式,它是利用构造函数的原型属性来实现共享属性和方法的。
function Person() {}
Person.prototype.name = 'Alice';
Person.prototype.age = 28;
Person.prototype.gender = 'female';
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
}
let person1 = new Person();
let person2 = new Person();
上述代码中,我们使用了一个Person构造函数,然后将它的属性和方法都添加到了它的原型(Person.prototype)中。这样,在创建Person对象的时候,只需要调用Person构造函数,就可以继承它的原型属性和方法,从而实现共享。
1.4 组合模式
定义:组合模式是一种创建对象的模式,它结合了构造函数模式和原型模式的优点。
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);
}
let person1 = new Person('Alice', 28, 'female');
let person2 = new Person('Bob', 30, 'male');
上述代码中,我们将构造函数中的属性定义放在了函数内部,将方法定义放在了原型上。这样既可以实现属性私有化,又可以实现方法共享。
2. JavaScript对象的增删改查
2.1 增加属性和方法
对于已经创建的JavaScript对象,可以通过以下两种方式来添加新的属性和方法:
点语法:使用点语法可以直接给对象添加新的属性或方法。例如:
let person = {
name: 'Alice',
age: 28,
};
person.gender = 'female'; // 添加新的属性
person.sayHello = function() { // 添加新的方法
console.log('Hello, my name is ' + this.name);
};
方括号语法:使用方括号语法也可以添加新的属性或方法,但需要用引号将属性名或方法名括起来。例如:
let person = {
name: 'Alice',
age: 28,
};
person['gender'] = 'female'; // 添加新的属性
person['sayHello'] = function() { // 添加新的方法
console.log('Hello, my name is ' + this.name);
};
2.2 删除属性和方法
对于已经创建的JavaScript对象,可以通过以下两种方式来删除属性和方法:
delete关键字:使用delete关键字可以删除对象的属性或方法。例如:
let person = {
name: 'Alice',
age: 28,
sayHello: function() {
console.log('Hello, my name is ' + this.name);
}
};
delete person.age; // 删除属性
delete person.sayHello; // 删除方法
设置属性为undefined:通过将对象的属性或方法设置为undefined,也可以实现类似删除的效果。例如:
let person = {
name: 'Alice',
age: 28,
sayHello: function() {
console.log('Hello, my name is ' + this.name);
}
};
person.age = undefined; // 删除属性
person.sayHello = undefined; // 删除方法
2.3 修改属性和方法
对于已经创建的JavaScript对象,可以通过以下两种方式来修改属性和方法:
点语法或方括号语法:使用点语法或方括号语法可以直接修改已有属性或方法的值。例如:
let person = {
name: 'Alice',
age: 28,
sayHello: function() {
console.log('Hello, my name is ' + this.name);
}
};
person.age = 30; // 修改属性
person['sayHello'] = function() { // 修改方法
console.log('Hi, my name is ' + this.name);
};
3. JavaScript对象的继承
3.1 原型继承
原型继承是通过继承父类的原型来实现的。在JavaScript中,每个对象都有一个[[Prototype]]的内部属性,用来存储该对象的原型。通过将子类的原型指向父类的实例,就可以实现原型继承。例如:
// 父类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
}
// 子类
function Student(name, age, grade) {
this.grade = grade;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
// 创建子类实例
let student = new Student('Alice', 18, 'A');
student.sayHello(); // "Hello, my name is Alice"
console.log(student.age); // 18
上述代码中,我们定义了一个Person父类和一个Student子类。在子类中,我们将Student.prototype指向了一个Person实例,这样就可以实现原型继承。在创建子类实例的时候,可以通过子类实例访问到父类的原型方法。
3.2 构造函数继承
在构造函数继承中,子类通过调用父类的构造函数来实现继承。例如:
// 父类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
}
// 子类
function Student(name, age, grade) {
Person.call(this, name, age);
this.grade = grade;
}
// 创建子类实例
let student = new Student('Alice', 18, 'A');
student.sayHello(); // 报错:student.sayHello is not a function
console.log(student.age); // 18
上述代码中,我们定义了一个Person父类和一个Student子类。在子类中,我们通过使用call方法来调用父类的构造函数,从而实现继承。在创建子类实例的时候,可以通过子类实例访问到父类的属性,但不能访问到父类的原型方法。
3.3 组合继承
组合继承是将原型继承和构造函数继承组合在一起的继承方式。在组合继承中,子类既继承了父类原型中的属性和方法,又继承了父类构造函数中的属性,同时还可以添加子类自己特有的属性和方法。例如:
// 父类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
}
// 子类
function Student(name, age, grade) {
Person.call(this, name, age);
this.grade = grade;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
// 添加子类的自身特有的方法
Student.prototype.sayGoodbye = function() {
console.log('Goodbye!');
}
// 创建子类实例
let student = new Student('Alice', 18, 'A');
student.sayHello(); // "Hello, my name is Alice"
console.log(student.age); // 18
student.sayGoodbye(); // "Goodbye!"
上述代码中,我们定义了一个Person父类和一个Student子类,并将Student.prototype指向了一个Person实例,实现了原型继承;同时通过使用call方法,调用Person构造函数,实现了构造函数继承。在创建子类实例的时候,可以通过子类实例访问到父类的原型方法和构造函数中的属性,也可以访问到子类自身添加的方法。
4. JavaScript中的this
this是JavaScript中一个很重要的关键字,它指向函数运行时所在的环境对象。在全局环境下,this指向window对象;在函数内部,this的值取决于函数的调用方式。
作为对象的方法调用:当函数作为对象的方法调用时,this指向这个对象。
let person = {
name: 'Alice',
sayHello: function() {
console.log('Hello, my name is ' + this.name);
}
};
person.sayHello(); // "Hello, my name is Alice"
作为普通函数调用:当函数作为普通函数调用时,this指向全局对象window。
function sayHello() {
console.log('Hello, my name is ' + this.name);
}
sayHello(); // 报错:Cannot read property 'name' of undefined
作为构造函数调用:当函数作为构造函数调用时,this指向新创建的对象。
function Person(name) {
this.name = name;
}
let person = new Person('Alice');
console.log(person.name); // "Alice"
使用apply或call方法调用:可以使用apply或call方法来改变函数的调用对象,从而改变this的指向。
let person1 = {
name: 'Alice',
};
let person2 = {
name: 'Bob',
};
function sayHello() {
console.log('Hello, my name is ' + this.name);
}
sayHello.call(person1); // "Hello, my name is Alice"
sayHello.call(person2); // "Hello, my name is Bob"
5. JavaScript中的继承方法总结
JavaScript中实现继承有三种方法:原型继承、构造函数继承和组合继承。不同的继承方法各有优缺点,具体使用时需要根据实际情况选择。