ES6学习笔记_proto_属性、Object.setPrototypeOf()、Object.getPrototypeOf()

_proto_属性

JS语言的对象继承是通过原型链实现的

用途

_proto_用来读取或设置当前对象的原型对象(prototype)

// es5 的写法
const obj = {
  method: function() { ... }
};
obj.__proto__ = someOtherObj;

// es6 的写法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };

 实现

_proto_没有写入ES6正文,而是写在了附录,原因是_proto_前后的双下划线,说明他本质上是一个内部属性,不是一个正式的API.避免使用这个属性,

使用Object.setPrototypeOf(写操作)、Object.getProtypeOf(读操作)、Object.create(生成操作)代替

实现上,_proto_调用的是Object.prototype._proto_,具体实现如下

Object.defineProperty(Object.prototype, '__proto__', {
  get() {
    let _thisObj = Object(this);
    return Object.getPrototypeOf(_thisObj);
  },
  set(proto) {
    if (this === undefined || this === null) {
      throw new TypeError();
    }
    if (!isObject(this)) {
      return undefined;
    }
    if (!isObject(proto)) {
      return undefined;
    }
    let status = Reflect.setPrototypeOf(this, proto);
    if (!status) {
      throw new TypeError();
    }
  },
});

function isObject(value) {
  return Object(value) === value;
}

如果一个对象本身部署了_protp_属性,该属性的值就是对象的原型

Object.setPrototypeOf()

用途

Object.setPrototypeOf方法作用与_proto_相同,用来设置一个对象的原型对象(prototype),返回参数对象本身,是ES正式推荐的设置原型对象的方法

// 格式
Object.setPrototypeOf(object, prototype)
// 用法
const o = Object.setPrototypeOf({}, null);

 该方法等同于

function setPrototypeOf(obj, proto) {
  obj.__proto__ = proto;
  return obj;
}

举例 

let proto = {};
let obj = { x: 10 };
Object.setPrototypeOf(obj, proto);

proto.y = 20;
proto.z = 40;

obj.x // 10
obj.y // 20
obj.z // 40

上述代码将proto设置为对象obj的原型,所以从obj对象可以读取proto对象的属性

如果第一个参数不是对象,会自动转为对象,但是由于返回的还是第一个参数,这个操作不会产生任何效果

Object.setPrototypeOf(1, {}) === 1 // true
Object.setPrototypeOf('foo', {}) === 'foo' // true
Object.setPrototypeOf(true, {}) === true // true

由于null和undefined无法转为对象,第一个参数是null或undefined会报错

Object.getPrototypeOf()

用途

与Object.setPrototypeOf方法配套,用于读取一个对象的原型对象

Object.getProtypeOf(obj)

举例

function Rectangle() {
  // ...
}

const rec = new Rectangle();

Object.getPrototypeOf(rec) === Rectangle.prototype
// true

Object.setPrototypeOf(rec, Object.prototype);
Object.getPrototypeOf(rec) === Rectangle.prototype
// false

如果参数不是对象,会被自动转为对象。

// 等同于 Object.getPrototypeOf(Number(1))
Object.getPrototypeOf(1)
// Number {[[PrimitiveValue]]: 0}

// 等同于 Object.getPrototypeOf(String('foo'))
Object.getPrototypeOf('foo')
// String {length: 0, [[PrimitiveValue]]: ""}

// 等同于 Object.getPrototypeOf(Boolean(true))
Object.getPrototypeOf(true)
// Boolean {[[PrimitiveValue]]: false}

Object.getPrototypeOf(1) === Number.prototype // true
Object.getPrototypeOf('foo') === String.prototype // true
Object.getPrototypeOf(true) === Boolean.prototype // true

如果参数是undefinednull,它们无法转为对象,所以会报错。

Object.getPrototypeOf(null)
// TypeError: Cannot convert undefined or null to object

Object.getPrototypeOf(undefined)
// TypeError: Cannot convert undefined or null to object

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值