构造函数
- 主要用来初始化对象,即为对象成员变量赋初始值,总与new一起使用
构造函数存在内存浪费的情况 ```javascript function Person(name, age) { this.name = name; this.age = age;
this.sayName = function() {
alert(this.name);
} }
const person1 = new Person(‘小明’, 12); const person1 = new Person(‘小红’, 12);
<a name="u72uK"></a>
### 问题
创建了对象,未使用new关键字实例化
```javascript
function Person(name, age) {
this.name = name;
this.age = age;
}
const person1 = Person('小明', 12);
console.log(person1) // undefined
console.log(window.name) // 小明
console.log(window.age) // 12
// 使用安全模式创建对象
function Person(name, age) {
// 判断执行过程中this是否是当前这个对象
// 如果是说明是通过new创建的
if (this instanceof Person) {
this.name = name;
this.age = age;
// 否则重新创建这个对象
} else {
return new Person(name, age);
}
}
new的作用
原型prototype(显示原型)
- 作用:共享属性和方法
- 一般情况下,属性定义到构造函数里,方法定义到原型对象上
- 每个函数都有一个prototype属性,它默认指向一个Object空对象(原型对象)
-
对象原型proto(隐式原型)
指向构造函数的原型对象
- 之所以对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有proto原型的存在
proto意义在于为对象的查找机制提供一个方向,它属于一个非标准属性,在实际开发中不可以使用这个属性,它只是内部用来指向原型对象prototype
方法
hasOwnProperty:判断属性是否存在构造函数中 ```javascript function Person() {} Person.prototype.name = ‘小明’; Person.prototype.age = 12;
const person1 = new Person();
console.log(person1.hasOwnProperty(‘name’)) // —> false,存在原型中 person1.name = ‘小红’; console.log(person1.hasOwnProperty(‘name’)) // —> true,存在实例中
- hasOwnProperty和in操作符:判断属性是否存在原型中
```javascript
function hasPrototypeProperty(obj, name) {
return !obj.hasOwnProperty(name) && (name in object);
}
构造函数、实例、原型对象的关系
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。 —《JavaScript高级程序设计》(第三版)
// 1、定义构造函数
function Fn() {};
// 2、创建实例对象
const fn = new Fn();
// fn.__proto__ === Fn.prototype
// 3、给构造函数原型添加方法
Fn.prototype.test = function() {};
// 4、通过实例调用原型方法
fn.test();
原型链
- 作用:查找对象的方法(属性)
- 先在自身属性上查找
- 如果没有,则沿着proto向上查找,直到找到为止
- 如果最后也没找到,返回undefined
- 缺点:
- 包含引用类型值的原型属性会被所有实例共享
this&prototype
- 通过this添加属性、方法和通过prototype添加属性、方法的区别:
通过this添加的属性、方法是在当前对象上添加的,然而js是一种基于原型prototype的语言,所以每创建一个对象时(当然在js中函数也是一种对象),它都有一个原型prototype用于指向其继承的属性。方法。这样通过prototype继承的方法并不是对象自身的,所以在使用这些方法时,需要通过prototype一级一级查找得到。这样通过this定义的属性或方法是该对象自身拥有的,所以每次通过类创建一个新对象时,this指向的属性和方法都会得到相应的创建。而通过prototype继承的属性或方法是每个对象通过prototype访问到,所以每次通过类创建一个新对象时这些属性和方法不会再次创建。