Прототип, цепочка прототипов, объем, цепочка объемов, замыкание

JavaScript
Прототип, цепочка прототипов, объем, цепочка объемов, замыкание

Я считаю, что тема знает, что это постоянные вопросы интервьюирования тысячелетия JS.

Прототип, цепочка прототипов?

Что такое прототип, цепочка прототипов?

Прототип: Эквивалент пресс-формы, используемой для производства объектов-экземпляров.

Цепочка прототипов: объект-прототип имеет указатель на конструктор, а объект-экземпляр имеет указатель на объект-прототип, формируя цепочку прототипов, которая в конечном итоге указывает на null.

Почему он существует?

Прототип: это способ реализации объектно-ориентированного подхода в js, то есть js является объектно-ориентированным на основе прототипа.

Цепочка прототипов: это то, как js реализует наследование.

Прицел, цепочка прицелов?

Что такое объем, цепочка объемов?

  • объем

Так называемая область видимости — это область действия переменной или функции, которую можно использовать.

Так что же такое область видимости в JavaScript?

1. Глобальный охват

За исключением переменных, определенных в функциях, все они находятся в глобальной области видимости.

Возьмите каштан:

var a = 10;
function bar(){
    console.log(a);
}
bar();//10

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

var a = 10;
function bar(){
    console.log(a);
    var a = 20;
}
bar();//undefined

Что за черт? неопределенный?

Да, вы не ошибаетесь. Поскольку переменные функции сначала просматриваются, чтобы увидеть, есть ли a, есть ли, и поскольку a предварительно анализируется (продвижение переменной), продвигаемый a привязывается к области действия a здесь, поэтому результат не определен.

2. Локальный охват

Переменная, объявленная с помощью var в функции.

Возьмите каштан:

var a = 10;
function bar(){
   var a  = 20;
    console.log(a);
}
bar();//20

3. Нет блочной области (до ES5), в ES6 есть блочная область

До ES6 блоки, отличные от функций, не имели области действия блока.

Общие классические примеры:

for(var i=0;i<4;i++){
    setTimeout(function(){
    	console.log(i);
    },200);
}
//4 4 4 4

Решение:

for(var i=0;i<4;i++){
    (function(j){
            setTimeout(function(){
    	console.log(j);
    },200);
    })(i)
}
//0 1 2 3
  • цепочка прицелов

Переменные просматриваются уровень за уровнем с помощью функции старшей функции, пока они не будут найдены, и если они не будут найдены, будет сообщено об ошибке.Этот процесс является ролью цепочки областей видимости.

var num = 30;
function f1(){
    var num  = 20;
    function f2(){
        var num = 10;
        function f3(){
            var num = 5;
            console.log(num);
        }
        f3();
    }
   f2();
}
f1();

js

Закрытие

Закрытие: способ приватизировать данные и методы в js. Внутренняя функция может вызывать переменные и методы внешней функции.

классические вопросы на собеседовании

Если есть такая необходимость

  • go('l') -> gol
  • go()('l') -> gool
  • go()()('l') -> goool
var go = function (a) {
var str = 'go';
    var add0 = function (a) {
    	str += 'o';
    	return a ? str += a : add0;// 巧妙使用
    }
	return a ? str += a : add0;// 巧妙使用
}
console.log(go('l'));//gol
console.log(go()('l'));//gool
console.log(go()()('l'));//goool

наследовать

Так как мы говорили о наследовании ранее. Наследование означает, что объект может разделять некоторые свойства родительского объекта. Так зачем вам наследование? Например, в приведенном выше вопросе фигура Shape имеет атрибут вершины, и треугольники и прямоугольники могут наследовать этот атрибут без его переопределения. Итак, давайте поговорим о реализации наследования в JavaScript до ES6 и после ES6.

  • До ES6

наследование композиции

function Parent(name, age) {
    this.name = name;
    this.age = age;
}  
Parent.prototype.getName = function() {
    return this.name;
}
function child(name, age, sex) {
    Parent.call(this, name, age);
    this.sex = sex;
}

child.prototype = new Parent()
var c1 = new child('zenquan', '23', 'M')
console.log(c1.getName())
console.log(c1)

Преимущество этого метода наследования в том, что конструктор может передавать параметры, он не будет делиться с родительским классом ссылочным свойством, и функции родительского класса можно использовать повторно, но есть и недостаток в том, что конструктор родительского класса вызывается при наследовании функции родительского класса, в результате чего в прототипе подкласса появляется больше ненужных свойств родительского класса, что является пустой тратой памяти.

Наследование паразитарного состава

function parent(name, age) {
    this.name = name;
    this.age = age;
}  
parent.prototype.getName = function() {
    return this.name;
}

function child(name, age, sex) {
    parent.call(this, name, age);
    this.sex = sex;
}

child.prototype = Object.create(parent.prototype, {
    constructor: {
        value: child,
        enumerable: true,
        writable: true,
        configurable: true
    }
})

var c1 = new child('zenquan', 23, 'M');

console.log(c1.getName())
console.log(c1)

Суть приведенной выше реализации наследования состоит в том, чтобы присвоить прототип родительского класса подклассу и установить конструктор в подкласс, что не только решает проблему бесполезных атрибутов родительского класса, но и корректно находит конструктор подкласса.

  • наследование классов после ES6

    Вышеупомянутые два метода наследования решаются через прототипы, В ES6 мы можем использоватьclassЧтобы реализовать наследование, и это очень просто реализовать

    class parent {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        getName() {
            return this.name;
        }
    }  
    class child extends parent {
        constructor(name, age, sex) {
            super(name, age);
            this.sex = sex;
        }
    }
    var c1 = new child('zenquan', 23, 'M');
    console.log(c1);