Чем выполнение функции С++ отличается от функций js?

Когда я пытаюсь запустить приведенную ниже программу С++, она дает мне ошибку компиляции... В то время как, если я пытаюсь запустить вторую программу javascript ниже, она не дает мне никакой ошибки. Почему?

////c++////

#include<iostream>
using namespace std;

void display(){
    cout << num << endl;  // error: num is not defined in this scope
}

int num = 30;

int main(){
    return 0;
}

/////JavaScript////

function display(){
    console.log(num)    // no error
}

let num = 25;
display()

В случае c++ переменная num не объявлена ​​на верхнем уровне, поэтому она выдает мне ошибку.... Но в случае javaScript переменная 'num' не объявлена ​​на верхнем уровне, но она не дает никакой ошибки... Почему это происходит?

Я также ожидал ошибки в js....

function display(){
    console.log(name)
}

let name = 'hi'
function test(){
    var name = 'Hello'
    display()
}

test()  // output : hi

person sparsh goyal    schedule 26.07.2019    source источник
comment
Пожалуйста, прочитайте о подъеме JavaScript. Я думаю, тогда вы получите свой ответ. w3schools.com/js/js_hoisting.asp   -  person Mazedul Islam    schedule 27.07.2019
comment
связанный/обман: 1, 2   -  person NathanOliver    schedule 27.07.2019
comment
@MohammadMazedulIslam - На самом деле речь идет не о подъеме в Javascript. Дело в том, что Javascript интерпретируется и динамически ищет значение num при запуске display(). Итак, к моменту запуска display() num находится в родительской области и имеет значение, поэтому интерпретатор доволен.   -  person jfriend00    schedule 27.07.2019


Ответы (1)


Javascript — это «интерпретируемый язык», который ищет символы во время выполнения функции, а не во время разбора языка. Это означает, что num просто должен существовать и иметь значение в соответствующей области, когда вызывается display(), а не при первом анализе кода. Переменная num динамически просматривается во время выполнения (не разрешается во время синтаксического анализа) в лексической области видимости. И, поскольку num определяется и инициализируется в соответствующей области до вызова display(), когда интерпретатор ищет num в текущей области видимости во время работы display(), он находит переменную с именем num и может ее использовать.

Но C++ — это скомпилированный язык, который оценивает символы при анализе/компиляции языка. num должен существовать во время компиляции, когда компилируется display(), и он еще не был объявлен, когда компилятор пытается скомпилировать display(), поэтому его невозможно найти, и это создает ошибку компиляции. Конечно, вы можете обойти это, изменив объявление display() так, чтобы он принимал аргумент int, а затем передавая значение num в качестве аргумента, когда вы вызываете его, как в display(num). Это удовлетворит компилятор.

person jfriend00    schedule 26.07.2019
comment
хорошо, но если бы я вызвал функцию display() внутри другой функции, в которой была инициализирована переменная num. Тогда js возьмет это число или глобальную область действия - person sparsh goyal; 27.07.2019
comment
@sparshgoyal - Javascript имеет иерархию области действия, но она лексическая (поскольку объявлен код), а не через цепочку вызовов. Таким образом, display() имеет фиксированную лексическую область действия кода, в который она вложена. Вызов display() из какой-либо другой функции, имеющей переменную num, не повлияет на область действия display(). Что влияет на область действия display(), так это то, в чем она объявлена. Если display() объявлено внутри другой функции, имеющей переменную num, то она найдет эту переменную при поиске переменной в иерархии области видимости. - person jfriend00; 27.07.2019
comment
Теперь я немного отредактировал, см. приведенный ниже код в вопросе... вы говорите, что если переменная имени объявлена ​​в локальной области, а также в глобальной области, то во время вызова функции display() она примет это локальное имя. .. так что я ожидал, что на выходе будет привет, но на выходе привет - person sparsh goyal; 27.07.2019
comment
О.. Хорошо, спасибо, я полностью понимаю, о чем вы говорите, большое вам спасибо, вы решили мою проблему, я исследовал ее много часов. Можете ли вы предложить мне темы, чтобы понять все проблемы, связанные с интерпретатором, и исправленную лексическую область видимости? - person sparsh goyal; 27.07.2019
comment
@sparshgoyal - Главное - понять, что такое лексическая область видимости Javascript. В этом наборе результатов поиска есть несколько хороших статей. В примере, который вы добавили к своему вопросу, var name не входит в лексическую область действия display(). Он находится в лексической области видимости test() и является частным для этой функции. let name = 'hi'; находится в лексической области видимости display() (на самом деле она находится в родительской области, но поиск выполняется в родительских областях, если символ не найден локально). - person jfriend00; 27.07.2019
comment
@DaveNewton - я понимаю, о чем ты говоришь. Речь идет о том, как работает язык (динамический поиск символов во время выполнения). Но эта проблема на самом деле не о подъеме. Это все равно будет работать, даже если не было подъема, потому что объявление и инициализация переменной происходит до вызова display() и, таким образом, она полностью инициализируется в родительской области до выполнения display(), тогда как C++ требует, чтобы переменная была известна во время компиляции. Javascript нужно знать только во время выполнения. - person jfriend00; 27.07.2019
comment
Да, правда. Я предполагаю, что моя точка зрения заключалась в том, что компиляция/интерпретация не является проблемой ненависти. Это было автоматически исправлено, но более интересно, чем то, что я имел в виду. - person Dave Newton; 27.07.2019
comment
@DaveNewton - я изменил ответ на основе ваших отзывов. - person jfriend00; 27.07.2019