构造函数
- 主要用来初始化对象,即为对象成员变量赋初始值,总与new一起使用
- 构造函数存在内存浪费的情况
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);
new的作用(简版)
- 在内存中创建一个新的对象;
- 让this指向这个对象;
- 执行构造函数里的代码,给这个新的对象添加属性和方法;
- 返回这个新的对象。
原型prototype(显示原型)
- 作用:共享属性和方法
- 一般情况下,属性定义到构造函数里,方法定义到原型对象上
- 每个函数都有一个prototype属性,它默认指向一个Object空对象(原型对象)
- 原型对象中有一个属性constractor,它指向函数对象
对象原型__proto__(隐式原型)
- 指向构造函数的原型对象
- 之所以对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在
- __proto__意义在于为对象的查找机制提供一个方向,它属于一个非标准属性,在实际开发中不可以使用这个属性,它只是内部用来指向原型对象prototype
方法
- hasOwnProperty:判断属性是否存在构造函数中
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操作符:判断属性是否存在原型中
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
- 缺点:
- 包含引用类型值的原型属性会被所有实例共享
function Fn() {
this.test1 = function() {
console.log('test1()')
}
}
Fn.prototype.test2 = function() {
console.log('test2()')
}
var fn = new Fn();
fn.test1(); // test1()
fn.test2(); // test2()
console.log(fn.toString()); // [object Object]
fn.test3(); // fn.test3 is not a function