Обновление: Спасибо за вашу поддержку. Недавно я бросил сводку данных для всех, чтобы прочитать систему. В будущем будет больше контента и больше оптимизации.Нажмите здесь, чтобы просмотреть
------ Далее идет текст ------
определение
новый операторСоздает экземпляр пользовательского типа объекта или экземпляр встроенного объекта с помощью конструктора. - (из МДН)
взять каштан
function Car(color) {
this.color = color;
}
Car.prototype.start = function() {
console.log(this.color + " car start");
}
var car = new Car("black");
car.color; // 访问构造函数里的属性
// black
car.start(); // 访问原型里的属性
// black car start
Как можно заметитьnewСозданный экземпляр имеет следующие 2 характеристики
- 1. Доступ к свойствам в конструкторе
- 2. Доступ к свойствам в прототипе
будь осторожен
ES6 новыйsymbolтипа нельзя использоватьnew Symbol(),потому чтоsymbolявляются примитивными типами данных, каждый изSymbol()вернутьsymbolВсе значения уникальны.
Number("123"); // 123
String(123); // "123"
Boolean(123); // true
Symbol(123); // Symbol(123)
new Number("123"); // Number {123}
new String(123); // String {"123"}
new Boolean(true); // Boolean {true}
new Symbol(123); // Symbol is not a constructor
Реализация моделирования
когда кодnew Foo(...)При выполнении происходят следующие вещи:
- один унаследовал от
Foo.prototypeСоздается новый объект. - вызвать конструктор с указанными аргументами
Foo, и воляthisПривязать к вновь созданному объекту.new FooЭквивалентноnew Foo(), то есть без указания списка параметров,FooПри вызове без аргументов. - Объект, возвращаемый конструктором,
newрезультат выражения. Если конструктор явно не возвращает объект, используется объект, созданный на шаге 1.
Первый шаг в симуляции
newявляется ключевым словом и не может быть охвачен напрямую. использовать здесьcreateимитироватьnewЭффект.
newвозвращает новый объект, переданныйobj.__proto__ = Con.prototypeНаследует прототип конструктора, при прохожденииCon.apply(obj, arguments)Вызовите родительский конструктор для реализации наследования и получите свойства конструктора ([Дополнительная фаза 3–3]).
Код реализации выглядит следующим образом
// 第一版
function create() {
// 创建一个空的对象
var obj = new Object(),
// 获得构造函数,arguments中去除第一个参数
Con = [].shift.call(arguments);
// 链接到原型,obj 可以访问到构造函数原型中的属性
obj.__proto__ = Con.prototype;
// 绑定 this 实现继承,obj 可以访问到构造函数中的属性
Con.apply(obj, arguments);
// 返回对象
return obj;
};
пройти тест
// 测试用例
function Car(color) {
this.color = color;
}
Car.prototype.start = function() {
console.log(this.color + " car start");
}
var car = create(Car, "black");
car.color;
// black
car.start();
// black car start
Идеально!
незнакомыйapply / callНажмите, чтобы просмотреть:[Расширенная фаза 3-3] Углубленный анализ принципов вызова и применения, сценариев использования и реализации
незнакомыйнаследоватьНажмите, чтобы просмотреть:Восемь распространенных схем наследования в JavaScript
Имитационная реализация второго шага
Приведенный выше код достиг 80%, теперь продолжаем оптимизировать.
Возвращаемое значение конструктора имеет следующие три ситуации:
- 1. Вернуть объект
- 2. Нет
return, который возвращаетundefined - 3. Возврат
undefinedОсновные типы, кроме
Дело 1: возвращает объект
function Car(color, name) {
this.color = color;
return {
name: name
}
}
var car = new Car("black", "BMW");
car.color;
// undefined
car.name;
// "BMW"
примерcarможно получить только вВернуть свойства в объекте.
Случай 2:нетreturn, который возвращаетundefined
function Car(color, name) {
this.color = color;
}
var car = new Car("black", "BMW");
car.color;
// black
car.name;
// undefined
примерcarможно получить только всвойства в конструкторе, что прямо противоположно случаю 1.
Случай 3:вернутьundefinedОсновные типы, кроме
function Car(color, name) {
this.color = color;
return "new car";
}
var car = new Car("black", "BMW");
car.color;
// black
car.name;
// undefined
примерcarможно получить только всвойства в конструкторе, что является полной противоположностью случая 1, и результат эквивалентен отсутствию возвращаемого значения.
такНеобходимо оценить, является ли возвращаемое значение объектом, если это объект, вернуть объект, иначе вернуть только что созданныйobjобъект.
Таким образом, код реализации выглядит следующим образом:
// 第二版
function create() {
// 创建一个空的对象
var obj = new Object(),
// 获得构造函数,arguments中去除第一个参数
Con = [].shift.call(arguments);
// 链接到原型,obj 可以访问到构造函数原型中的属性
obj.__proto__ = Con.prototype;
// 绑定 this 实现继承,obj 可以访问到构造函数中的属性
var ret = Con.apply(obj, arguments);
// 优先返回构造函数返回的对象
return ret instanceof Object ? ret : obj;
};
[Продвинутая фаза 3-4] Решение проблем мышления
Вопрос: Реализовать функцию бесконечного накопления в JSadd, пример следующий:
add(1); // 1
add(1)(2); // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
// 以此类推
выполнить:
function add(a) {
function sum(b) { // 使用闭包
a = a + b; // 累加
return sum;
}
sum.toString = function() { // 重写toString()方法
return a;
}
return sum; // 返回一个函数
}
add(1); // 1
add(1)(2); // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
Мы знаем, что функция печати вызывается автоматически, когдаtoString()метод, функцияadd(a)возвращать закрытиеsum(b), функцияsum()кумулятивный расчетa = a + b, просто нужно переписатьsum.toString()возвращаемая переменная методаaПросто нормально.
Ссылаться на
Углубленная новая реализация моделирования JavaScript
Функция javascript add(1)(2)(3)(4) реализует бесконечное накопление