Все в Шэньчжэне собирают состояние, чтобы нанять фронтенда ~~~
Наймите фронтенда, наймите фронтенда, наймите фронтенда, добро пожаловать, чтобы отсканировать код, чтобы присоединиться к группе, оставьте свое резюме здесь:
предисловие
За это время я вдруг обнаружил, что многие вещи в JS native были забыты, но некоторые вещи действительно важны, так что буду разбираться еще раз. В основном существует 3 способа определения функций, на которые указывает функция ES5, использование вызова и приложения, 4 общих шаблона проектирования JS, цепочка прототипов, цепочка прототипов и методы наследования (ES5 и ES6).
1. 3 способа определения функций
1.1 Описание функции
//ES5
function getSum(){}
function (){}//匿名函数
//ES6
()=>{}//如果{}内容只有一行{}和return关键字可省,
1.2 Функциональные выражения (функциональные литералы)
//ES5
var sum=function(){}
//ES6
let sum=()=>{}//如果{}内容只有一行{}和return关键字可省,
1.3 Конструктор
var sum=new GetSum(num1,num2)
1.4 Сравнение трех методов
1. Объявления функций предварительно анализируются, и объявления функций имеют более высокий приоритет, чем переменные;
2. Способ использования конструктора Function для определения функции — это функциональное выражение, которое приводит к двойному синтаксическому анализу кода и влияет на производительность. Первый анализирует обычный код JavaScript, второй анализирует строку, переданную в конструктор.
2. 4 типа вызовов функций в ES5
В ES5 указатель this содержимого функции связан с вызывающим методом.
2.1 Режим вызова функции
Включая имя функции () и анонимные вызовы функций, это указывает на окно
function getSum() {
console.log(this) //window
}
getSum()
(function() {
console.log(this) //window
})()
var getSum=function() {
console.log(this) //window
}
getSum()
2.2 Вызов метода
Объект.Имя метода(), это указывает на объект
var objList = {
name: 'methods',
getSum: function() {
console.log(this) //objList对象
}
}
objList.getSum()
2.3 Вызов конструктора
новое имя конструктора(), это указывает на конструктор
function Person() {
console.log(this); //指向构造函数Person
}
var personOne = new Person();
2.4 Косвенные вызовы
Для этого используйте вызов и применение. Это первый параметр, соответствующий вызову и применению. Если значение не передано или первое значение равно нулю, это указывает на окно, когда оно не определено.
function foo() {
console.log(this);
}
foo.apply('我是apply改变的this值');//我是apply改变的this值
foo.call('我是call改变的this值');//我是call改变的this值
3. Вызов функции в ES6
Стрелочные функции нельзя использовать в качестве конструкторов, то есть объект нельзя создать с помощью новой команды, иначе будет выброшена ошибка
this функции стрелки связано с определением и не имеет ничего общего с вызовом
Вызов — это шаблон вызова функции.
(() => {
console.log(this)//window
})()
let arrowFun = () => {
console.log(this)//window
}
arrowFun()
let arrowObj = {
arrFun: function() {
(() => {
console.log(this)//arrowObj
})()
}
}
arrowObj.arrFun();
4.звоните, обращайтесь и связывайтесь
1. IE5 не поддерживает вызов и применение, привязка взята из ES5;
2.call и apply могут вызывать функции, изменять это и реализовывать методы наследования и заимствования других объектов;
4.1 Определение вызова и применения
Вызвать метод, который заменяет один объект другим (этот)
object.call(новый этот объект, аргумент 1, аргумент 2, аргумент 3...)
object.apply(новый этот объект, [параметр 1, параметр 2, параметр 3...])
4.2 позвонить и применить использование
1. Косвенно вызовите функцию и измените это значение области видимости.
2. Методы захвата других объектов
var foo = {
name:"张三",
logName:function(){
console.log(this.name);
}
}
var bar={
name:"李四"
};
foo.logName.call(bar);//李四
实质是call改变了foo的this指向为bar,并调用该函数
3. Две функции реализуют наследование
function Animal(name){
this.name = name;
this.showName = function(){
console.log(this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Black Cat");
cat.showName(); //Black Cat
4. Добавьте методы массива push, pop в массивы классов (arguments и nodeList)
(function(){
Array.prototype.push.call(arguments,'王五');
console.log(arguments);//['张三','李四','王五']
})('张三','李四')
5. Объединить массивы
let arr1=[1,2,3];
let arr2=[4,5,6];
Array.prototype.push.apply(arr1,arr2); //将arr2合并到了arr1中
6. Найдите максимальное значение массива
Math.max.apply(null,arr)
7. Определите тип персонажа
Object.prototype.toString.call({})
4.3 bind
bind — это метод расширения функции.После связывания код повторно связывает указатель this внутри func, метод не будет вызываться и несовместим с IE8.
var name = '李四'
var foo = {
name: "张三",
logName: function(age) {
console.log(this.name, age);
}
}
var fooNew = foo.logName;
var fooNewBind = foo.logName.bind(foo);
fooNew(10)//李四,10
fooNewBind(11)//张三,11 因为bind改变了fooNewBind里面的this指向
5. Четыре распространенных шаблона проектирования в JS
5.1 Заводской образец
Простой фабричный шаблон можно понимать как решение нескольких схожих задач;
function CreatePerson(name,age,sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function(){
return this.name;
}
return obj;
}
var p1 = new CreatePerson("longen",'28','男');
var p2 = new CreatePerson("tugenhua",'27','女');
console.log(p1.name); // longen
console.log(p1.age); // 28
console.log(p1.sex); // 男
console.log(p1.sayName()); // longen
console.log(p2.name); // tugenhua
console.log(p2.age); // 27
console.log(p2.sex); // 女
console.log(p2.sayName()); // tugenhua
5.2 Одноэлементный шаблон
Может быть создан только один раз (конструктор добавляет свойства и методы к экземпляру)
// 单体模式
var Singleton = function(name){
this.name = name;
};
Singleton.prototype.getName = function(){
return this.name;
}
// 获取实例对象
var getInstance = (function() {
var instance = null;
return function(name) {
if(!instance) {//相当于一个一次性阀门,只能实例化一次
instance = new Singleton(name);
}
return instance;
}
})();
// 测试单体模式的实例,所以a===b
var a = getInstance("aa");
var b = getInstance("bb");
5.3 Режим песочницы
Поместите некоторые функции в самовыполняющуюся функцию, но используйте замыкание для предоставления интерфейса, используйте переменную для получения открытого интерфейса, а затем вызовите значение внутри, иначе значение внутри не может быть использовано.
let sandboxModel=(function(){
function sayName(){};
function sayAge(){};
return{
sayName:sayName,
sayAge:sayAge
}
})()
5.4 Модель подписки издателя
Например, если мы подписаны на определенный публичный аккаунт, то он будет подталкивать вам новые новости, соответствующие ему,
//发布者与订阅模式
var shoeObj = {}; // 定义发布者
shoeObj.list = []; // 缓存列表 存放订阅者回调函数
// 增加订阅者
shoeObj.listen = function(fn) {
shoeObj.list.push(fn); // 订阅消息添加到缓存列表
}
// 发布消息
shoeObj.trigger = function() {
for (var i = 0, fn; fn = this.list[i++];) {
fn.apply(this, arguments);//第一个参数只是改变fn的this,
}
}
// 小红订阅如下消息
shoeObj.listen(function(color, size) {
console.log("颜色是:" + color);
console.log("尺码是:" + size);
});
// 小花订阅如下消息
shoeObj.listen(function(color, size) {
console.log("再次打印颜色是:" + color);
console.log("再次打印尺码是:" + size);
});
shoeObj.trigger("红色", 40);
shoeObj.trigger("黑色", 42);
Логика реализации кода заключается в том, чтобы хранить подписчиков в массиве, а метод уведомления в функции обратного вызова издателя состоит в обходе массива подписчиков и передаче содержимого издателя в массив подписчиков.
Для получения дополнительных шаблонов дизайна, пожалуйста, нажмите:Подробное объяснение общих шаблонов проектирования в Javascript.
6. Цепочка прототипов
6.1 Определения
Цепочка свойств наследования объекта
6.2 Конструктор, связь между экземпляром и объектом-прототипом
var Person = function (name) { this.name = name; }//person是构造函数
var o3personTwo = new Person('personTwo')//personTwo是实例
Объекты-прототипы имеют свойство конструктора по умолчанию, указывающее на конструктор.
6.3 Как создать экземпляр
1. Буквальный
let obj={'name':'张三'}
2. Создание конструктора объектов
let Obj=new Object()
Obj.name='张三'
3. Используйте фабричный шаблон для создания объектов
function createPerson(name){
var o = new Object();
o.name = name;
};
return o;
}
var person1 = createPerson('张三');
4. Используйте конструктор для создания объектов
function Person(name){
this.name = name;
}
var person1 = new Person('张三');
6.4 Новый оператор
1. Создайте новый объект;
2. это указывает на конструктор;
3. Конструктор вернулся, заменив объект из New, если нет, то выходящий объект.
4. Вручную инкапсулировать новый оператор
var new2 = function (func) {
var o = Object.create(func.prototype);    //创建对象
var k = func.call(o);             //改变this指向,把结果付给k
if (typeof k === 'object') {         //判断k的类型是不是对象
return k;                  //是,返回k
} else {
return o;                  //不是返回返回构造函数的执行结果
}
}
Подробнее:Подробно о цепочке прототипов JavaScript
6.5 Цепочка прототипов объектов
7. Способ наследования
JS - это слабо напечатанный динамический язык, инкапсуляция и наследство - это две основные характеристики
7.1 наследование цепочки протоколов
Использовать экземпляр родительского класса в качестве прототипа дочернего класса
1. Реализация кода
Определите родительский класс:
// 定义一个动物类
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
Подкласс:
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name);//cat
console.log(cat.eat('fish'));//cat正在吃:fish undefined
console.log(cat.sleep());//cat正在睡觉! undefined
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
2. Преимущества и недостатки
Просто и легко реализовать, но если вы хотите добавить свойства и методы к подклассам, вы должны выполнить их после операторов, таких как new Animal(), которые не могут обеспечить множественное наследование.
7.2 Конструктивное наследование
Суть в том, чтобы использовать вызов для изменения этой точки в Cat
1. Реализация кода
Подкласс:
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
2. Преимущества и недостатки
Множественное наследование может быть достигнуто, но свойства/методы прототипа не могут быть унаследованы
7.3 Наследование экземпляра
Добавьте новые свойства в экземпляр родительского класса и верните его как экземпляр дочернего класса.
1. Реализация кода
Подкласс
function Cat(name){
var instance = new Animal();
instance.name = name || 'Tom';
return instance;
}
2. Преимущества и недостатки
Не ограничивает вызывающий метод, но не может обеспечить множественное наследование
7.4 Наследование копирования
Скопируйте свойства и методы родительского класса в детский класс
1. Подкласс:
function Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name || 'Tom';
}
2. Преимущества и недостатки
Поддерживает множественное наследование, но неэффективно и занимает память
7.5 Композиционное наследование
Вызывая структуру родительского класса, наследуйте свойства родительского класса и сохраняйте преимущества передачи параметров, а затем реализуйте повторное использование функций, используя экземпляр родительского класса в качестве прототипа дочернего класса.
1. Подкласс:
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
7.6 Наследование паразитарного состава
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
})();
7.7 ES6 расширяет наследование
Механизм наследования ES6 заключается в том, чтобы сначала создать объект экземпляра this родительского класса (поэтому сначала должен быть вызван суперметод), а затем использовать конструктор подкласса для его изменения.Ссылка Описание
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}
Для получения более подробной информации, пожалуйста, нажмите:Реализация наследования JS
использованная литература:
www.cnblogs.com/tugen...
www.cnblogs.com/humin...
www.cnblogs.com/cheng...
www.cnblogs.com/cheng...