构造函数和原型

126 阅读2分钟

构造函数

  • 主要用来初始化对象,即为对象成员变量赋初始值,总与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();

截屏2021-09-27 下午7.46.56.png

原型链

  • 作用:查找对象的方法(属性)
    • 先在自身属性上查找
    • 如果没有,则沿着__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

截屏2021-09-27 下午7.56.09.png

截屏2021-09-27 下午8.05.51.png