Разница между Object.create(), new Object() и {}

JavaScript

Эта статья была впервые опубликована вlijing0906.github.io

Объекты всегда используются в коде, обычно создаваемом самым прямым литеральным методом.var obj = {}, недавно закончилМетод наследования JSсталкиватьсяObject.create()Также можно создавать объекты и, как вариант, использоватьnew Object()Создание ключевых слов. Есть ли разница между этими тремя методами?

прямое буквальное создание

var objA = {};
objA.name = 'a';
objA.sayName = function() {
    console.log(`My name is ${this.name} !`);
}
// var objA = {
//     name: 'a',
//     sayName: function() {
//         console.log(`My name is ${this.name} !`);
//     }
// }
objA.sayName();
console.log(objA.__proto__ === Object.prototype); // true
console.log(objA instanceof Object); // true

создание нового ключевого слова

var objB = new Object();
// var objB = Object();
objB.name = 'b';
objB.sayName = function() {
    console.log(`My name is ${this.name} !`);
}
objB.sayName();
console.log(objB.__proto__ === Object.prototype); // true
console.log(objB instanceof Object); // true

существуетПроблема с указателем JSсредний классновый переплетвремя поговоритьnewФактически оператор выполняет следующие четыре шага:

var obj = new Object(); // 创建一个空对象
obj.__proto__ = Object.prototype; // obj的__proto__指向构造函数Object的prototype
var result = Object.call(obj); // 把构造函数Object的this指向obj,并执行构造函数Object把结果赋值给result
if (typeof(result) === 'object') {
    objB = result; // 构造函数Object的执行结果是引用类型,就把这个引用类型的对象返回给objB
} else {
    objB = obj; // 构造函数Object的执行结果是值类型,就返回obj这个空对象给objB
}

В этом сравнении, по сути, нет никакой разницы между созданием букв и созданием новых ключевых слов.__proto__оба указывают наObject.prototype, просто буквальное создание более эффективно, менее__proto__назначение указателя иthis.

Object.create()

Object.create()метод создает новый объект, используя существующий объект, чтобы предоставить только что созданному объекту__proto__.MDN

const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};
const me = Object.create(person); // me.__proto__ === person
me.name = "Matthew"; // name属性被设置在新对象me上,而不是现有对象person上
me.isHuman = true; // 继承的属性可以被重写
me.printIntroduction(); // My name is Matthew. Am I human? true

Object.create(proto[, propertiesObject])

  • protoОбязательный параметр — объект-прототип нового объекта, такой как новый объект в приведенном выше коде.meиз__proto__направлениеperson. Обратите внимание, что если этот параметрnull, новый объект полностью пуст и не имеет наследованияObject.prototypeлюбые свойства и методы наhasOwnProperty()、toString()Ждать.
var a = Object.create(null);
console.dir(a); // {}
console.log(a.__proto__); // undefined
console.log(a.__proto__ === Object.prototype); // false
console.log(a instanceof Object); // false 没有继承`Object.prototype`上的任何属性和方法,所以原型链上不会出现Object
  • propertiesObject— необязательный параметр, указывающий перечисляемые свойства, добавляемые к новому объекту (то есть его настраиваемые свойства и методы, доступныеhasOwnProperty()полученный, а не объект-прототип) дескриптор и соответствующее имя свойства.
var bb = Object.create(null, {
    a: {
        value: 2,
        writable: true,
        configurable: true
    }
});
console.dir(bb); // {a: 2}
console.log(bb.__proto__); // undefined
console.log(bb.__proto__ === Object.prototype); // false
console.log(bb instanceof Object); // false 没有继承`Object.prototype`上的任何属性和方法,所以原型链上不会出现Object

// ----------------------------------------------------------

var cc = Object.create({b: 1}, {
    a: {
        value: 3,
        writable: true,
        configurable: true
    }
});
console.log(cc); // {a: 3}
console.log(cc.hasOwnProperty('a'), cc.hasOwnProperty('b')); // true false 说明第二个参数设置的是新对象自身可枚举的属性
console.log(cc.__proto__); // {b: 1} 新对象cc的__proto__指向{b: 1}
console.log(cc.__proto__ === Object.protorype); // false
console.log(cc instanceof Object); // true cc是对象,原型链上肯定会出现Object

Object.create()Прототип созданного объекта указывает на переданный объект. за которым следует буквальное иnewСоздание ключевых слов имеет значение.

  • Реализуйте Object.create() самостоятельно
Object.mycreate = function(proto, properties) {
    function F() {};
    F.prototype = proto;
    if(properties) {
        Object.defineProperties(F, properties);
    }
    return new F();
}
var hh = Object.mycreate({a: 11}, {mm: {value: 10}});
console.dir(hh);

Суммировать

  • буквальное иnewОсновная клавиша созданаObjectнапример, прототип указывает наObject.prototype, наследует встроенный объектObject
  • Object.create(arg, pro)Прототип создаваемого объекта зависит отarg,argдляnull, новый объект является пустым объектом, не имеет прототипа и не наследует никакого объекта;argДля указанного объекта прототип нового объекта указывает на указанный объект и наследует указанный объект