javascript中Object.create

121 篇文章 3 订阅

参考:https://www.cnblogs.com/lyy-2016/p/8916350.html

例子1:

const log = console.log;

function Parent() {
    this.pname = "parent name";
}

function Old() {
    this.oname = "old name";
}
Old.prototype = new Parent();
Old.prototype.runOld = function() {
    log("Old runOld");
}

Old.prototype.constructor = Old;

function Animal() {
    this.aname = "animal name";
}
Animal.prototype = new Old();
Animal.prototype.runAnim = function() {
    log("Animal runAnim");
}
Animal.prototype.constructor = Animal;

let o = new Old();
let animal = new Animal();
let a = Object.create(Animal.prototype);
log("o = ", o);
log("o.getPrototypeOf(o) = ", Object.getPrototypeOf(o));
for (let k in o) {
    log("o k = ", k, ", ", o[k]);
}
log("animal = ", animal);

log("a = ", a);
log("a.prototype = ", a.prototype);
log("Object.getPrototypeOf(a) = ", Object.getPrototypeOf(a));
log("Object.getPrototypeOf(animal) = ", Object.getPrototypeOf(animal));
animal.aname = "cccc";
animal.pname = "xxxx";
//没有打印出this.aname
for (let k in a) {
    log("a k = ", k, ", ", a[k]);
}

结果:

$ node for.js
o =  Old { oname: 'old name' }
o.getPrototypeOf(o) =  Old {
  pname: 'parent name',
  runOld: [Function],
  constructor: [Function: Old]
}
o k =  oname ,  old name
o k =  pname ,  parent name
o k =  runOld ,  [Function]
o k =  constructor ,  [Function: Old]
animal =  Animal { aname: 'animal name' }
a =  Animal {}
a.prototype =  undefined
Object.getPrototypeOf(a) =  Animal {
  oname: 'old name',
  runAnim: [Function],
  constructor: [Function: Animal]
}
Object.getPrototypeOf(animal) =  Animal {
  oname: 'old name',
  runAnim: [Function],
  constructor: [Function: Animal]
}
a k =  oname ,  old name
a k =  runAnim ,  [Function]
a k =  constructor ,  [Function: Animal]
a k =  pname ,  parent name
a k =  runOld ,  [Function]

 

例子2:

const log = console.log;

function cat(name) {
    this.name = name ? name : "defaultname";
}

cat.skey = "test-skey";
cat.prototype.pinfo = function() {
    return `name = ${this.name}`;
}

let b = new cat("bbb");
let c = new cat("ccc");
let e = Object.create(cat.prototype);
log("b = ", b);
log("c = ", c);
log("e = ", e);
log("Object.keys(c) = ", Object.keys(c))
log("Object.keys(e) = ", Object.keys(e))
log("c.pinfo() = ", c.pinfo());
log("e.pinfo() = ", e.pinfo());
e.name = "new-name";
log("c.pinfo() = ", c.pinfo());
log("e.pinfo() = ", e.pinfo());

log("c.skey = ", c.skey);
log("e.skey = ", e.skey);

结果:

$ node for.js
b =  cat { name: 'bbb' }
c =  cat { name: 'ccc' }
e =  cat {}
Object.keys(c) =  [ 'name' ]
Object.keys(e) =  []
e  k= pinfo , v =  [Function]
e  k= constructor , v =  [Function: cat] { skey: 'test-skey' }
c.pinfo() =  name = ccc
e.pinfo() =  name = undefined
c.pinfo() =  name = ccc
e.pinfo() =  name = new-name
c.skey =  undefined
e.skey =  undefined

Object.create()方法是ECMAScript 5中新增的方法,这个方法用于创建一个新对象。被创建的对象继承另一个对象的原型,在创建新对象时可以指定一些属性。

语法: Object.create(proto[,propertiesObject]) 
proto: 对象,要继承的原型 
propertiesObject: 对象,可选参数,为新创建的对象指定属性对象。该属性对象可能包含以下值:

属性说明
configurable表示新创建的对象是否是可配置的,即对象的属性是否可以被删除或修改,默认false
enumerable对象属性是否可枚举的,即是否可以枚举,默认false
writable对象是否可写,是否或以为对象添加新属性,默认false
get对象getter函数,默认undefined
set对象setter函数,默认undefined

注意,使用Object.create()方法创建对象时,如果不是继承一个原有的对象,而是创建一个全新的对象,就要把proto设置为null。

来看一个简单的应用

const log = console.log;

function Old() {
    this.origin = "原型";
    log("Old::constructor");
}

// 基类
function Site() {
    Old.call(this);
    this.name = 'Site';
    this.domain = 'domain';
    log("Site::constructor");
}

Site.prototype = Object.create(Old.prototype);
Site.prototype.create = function(name, domain) {
    this.name = name;
    this.domain = domain;
};

// 子类
function Itbilu() {
    Site.call(this); //调用基类的构造函数
}

// 继承父类
Itbilu.prototype = Object.create(Site.prototype);
Itbilu.prototype.constructor = Itbilu;
// 创建类实例
var itbilu = new Itbilu();
log("itbilu = ", itbilu);
log("itbilu instanceof Site = ", itbilu instanceof Site); // true
log("itbilu instanceof Itbilu = ", itbilu instanceof Itbilu); // true

itbilu.create('IT笔录', 'itbilu.com');
log("itbilu.name = ", itbilu.name); // 'IT笔录'
log("itbilu.domain = ", itbilu.domain); // 'itbilu.com'

结果:

$ node for.js
Old::constructor
Site::constructor
itbilu =  Itbilu { origin: '原型', name: 'Site', domain: 'domain' }
itbilu instanceof Site =  true
itbilu instanceof Itbilu =  true
itbilu.name =  IT笔录
itbilu.domain =  itbilu.com

参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create

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

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

const me = Object.create(person);

me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"

结果:

> "My name is Matthew. Am I human? true"

语法

Object.create(proto,[propertiesObject])

参数

proto

新创建对象的原型对象。

propertiesObject

可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。如果该参数被指定且不为 undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。

返回值

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

例外

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

 

例子

用 Object.create实现类式继承

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

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

// 父类的方法
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.
}

// 子类续承父类
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);
}

// 继承一个类
MyClass.prototype = Object.create(SuperClass.prototype);
// 混合其它
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// 重新指定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.create 的 propertyObject参数

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 (typeof proto !== 'object' && typeof proto !== 'function') {
            throw new TypeError('Object prototype may only be an Object: ' + proto);
        } else if (proto === null) {
            throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
        }

        if (typeof propertiesObject !== 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");

        function F() {}
        F.prototype = proto;

        return new F();
    };
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值