Object.create()分析及实现

更新日期: 2019-08-28阅读: 2.1k标签: object

Object.create()方法的作用:创建一个新对象,使用现有的对象来提供新创建的对象的__proto__(会返回一个新对象,带着指定的原型对象和属性)。


分析

默认情况下,js中对象的隐式原型__proto__指向其构造函数的显示原型prototype(这里的指向可以理解为属性与值的关系)

// 字面量创建对象
let obj1 = {}
obj1.__proto__ === Object.prototype; // true

// 内置构造函数创建对象。等价于new Object();
let obj2 = Object();
obj2.__proto__ === Object.prototype; // true

// 自定义构造函数创建实例对象
let Ctr = function(){};
let obj3 = new Ctr();
obj3.__proto__ === Ctr.prototype; // true


而经过Object.create()方法创建的对象可以指定其隐式原型为一个函数或者对象。

// 首先自定义一个构造函数并初始化一个实例对象。
function Base(){
    this.name = 'cuixiaodao'
}
Base.prototype.say = function (){
    console.log(`1:`,1);
}

var base = new Base();


// 创建新对象,指定其隐式原型为Base
var o1 = Object.create(Base);
o1.__proto__ === Base; // true

// 创建新对象,指定其隐式原型为base
var o2 = Object.create(base);
o2.__proto__ === base; // true

如图:


可以看出,Object.create方法的主要逻辑:创建一个对象,手动设置其隐式原型__proto__属性为传入的参数,让后将这个对象返回。

这样看实现过程就比较简单了。不过Object.create()方法还可以接受第二个参数,用来给新创建的对象添加可枚举属性,与Object.defineProperies方法第二个参数用法一样。


实现

这里我们本着弄清Object.create方法主要过程的原则,暂时不考虑第二个参数,对其主要功能做简单实现。

function _create(paramProto){
     var isObject = (typeof paramProto === 'object') || (typeof paramProto === 'function');
     var isUndefined = typeof paramProto === 'undefined';
     if (isUndefined || !isObject){
         throw new TypeError('Object prototype may only be an Object or null: ' + paramProto)
     }
     
     function F() { }
     F.prototype = paramProto;
     return new F();
}

上面最后三行代码,返回了F的实例对象,暂且称为f,那么也就是f.__proto__ === F.prototype,而F.prototype = paramProto,也就做到了f.__proto__ === paramProto。

也可以理解为下面的形式

function _create(paramProto) {
    return {
        __proto__: paramProto
    }
}


唠叨一下

Object.create()参数为对象和函数的区别

自定义一个构造函数并且实例化,分别用1Object.create()创建o1、o2另个对象。


function Base() {
    this.name = 'cuixiaodao'
}
Base.age = '18';
Base.prototype.say = function () {
    console.log(`1:`, 1);
}

let base = new Base();

let o1 = Object.create(Base);
var o2 = Object.create(base);
console.log(`o1:`,o1);
console.log(`o2:`,o2);


可以看到o1的隐式原型是Base,而o2隐式原型是baese

o1.__proto__ === Base; // true
o2.__proto__ === base; // true


o2可以访问到base上的name属性及base通过__proto__继承来的say方法。

o2.name;  // cuixiaodao
o2.say(); // 1

但是o1都访问不到

o1.name;  // 'Base'
o1.say;  // undefined
函数自带name属性,也就是函数名,所以这里返回了函数的名称Base。类似的还有length表示函数参数的个数,arguments代表函数接收的所有参数。

主要是因为原型链继承是通过对象的__proto__属性实现的:访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。虽然o1.__proto__ === Base,但由于say方法是定义在Base原型上的,通过o1.__proto__并访问不到,所以是undefined。直接在Base上面定义属性,o1是可以访问到的。

o1.age; // 18

Object.crete(null)和{}

Object.crete(null)会返回一个纯净的对象,不会继承内置Object的toString、valueof等方法。



链接: https://fly63.com/article/detial/5564

Js中Object对象的理解,Object常用的属性和方法有哪些?

在JavaScript中的所有对象都是继承Object对象而来的, 我们可以理解为Object是所有js对象通用的功能,讲解Object的prototype属性、Object.prototype属性和方法?Object.prototype.constructor属性等

Object.create()的使用总汇:创建对象,参数说明,兼容性的实现

JavaScript中Object.create()的含义和语法,使用它创建null原型的对象 ,创建一个普通的空对象,Object.create()第二个参数说明。

Javascript中的object相等

相等是JavaScript中起初最让人困惑的部分。==和===的比较、强制类型的顺序等等,都使得这个问题变得复杂。今天,我们会聚焦另一个方面:object相等是如何实现的。

js 中 Object.defineProperty 的用法

还能通过 Object.defineProperty() 方法,添加或修改对象的属性。更重要的是,除了目标对象 obj,属性名称 prop 外,方法能传入属性描述符 descriptor,以实现更复杂的性质。属性描述符是一个对象,有两种形式:一种是数据描述符,另一种是存取描述符。

理解js中Object的defineProperty()和defineProperties()

Object的defineProperty和defineProperties这两个方法在js中的重要性十分重要,主要功能就是用来定义或修改这些内部属性,与之相对应的getOwnPropertyDescriptor和getOwnPropertyDescriptors就是获取这行内部属性的描述。

js中的Object.defineProperty()和defineProperties()

Object.defineProperty()该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象,Object.defineProperties()该方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象

Object.keys方法

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。

Js中Object.freeze()方法

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。

Js Object.freeze和Object.seal

本文实例讲述了JS Object.preventExtensions(),Object.seal()与Object.freeze()用法。分享给大家供大家参考,Object.preventExtensions 只能阻止一个对象不能再添加新的自身属性,仍然可以为该对象的原型添加属性。

Object.assign实现浅拷贝的原理

什么是浅拷贝?浅拷贝就是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。浅拷贝Object.assign()是什么?主要将所有可枚举属性的值从一个或者多个数据源对象复制到目标对象,同时返回目标对象。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!