资讯专栏INFORMATION COLUMN

JavaScript深入理解对象方法——Object.create()

melody_lql / 3162人阅读

摘要:语法新创建对象的原型对象。返回值在指定原型对象上添加新属性后的对象。例外如果参数不是或一个对象,则抛出一个异常。是在引入的,且可用。请注意,尽管在中支持设置为为,但因为那些以前版本限制,此无法支持该特性。

Object.create()

Object.create() 方法会使用指定的原型对象及其属性去创建一个新的对象。

语法
Object.create(proto[, propertiesObject])

proto
新创建对象的原型对象。

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

返回值

在指定原型对象上添加新属性后的对象。

例外

如果propertiesObject参数不是 null 或一个对象,则抛出一个 TypeError 异常。

例子 Object.create实现类式继承

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

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log("Is rect an instance of Rectangle?",
  rect instanceof Rectangle); // true
console.log("Is rect an instance of Shape?",
  rect instanceof Shape); // true
rect.move(1, 1); // Outputs, "Shape moved."

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

function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

// inherit one class
MyClass.prototype = Object.create(SuperClass.prototype);
// mixin another
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// re-assign constructor
MyClass.prototype.constructor = MyClass;

MyClass.prototype.myMethod = function() {
     // do a thing
};

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

使用 Object.createpropertyObject参数
var o;

// 创建一个原型为null的空对象
o = Object.create(null);


o = {};
// 以字面量方式创建的空对象就相当于:
o = Object.create(Object.prototype);


o = Object.create(Object.prototype, {
  // foo会成为所创建对象的数据属性
  foo: { 
    writable:true,
    configurable:true,
    value: "hello" 
  },
  // bar会成为所创建对象的访问器属性
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) {
      console.log("Setting `o.bar` to", value);
    }
  }
});


function Constructor(){}
o = new Constructor();
// 上面的一句就相当于:
o = Object.create(Constructor.prototype);
// 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码


// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
o = Object.create({}, { p: { value: 42 } })

// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
o.p = 24
o.p
//42

o.q = 12
for (var prop in o) {
   console.log(prop)
}
//"q"

delete o.p
//false

//创建一个可写的,可枚举的,可配置的属性p
o2 = Object.create({}, {
  p: {
    value: 42, 
    writable: true,
    enumerable: true,
    configurable: true 
  } 
});
Polyfill

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

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

if (typeof Object.create !== "function") {
    Object.create = function (proto, propertiesObject) {
        if (!(proto === null || typeof proto === "object" || typeof proto === "function")) {
            throw TypeError("Argument must be an object, or null");
        }
        var temp = new Object();
        temp.__proto__ = proto;
        if(typeof propertiesObject ==="object")
            Object.defineProperties(temp,propertiesObject);
        return temp;
    };
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89133.html

相关文章

  • 深入理解 js 之继承与原型链

    摘要:原型链与继承当谈到继承时,只有一种结构对象。如果对该图不怎么理解,不要着急,继续往下看基于原型链的继承对象是动态的属性包指其自己的属性。当使用操作符来作用这个函数时,它就可以被称为构造方法构造函数。 原型链与继承 当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为proto)指向它的原型对象(prototype)。该原型对象也...

    xingqiba 评论0 收藏0
  • 深入理解 JavaScript 原型继承

    摘要:下面轮到我们的主角原型继承登场了,它从另一个角度解决了重用的问题。原型继承的原理原型对象中的由两部分组成,普通属性的集合,和原型属性。原型继承的实现在上面的例子中,通过直接修改了属性值,实现了原型继承。使用原型继承,同样可以达到重用的目的。 继承的本质:重用 在探讨 JavaScript 的原型继承之前,先不妨想想为什么要继承? 考虑一个场景,如果我们有两个对象,它们一部分属性相同,另...

    UCloud 评论0 收藏0
  • 深入JavaScript(一)this & Prototype

    摘要:然而事实上并不是。函数本身也是一个对象,但是给这个对象添加属性并不能影响。一图胜千言作者给出的解决方案,没有麻烦的,没有虚伪的,没有混淆视线的,原型链连接不再赤裸裸。所以是这样的一个函数以为构造函数,为原型。 注意:本文章是个人《You Don’t Know JS》的读书笔记。在看backbone源码的时候看到这么一小段,看上去很小,其实忽略了也没有太大理解的问题。但是不知道为什么,我...

    The question 评论0 收藏0
  • JavaScript深入各种继承

    摘要:通常有这两种继承方式接口继承和实现继承。理解继承的工作是通过调用函数实现的,所以是寄生,将继承工作寄托给别人做,自己只是做增强工作。适用基于某个对象或某些信息来创建对象,而不考虑自定义类型和构造函数。 一、继承的概念 继承,是面向对象语言的一个重要概念。通常有这两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。 《JS高程》里提到:由于函数没有签名,...

    tomlingtm 评论0 收藏0
  • JavaScript深入理解对象方法——Object.entries()

    摘要:返回值给定对象自身可枚举属性的键值对数组。描述返回一个数组,其元素是与直接在上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。借助方法你可以很容易的将转换为你可以使用下面列出的简易。 Object.entries() Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时...

    dance 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<