es6 __proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()
__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()
JavaScript 语言的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。
__proto__属性
__proto__
属性(前后各两个下划线),用来读取或设置当前对象的prototype
对象。目前,所有浏览器(包括 IE11)都部署了这个属性。
// es6 的写法
const obj = {
method: function() { ... }
};
obj.__proto__ = someOtherObj;
// es5 的写法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };
该属性没有写入 ES6 的正文,而是写入了附录,原因是__proto__
前后的双下划线,说明它本质上是一个内部属性,而不是一个正式的对外的 API,只是由于浏览器广泛支持,才被加入了 ES6。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。因此,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的Object.setPrototypeOf()
(写操作)、Object.getPrototypeOf()
(读操作)、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;
}
如果一个对象本身部署了__proto__
属性,该属性的值就是对象的原型。
Object.getPrototypeOf({ __proto__: null })
// null
Object.setPrototypeOf()
Object.setPrototypeOf()
方法的作用与__proto__
相同,用来设置一个对象的prototype
对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
// 格式
Object.setPrototypeOf(object, prototype)
// 用法
const o = Object.setPrototypeOf({}, null);
该方法等同于下面的函数。
function (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
由于undefined
和null
无法转为对象,所以如果第一个参数是undefined
或null
,就会报错。
Object.setPrototypeOf(undefined, {})
// TypeError: Object.setPrototypeOf called on null or undefined
Object.setPrototypeOf(null, {})
// TypeError: Object.setPrototypeOf called on null or undefined
Object.getPrototypeOf()
该方法与Object.setPrototypeOf()
方法配套,用于读取一个对象的原型对象。
Object.getPrototypeOf(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
如果参数是undefined
或null
,它们无法转为对象,所以会报错。
Object.getPrototypeOf(null)
// TypeError: Cannot convert undefined or null to object
Object.getPrototypeOf(undefined)
// TypeError: Cannot convert undefined or null to object
es6 __proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()相关推荐
- es6 prototype 属性和__proto__属性
prototype 属性和__proto__属性 大多数浏览器的 ES5 实现之中,每一个对象都有__proto__属性,指向对应的构造函数的prototype属性.ES6 Class 作为构造函数的 ...
- Object.setPrototypeOf 与 Object.create() 的区别
在讲之前,我们先回顾下创建对象的几种方式,并且Object.new Object() 和 Object.create 的区别 ①:字面量方式创建对象 let person = {name: 'nick ...
- ECMA262 Edition5 Object,Object的属性和方法,Object.prototype的方法.
ES5,为Object添加了一批方法.了解这些方法,可以更好的理解属性描述符的应用. 所以还是很有必要读一读的.另外,这些方法用起来还是蛮给力的. 暂时对于ES5,就只放出这些吧,希望对大家有所帮助. ...
- js学习日记-new Object和Object.create到底干了啥
function Car () {this.color = "red"; } Car.prototype.sayHi=function(){console.log('你好') }v ...
- JS中关于构造函数、原型链、prototype、constructor、instanceof、__proto__属性
在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中引入 ...
- JS中函数的prototype属性和对象的__proto__属性
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...
- 【js基础】理清Object、Object.prototype、Function、Function.prototype
Object.prototype.toString.call(something) 上面这段代码一般被用来判断变量的类型,相信很多人都非常熟悉 今天coding时用到上面这段代码,突然想到 Objec ...
- ES6 计算属性名快速上手
1. ES6 计算属性名 ES6 中引入了计算属性名,英文是 computed property names,它可以在对象字面量中动态计算属性名称. 我们知道添加或修改对象的属性有两种常用的方法,一种 ...
- new Object()和Object.create()的区别
Object.create() 创建一个新对象,使用现有的对象来提供新创建的对象的__proto__. --MDN 语法 Object.create(proto, [propertiesObject] ...
最新文章
- Weblogic 10.3.6 for linux 集群安装
- qt5 + vs2015自定义控件错误:undefend interface
- 2019年的前端学习计划
- 【算法竞赛学习】二手车交易价格预测-Task1赛题理解
- Android 4.2 通知通过PendingIntent启动Activity失败的问题
- text/html与text/plain的区别
- java类无法调用值,Kotlin无法调用到Java中定义的interface类的问题记录
- mysql服务的注册,启动、停止、注销。 [delphi代码实现]
- CNN_原理以及pytorch多分类实践
- 黑苹果alc269声卡仿冒id_黑苹果定制声卡驱动(ALC892为例)
- Static Single Assignment(SSA)
- 计算机毕设存档袋子,关于做好2018届毕业论文(设计)材料整理存档的通知
- 配对交易之统计套利配对:介绍
- J2EE--自定义mvc增删改查
- Javascript实现全屏阅读和复制功能
- 基于eNSP的企业PON入云网络模拟
- 工业4.0 资产管理壳学习笔记(1)
- 华信mysql数据恢复_华信安卓手机数据恢复程序3.0
- Java静态编译技术:突破Java“冷启动”桎梏,实现启动性能“质”的飞跃
- 甲骨文高管薪酬去年骤降 董事长埃利森少拿35%
热门文章
- 《BackTrack 5 Cookbook中文版——渗透测试实用技巧荟萃》—第1章1.3节安装BackTrack到USB驱动器...
- 2015年关注的技术书籍
- Java虚拟机-逃逸分析(Escape Analysis)和栈上分配
- 地府后台管理系统30.已经在开发中,介绍下目前的工作进度和未来展望
- 基于生成对抗的知识图谱零样本关系学习 AAAI2020
- yum 安装boost
- Asia Yokohama Regional Contest 2018 K题 - Sixth Sense(思维加贪心加二分)
- DOM中对表格的操作
- BZOJ1041:[HAOI2008]圆上的整点(数论)
- CentOS 6.8 安装JDK8