Некоторое время назад мой друг проходил собеседование, и интервьюер задал ему вопрос: напишите метод js для реализацииnewоператор. В глубине сердца моего друга скакали 10 000 травяных и грязных лошадей...newиспользовались для создания объектов-экземпляров, вы можетеnewМы действительно мало обращаем внимания на то, что происходит за кулисами.
newза операцией
Новый оператор создает экземпляр пользовательского типа объекта или экземпляр встроенного объекта с конструктором. Новое ключевое слово делает следующее:
1. Создайте пустой простой объект JavaScript (например, {});
2. Связать объект (то есть установить конструктор объекта) с другим объектом;
3. Используйте объект, вновь созданный на шаге 1, в качестве контекста этого;
4. Если функция не возвращает объект, верните это.
ВышеMDNИсходный текст, благодаря приведенному выше описанию, мы можем ясно понять простойnewЧто происходит за оператором. Теперь давайте посмотрим на следующий код
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
Car.prototype={
getMake: function() {
return this.make
}
}
var car = new Car('Eagle', 'Talon TSi', 1993)
Давайте сломаем этоvar car = new Car('Eagle', 'Talon TSi', 1993)эта строка кода
Шаг 1: Создайте простой пустой объект
var obj = {}
Шаг 2: Связать объект с другим объектом (цепочка прототипов)
// 设置原型链
obj.__proto__ = Car.prototype
Шаг 3: Используйте вновь созданный объект на шаге 1 какthisконтекст
// this指向obj对象
Car.apply(obj, ['Eagle', 'Talon TSi', 1993])
Шаг 4: Если функция не возвращает объект, верните этот
// 因为 Car() 没有返回值,所以返回obj
var car = obj
car.getMake() // 'Eagle'
Следует отметить, что еслиCar()имеютreturnзатем вернутьсяreturnзначение
var rtnObj = {}
function Car(make, model, year) {
// todo
// ...
//返回一个对象
return rtnObj
}
var car = new Car('Eagle', 'Talon TSi', 1993)
console.log(car === rtnObj) // true
инкапсулировать метод
Теперь мы инкапсулируем вышеуказанные шаги в метод создания объекта.
function objectFactory(){
var obj = {};
//取得该方法的第一个参数(并删除第一个参数),该参数是构造函数
var Constructor = [].shift.apply(arguments);
//将新对象的内部属性__proto__指向构造函数的原型,这样新对象就可以访问原型中的属性和方法
obj.__proto__ = Constructor.prototype;
//取得构造函数的返回值
var ret = Constructor.apply(obj, arguments);
//如果返回值是一个对象就返回该对象,否则返回构造函数的一个实例对象
return typeof ret === "object" ? ret : obj;
}
class
Новые ключевые слова добавлены в es6class, если вышеfunctionзаменитьclassКаков будет результат? На самом деле результат тот же.
class Car {
constructor(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
getMake() {
return this.make
}
}
var car = objectFactory(Car, 'Eagle', 'Talon TSi', 1993)
car.getMake() // 'Eagle'
резюме
Теперь вы понимаете, что в jsnewКакую операцию выполняет экземпляр? Казалось бы, простой оператор за ним не так просто реализовать, и его нужно тщательно попробовать, чтобы понять смысл.