Skip to content

Prototype

属性 [[Prototype]] 是内部的而且是隐藏的,访问它的方式为

  1. __proto__
  2. Object.getPrototypeOf/Object.setPrototypeOf

__proto__ 并不是 [[Prototype]] 的引用,而是 [[Prototype]] 的 getter/setter

__proto__ 的存在是历史的原因,规范要求所有浏览器都支持 __proto__

__proto__ 只能是 null 和 对象

this

this 不受原型的影响。谁调用的,this 就是谁。

Writing doesn’t use prototype

子类可以通过 继承 访问夫类的 getter

子类通过 夫类 setter 设置的内容,只会在自身生效,并不会影响父类。

js
const a = {
  _name: "啊?",
  get name() {
    return this._name;
  },

  set name(val) {
    return (this._name = val);
  },
};

const b = {
  __proto__: a,
};

console.log(b.name); //啊?

b.name = "张三";

console.log(b.name); //张三

console.log(a.name); // a 依旧是 啊?

现代 api

  • Object.getPrototypeOf(obj) —— 返回 [[Prototype]]
  • Object.setPrototypeOf(obj, proto) —— 设置[[Prototype]]

Object.create(proto[, descriptors])
创建一个空对象,并设置 [[Prototype]] 和 属性描述。

js
let animal = {
  eats: true,
};

let rabbit = Object.create(animal, {
  name: { value: "白" },
  age: { value: 1 },
});

rabbit.__proto__ === animal; // true

也可用这些 api 来 copy

js
let clone = Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
);

历史

构造函数的 "prototype" 属性自古以来就起作用。

2012 年,Object.create 出现在标准中。但是无法获取 [[Prototype]],于是才有了 __proto__

2015 年,Object.setPrototypeOf 和 Object.getPrototypeOf 被加入到标准中

"Very plain"

[[Prototype]] 指向 null ,彻底空白的对象