Мысли из вопроса интервью: Понимание нового оператора

JavaScript

Я видел вопрос интервью сегодня, как следует спросить: создание экземпляраPersonв процессе,Personчто вернуть (илиpравен чему)?

function Person(name) {
    this.name = name
    return name;
}
let p = new Person('Tom');

Честно говоря, первая реакция, которую я подумал, была'Tom', я не понимал, что был неправ, пока не закинул код в консоль и не вывел его. господи,newОператор был проигнорирован? ? ? отложить в сторонуnewсуществует, мы модифицируем код

function Person(name) {
    this.name = name
    return name;
}
let p = Person('Tom');
console.log(p);

Очевидно, что выходной результат'Tom', но естьnewсуществует? Далее делаем свайп. Сначала я идуMDNИскал определение нового на

Новый оператор создает экземпляр пользовательского типа объекта или экземпляр встроенного объекта с конструктором.

эммм, довольно неясно.

Тогда давайте попробуем написать несколько каштанов и посмотрим на результат.

function Person1(name) {
  this.name = name;
  // 没有返回值
}

function Person2(name) {
  this.name = name;
  return name;
  // 返回非对象
}

function Person3(name) {
  this.name = name;
  return { a: 1 };
  // 返回对象
}

function Person4(name) {
  this.name = name;
  return null;
  // 返回null
}

var p1 = new Person1("aa");
var p2 = new Person2("bb");
var p3 = new Person3("cc");
var p4 = new Person4("dd");

console.log(p1); // Person1 {name: "aa"}
console.log(p2); // Person2 {name: "bb"}
console.log(p3); // {a: 1}
console.log(p4); // Person4 {name: "dd"}

По приведенным выше каштанам можно сделать вывод, что при использовании new для создания объекта || вызов конструктора, если функция не возвращает значение || возвращаемое значение не является объектом, то возвращаемый объект является объектом после экземпляр конструктора (примечание:return null, который также возвращает объект после экземпляра конструктора вместоnull); если функция возвращает объект, то вернуть этот объект

Давайте посмотримMDNОбъяснение документа, в конце концов, просто смотреть на эти демо неубедительно.

Давайте разбираться вместеnewКакую работу вы сделали? просто возьми этоdemoанализировать

function Person(name) {
  this.name = name;
  return {a: 1}
}
var p = new Person('fe')

при звонкеnew Person(...), выполняются следующие шаги:

  • Первый наследуется отPerson.prototypeБудет создан новый объект
  • Использовать параметры'fe'вызвать конструкторPerson, и воляthisпривязать к вновь созданному объекту
  • Зависит отPersonВозвращаемый объектnewРезультат выражения =>PersonВозвращаемый объект{a: 1}такnewРезультат выражения{a:1}; еслиPersonВозвращаемого значения нет (как правило, конструктор не возвращает значение), тогда используйте объект, созданный на шаге 1, то есть ==> унаследованный отPerson.prototypeновый объект

Вроде по документу можно немного понять, если симуляция реализованаnewОператоры могут быть лучше понятыnewНиже приведена фиктивная реализация нового исходного кода:Углубленная новая реализация моделирования JavaScript

function objectFactory() {
  var obj = new Object(),
  cons = [].shift.call(arguments)
  obj.__proto__ = cons.prototype
  var ret = cons.apply(obj, arguments)
  return typeof ret === 'object' ? ret|| obj : obj
}
function Person(name) {
  this.name = name;
  return {a: 1}
}
var p = objectFactory(Person, 'fe')

Конечно, изучение чужого кода не может быть просто скопировано, по крайней мере, вы должны понимать код. использовать

  • Первый — создать объект
  • consэто вызовobjectFactoryпервый параметр метода, конструктор, потому чтоshiftизменит исходный массив, поэтому измененныйargumentТо есть параметры для вызова конструктора (здесь дополнительно: arguments — массивоподобный объект, соответствующий переданным в функцию параметрам.)
  • Будуobjпрототип указывает на конструктор, так что obj может получить доступ к свойствам прототипа конструктора
  • конструкторconsизthisнаправлениеobj,такobjМожет получить доступ к свойствам в конструкторе
  • Определить, является ли возвращаемое значение объектом, и если это объект, вернуть его (разумеется, здесь нужно разобратьсяreturn nullособый случай, из-за исторических проблемtypeof null === 'object'); вернуть, если не объектobj(Примечание: здесьobjуже не пустой объект)

Если у вас хватит терпения заглянуть сюда, то большое вам спасибо. Если в статье есть ошибки, поправьте меня~