JS Object.create()

🌙
手机阅读
本文目录结构

**Object.create()**方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)

The source for this interactive example is stored in a GitHub repository. If you’d like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

语法

  1. Object.create(proto[, propertiesObject])

参数

proto

新创建对象的原型对象。

propertiesObject

可选。如果没有指定为 undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。

返回值

一个新对象,带着指定的原型对象和属性。

例外

如果propertiesObject参数是 null 或非原始包装对象,则抛出一个 TypeError 异常。

例子

用 Object.create实现类式继承

下面的例子演示了如何使用Object.create()来实现类式继承。这是一个所有版本JavaScript都支持的单继承。

  1. // Shape - 父类(superclass)
  2. function Shape() {
  3. this.x = 0;
  4. this.y = 0;
  5. }
  6. // 父类的方法
  7. Shape.prototype.move = function(x, y) {
  8. this.x += x;
  9. this.y += y;
  10. console.info('Shape moved.');
  11. };
  12. // Rectangle - 子类(subclass)
  13. function Rectangle() {
  14. Shape.call(this); // call super constructor.
  15. }
  16. // 子类续承父类
  17. Rectangle.prototype = Object.create(Shape.prototype);
  18. Rectangle.prototype.constructor = Rectangle;
  19. var rect = new Rectangle();
  20. console.log('Is rect an instance of Rectangle?',
  21. rect instanceof Rectangle); // true
  22. console.log('Is rect an instance of Shape?',
  23. rect instanceof Shape); // true
  24. rect.move(1, 1); // Outputs, 'Shape moved.'

如果你希望能继承到多个对象,则可以使用混入的方式。

  1. function MyClass() {
  2. SuperClass.call(this);
  3. OtherSuperClass.call(this);
  4. }
  5. // 继承一个类
  6. MyClass.prototype = Object.create(SuperClass.prototype);
  7. // 混合其它
  8. Object.assign(MyClass.prototype, OtherSuperClass.prototype);
  9. // 重新指定constructor
  10. MyClass.prototype.constructor = MyClass;
  11. MyClass.prototype.myMethod = function() {
  12. // do a thing
  13. };

Object.assign 会把  OtherSuperClass原型上的函数拷贝到 MyClass原型上,使 MyClass 的所有实例都可用 OtherSuperClass 的方法。Object.assign 是在 ES2015 引入的,且可用 polyfilled。要支持旧浏览器的话,可用使用 jQuery.extend() 或者 _.assign()

使用 Object.createpropertyObject参数

  1. var o;
  2. // 创建一个原型为null的空对象
  3. o = Object.create(null);
  4. o = {};
  5. // 以字面量方式创建的空对象就相当于:
  6. o = Object.create(Object.prototype);
  7. o = Object.create(Object.prototype, {
  8. // foo会成为所创建对象的数据属性
  9. foo: {
  10.   writable:true,
  11.   configurable:true,
  12.   value: "hello"
  13.   },
  14. // bar会成为所创建对象的访问器属性
  15. bar: {
  16. configurable: false,
  17. get: function() { return 10 },
  18. set: function(value) {
  19.   console.log("Setting `o.bar` to", value);
  20.   }
  21. }
  22. });
  23. function Constructor(){}
  24. o = new Constructor();
  25. // 上面的一句就相当于:
  26. o = Object.create(Constructor.prototype);
  27. // 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码
  28. // 创建一个以另一个空对象为原型,且拥有一个属性p的对象
  29. o = Object.create({}, { p: { value: 42 } })
  30. // 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
  31. o.p = 24
  32. o.p
  33. //42
  34. o.q = 12
  35. for (var prop in o) {
  36. console.log(prop)
  37. }
  38. //"q"
  39. delete o.p
  40. //false
  41. //创建一个可写的,可枚举的,可配置的属性p
  42. o2 = Object.create({}, {
  43. p: {
  44. value: 42,
  45. writable: true,
  46. enumerable: true,
  47. configurable: true
  48. }
  49. });

Polyfill

这个 polyfill 涵盖了主要的应用场景,它创建一个已经选择了原型的新对象,但没有把第二个参数考虑在内。

请注意,尽管在 ES5 中 Object.create支持设置为[[Prototype]]null,但因为那些ECMAScript5以前版本限制,此 polyfill 无法支持该特性。

  1. if (typeof Object.create !== "function") {
  2. Object.create = function (proto, propertiesObject) {
  3. if (typeof proto !== 'object' && typeof proto !== 'function') {
  4. throw new TypeError('Object prototype may only be an Object: ' + proto);
  5. } else if (proto === null) {
  6. throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
  7. }
  8. if (typeof propertiesObject != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
  9. function F() {}
  10. F.prototype = proto;
  11. return new F();
  12. };
  13. }

规范

Specification Status Comment
ECMAScript 5.1 (ECMA-262) Object.create Standard Initial definition. Implemented in JavaScript 1.8.5.
ECMAScript 2015 (6th Edition, ECMA-262)Object.create Standard
ECMAScript Latest Draft (ECMA-262)Object.create Draft

相关链接

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了