Как изпълнението на c++ функция се различава от js функциите?

Когато се опитам да стартирам програмата c++ по-долу, тя ми дава грешка при компилиране... Докато, ако се опитам да стартирам втората програма на 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 Hoisting. Мисля, че тогава ще получите отговора си. 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() в друга функция, в която var num е инициализирана. След това js ще вземе този num или глобален обхват num - person sparsh goyal; 27.07.2019
comment
@sparshgoyal - Javascript има йерархия на обхвата, но е лексикална (тъй като кодът е деклариран), а не чрез веригата за повикване. И така, display() има фиксиран лексикален обхват на кода, в който е вложен. Извикването на display() от друга функция, която има променлива num, няма да повлияе на обхвата на display(). Това, което влияе върху обхвата на display(), е това, в което е деклариран. Ако display() е деклариран в друга функция, която има променлива num, тогава тя ще намери тази променлива, когато го направи, като търси нейната променлива в йерархията на обхвата. - person jfriend00; 27.07.2019
comment
Сега редактирах малко, вижте кода по-долу във въпроса... вие казвате, че ако променливата на името е декларирана в loal обхвата, а също и в глобалния обхват, тогава по време на извикването на функцията 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