Я видел вопрос интервью сегодня, как следует спросить: создание экземпляра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уже не пустой объект)
Если у вас хватит терпения заглянуть сюда, то большое вам спасибо. Если в статье есть ошибки, поправьте меня~