Object.create() ╰+哭是因爲堅強的太久メ 2023-06-13 06:05 24阅读 0赞 Object.create(proto, [propertiesObject]) //方法创建一个新对象,使用现有的对象来提供新创建的对象的proto。 参数: * proto : 必须。表示新建对象的原型对象,即该参数会被赋值到目标对象(即新对象,或说是最后返回的对象)的原型上。该参数可以是null, 对象, 函数的prototype属性 (创建空的对象时需传null , 否则会抛出TypeError异常)。 * propertiesObject : 可选。 添加到新创建对象的可枚举属性(即其自身的属性,而不是原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。 返回值: **在指定原型对象上添加新属性后的对象。** **Object.create()与new Object()** 在js中,创建对象有三种方式 * \{\} // 对象字面量 * new Object() * Object.create() 1和2的区别很小,1不能传参,2可以传参。 new Object() 和Object.create() 区别就比较大了 **new关键字** new 关键字做了几件事 (1)创建一个新对象 (2)将新对象的原型指向构造函数的原型 (3)执行构造函数,绑定this (4)返回这个对象 比如创建一个Car对象,伪代码 // new Car() var obj = new Object() obj._proto_ = Car.prototype // 执行构造函数, 绑定this Car.call(obj) 我们注意到比较关键的地方是,它调用了Car对象的构造函数,并通过call将obj的this绑定到了Car对象上,这一步操作将Car对象上的属性,继承到了obj上。 **Object.create()** 它同样是创建一个新对象,将新对象的原型关联到构造函数上 var f = function() { } f.prototype = Car return new f() 比较鲜明的地方是在继承的时候 子类去继承父类的原型方法的时候,很多人会这样写 // 父类是People,子类是Male Male.prototype = new People() new确实能够继承,但是调用了父类的构造函数,把父类的属性也给继承到了原型上,但是我们仅仅只是想要父类的原型方法,所以这样写是存在副作用的 正确的写法应该是 Male.prototype = Object.create(People.prototype) 这种方式,不会调用父类的构造函数,而是生成新对象,将新对象与父类原型关联,然后new这个新对象返回,将 new 构造函数的方式转变了成 new 新对象的方式,这样就更加纯净,干脆。 (1)创建对象的方式不同 new Object() 通过构造函数来创建对象, 添加的属性是在**自身实例**下。 Object.create() es6创建对象的另一种方式,可以理解为继承一个对象, 添加的属性是在**原型**下。 // new Object() 方式创建 var a = { rep : 'apple' } var b = new Object(a) console.log(b) // {rep: "apple"} console.log(b.__proto__) // {} console.log(b.rep) // {rep: "apple"} // Object.create() 方式创建 var a = { rep: 'apple' } var b = Object.create(a) console.log(b) // {} console.log(b.__proto__) // {rep: "apple"} console.log(b.rep) // {rep: "apple"} Object.create()方法创建的对象时,属性是在原型下面的,也可以直接访问 b.rep // \{rep: “apple”\} , 此时这个值不是吧b自身的,是它通过原型链proto来访问到b的值。 (2)创建对象属性的性质不同 // 创建一个以另一个空对象为原型,且拥有一个属性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 Object.create() 用第二个参数来创建非空对象的属性描述符默认是为false的,而构造函数或字面量方法创建的对象属性的描述符默认为true。看下图解析: ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDQzODU5_size_16_color_FFFFFF_t_70] (3)创建空对象时不同 ![在这里插入图片描述][20191114124629324.png] 当用构造函数或对象字面量方法创建空对象时,对象时有原型属性的,即有\_proto\_; 当用Object.create()方法创建空对象时,对象是没有原型属性的。 (4)`__proto__` 属性 JavaScript 的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。 `__proto__`属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前只有浏览器环境必须部署有这个属性,其他运行环境不一定要部署,因此不建议使用这个属性,而是使用下面这些来 Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替。 **Object.create()** 描述:该方法创建一个新对象,使用现有的对象来提供新创建的对象的`__proto__`; 格式:Object.create(proto\[, propertiesObject\]) 用法:如果用传统的方法要给一个对象的原型上添加属性和方法,是通过 `__propt__` 实现的 var proto = { y: 20, z: 40, showNum(){ } }; var o = Object.create(proto); ![在这里插入图片描述][20191114124839830.png] 如果是不用Object,create()方法,我们是如何给对象原型添加属性和方法的? \------ 通过构造函数或者类,例如: //创建一个构造函数或者类 var People = function(){ } People.prototype.y = 20 People.prototype.showNum = function() { } //通过构造函数创建实例 var p = new People(); console.log(p.__proto__ === People.prototype) // true ![在这里插入图片描述][20191114124913963.png] **Object.setPrototypeOf** 描述:该方法的作用与 **proto** 相同,用来设置一个对象的 prototype 对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。 格式:Object.setPrototypeOf(object, prototype) 用法: var proto = { y: 20, z: 40 }; var o = { x: 10 }; Object.setPrototypeOf(o, proto); ![在这里插入图片描述][20191114124958821.png] 输出结果中看出,添加的方法是在原型上的。就类似于 obj.__proto__ = proto; **Object.getPrototypeOf()** 描述:用于读取一个对象的原型对象; 格式:Object.getPrototypeOf(obj); 用法: Object.getPrototypeOf('foo') === String.prototype // true Object.getPrototypeOf(true) === Boolean.prototype // true **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.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 } }); 参考:[Object.create()][Object.create] [Object.create()方法][Object.create 1] [js 中 new 与 Object.create()的区别][js _ new _ Object.create] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDQzODU5_size_16_color_FFFFFF_t_70]: https://img-blog.csdnimg.cn/20191114124607138.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMDQzODU5,size_16,color_FFFFFF,t_70 [20191114124629324.png]: https://img-blog.csdnimg.cn/20191114124629324.png [20191114124839830.png]: https://img-blog.csdnimg.cn/20191114124839830.png [20191114124913963.png]: https://img-blog.csdnimg.cn/20191114124913963.png [20191114124958821.png]: https://img-blog.csdnimg.cn/20191114124958821.png [Object.create]: https://www.jianshu.com/p/28d85bebe599 [Object.create 1]: https://blog.csdn.net/devincob/article/details/82021926 [js _ new _ Object.create]: http://www.fly63.com/article/detial/4917
还没有评论,来说两句吧...