JavaScript系列(七):原型对象

对象原型

JavaScript中的每个对象都有一个原型对象,对象以其原型为模板、从原型中继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性。就这样一层一层、以此类推,这种关系就被称为了原型链。

准确地说,这些属性和方法定义在Object的构造器函数(constructor functions)之上的prototype属性上,而非对象实例本身。

理解原型对象

先定义一个对象模型:

function Person(id, name, age) {
    this.id = id;
    // ...
}

创建一个对象并打印:

let person1 = Person(00001, "曾小晨", 102);

在 JavaScript 控制台输入 person.,就会看到,浏览器将根据这个对象的可用的成员名称进行自动补全:

在这个列表中,你可以看到定义在 person1 的原型对象、即 Person() 构造器中的成员—— nameageid。同时也有一些其他成员—— watch、valueOf 等等——这些成员定义在 Person() 构造器的原型对象、即 Object 之上。下图展示了原型链的运作机制:

如果调用了person1的方法,浏览器会做以下事情:

  • 浏览器首先检查,person1 对象是否具有可用的 valueOf() 方法。
  • 如果没有,则浏览器检查 person1 对象的原型对象(即 Person)是否具有可用的 valueof() 方法。
  • 如果也没有,则浏览器检查 Person() 构造器的原型对象(即 Object)是否具有可用的 valueOf() 方法。Object 具有这个方法,于是该方法被调用

这些继承的属性和成员都有一个前提条件:在原型对象中,把可以继承的属性和方法用Object.prototype.* 公开。

使用create()实现原型链

Object.create([object]):如果无参,创建一个对象;如果有参,创建一个基于object的对象,object将是新建后的对象的原型对象。

注意

prototype不是原型对象本身,它只是指向了一个对象,真正的原型对象本身是用__proto__访问:

function Person(id, name, age) {
    this.id = id;
    this.name = name;
    this.age = age;
}
Person.prototype.ddd = "A";

let person = new Person(00001, "曾小晨", 102);
let person1 = Object.create(person);
console.log(person1.prototype) // prototype 在缺省的情况下是undefined
console.log(person1.__proto__ === person) // true

使用call()实现原型链

function Person(id, name, age) {
    this.id = id;
    this.name = name;
    this.age = age;
}
function User (email, id, name, age) {
    this.email = email;
    Person.call(this, id, name, age)
}
let user = new User("704729872@qq.com", 1, "曾小晨", 99);
console.log(user) // 拥有了Person的所有属性

call可以调用构造函数匿名函数具名函数并指定this

call() 的资料

Last modification:March 4th, 2018 at 11:16 pm
If you think my article is useful to you, please feel free to appreciate

One comment

  1. 林洋洋

    去旅行了啊?留下足迹。OωO

Leave a Comment