阅读 148

Js基础---Object.create/{}/new Object

Object.create

基本用法

Object.create()方法是ECMAScript5中新增的,用来规范化原型式继承的。

object.create(proto, propertiesObject)
复制代码

object.create() 是使用指定的原型proto对象及其属性propertiesObject去创建一个新的对象。

这个方法接收两个参数,一个是用作新对象原型的对象,另一个是新对象定义额外属性的(可选)对象。

  • proto 是必填参数,就是新创建出来的对象的原型 (新对象的 __proto__属性指向的对象),值得注意的是当proto为null的时候创建的新对象完全是一个空对象,没有原型,也就是没有继承Object.prototype上的方法。(如hasOwnProperty() toString() 等)

  • propertiesObject是可选参数,作用就是给新对象添加新属性以及描述器(图1),需要注意的是新添加的属性是新对象自身具有的属性也就是通过hasOwnProperty() 方法可以获取到的属性,而不是添加在原型对象里。

        var person = {
            name: "Nicholas",
            friends: ["John", "Jane"]  // 引用类型值属性共享
        }
        var onePerson = Object.create(person);  // onePerson继承person对象
        onePerson.name = "Greg";
        onePerson.friends.push("Mike");
        console.log(onePerson.name);  // Greg
        console.log(onePerson.friends);  // ["John", "Jane", "Mike"]
        var anotherPerson = Object.create(person);
        console.log(anotherPerson.name);  // Nicholas
        anotherPerson.friends.push("Jacky");
        console.log(anotherPerson.friends);  // ["John", "Jane", "Mike", "Jacky"]
        // 第二个参数对象格式与Object.defineProperties()方法的第二个参数格式相同
        var theOtherPerson = Object.create(person,
            {
                name: {
                    configurable: false,  // 不可修改
                    value: "Greg"
                }
            });
        console.log(theOtherPerson.name);  // Greg
        theOtherPerson.name = "Bob";  // 失效
        console.log(theOtherPerson.name);  // Greg
    复制代码

手写Object.create

具体三个步骤就是:

  1. 创建一个对象

  2. 继承指定父对象

  3. 为新对象扩展新属性

        Object.myCreate = function (proto, properties) {
            var F = function () { };
            F.prototype = proto;
            if (properties) {
                Object.defineProperties(F, properties);
            }
            return new F();
        }
        Object.myCreate({}, { a: { value: 1 } });     // {a: 1}
    复制代码

new Object

     new 运算符是创建一个自定义对象或者具有构造函数的内置对象的实例。

     使用new运算符会创建一个新的对象,它继承自构造函数的prototype,也就是说它的__proto__属性会指向构造函数的prototype,new Object() 也就是具有构造函数的内置Object的实例,新创建的对象的__proto__属性会指向Object的prototype。

手写new

        function newObj() {
            var con = [].shift.call(arguments, 1);
            var obj = Object.create(con.prototype);
            var result = con.apply(obj, arguments);
            return result instanceof Object && result ? result : obj;
        }
复制代码

总结

Object.cerate() 必须接收一个对象参数,创建的新对象的原型指向接收的参数对象,new Object() 创建的新对象的原型指向的是Object.prototype。(表述有点啰嗦,简洁点说就是前者继承指定对象, 后者继承内置对象Object)

可以通过Object.create(null) 创建一个干净的对象,也就是没有原型,而 new Object() 创建的对象是 Object的实例,原型永远指向Object.prototype。

参考

object.create与new object的区别,手写一个object.create

JS深入理解—详解Object.create(null)、new实现过程以及手写实现

Object.create()、new Object()和{}的区别

文章分类
前端
文章标签