Jump to content

Problema a fazer "reload" de script


coxosclassic

Recommended Posts

coxosclassic

Boas,

Estou a desenvolver uma aplicação que necessita carregar, apagar e voltar a carregar scripts externos  mas não o estou a conseguir fazer devidamente.

Deixo aqui um exemplo:

Script externo:

class ClassA {
    constructor() {
        console.log("ClassA object created");
    }
}

Aquilo que estou a tentar fazer:

let aScript = document.createElement("script");

aScript.onload = function() {
  
  //Testo um objeto do tipo ClassA
  let classA = new ClassA(); //OK (ClassA object created)
  classA = null //OK
  
  //Tento apagar o script...
  document.head.removeChild(aScript); //OK
  delete ClassA; //OK
  ClassA = null; //OK

  //Tento voltar a carregar o mesmo script...
  aScript = document.createElement("script");
  aScript.src = "ClassA.js";
  document.head.appendChild(aScript);
  //...e dá erro: (ClassA.js:1 Uncaught SyntaxError: Identifier 'ClassA' has already been declared at VM1088 ClassA.js:1)
};

aScript.src = "ClassA.js"; //Carrego o script pela 1ª vez.
document.head.appendChild(aScript);

Pelo que tenho procurado, remover o elemento"script" ou fazer "delete" ou "null", não remove o objecto em si da memória mas apenas do DOM (?). Li também algures que uma classe fica guardada como Global Variable no engine e que assim sendo é impossível apagar?

Alguém sabe como remover definitivamente um objeto (class) da memória? Ou então sugerir outra maneira de tentar fazer o que pretendo (carregar, apagar e voltar a carregar uma classe em JS)?

 

Obrigado,

cc

Cumps,

cc

Link to post
Share on other sites

Quando fazes referência ao "document", basicamente referes-te ao DOM, que é como quem diz, à estrutura HTML/XML que o browser interpreta.

Uma forma de "eliminares" (e nota as aspas) uma função de Javascript que fica em memória é redefinires a mesma de forma a que não faça nada, "nulificas" a mesma (desculpa a expressão, mas creio que percebes o que quero dizer):

function minhaFn(arg){
	alert(arg)
	}

window['minhaFn']=function(){null}

// Testar:
minhaFn('boo');

 

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to post
Share on other sites
coxosclassic

O meu problema é estar a tentar usar classes em vez de funções.

Se o meu script externo fosse algo tipo :

(function(window) {

    function ClassA() {
        console.log("ClassA object created");
    }
    window.ClassA = ClassA;

}(window));

Desta forma conseguia eliminar, mas como estou a usar "class" não o estou a conseguir nem com o exemplo que mostraste. Dá sempre o erro:

Uncaught SyntaxError: Identifier 'ClassA' has already been declared

Aparentemente uma "class" não é tratada da mesma maneira que uma função ou variável(?). Não estou a conseguir encontrar informação relevante sobre o assunto, apenas de que se tratam de "special functions" e pouco mais..

Queria mesmo manter as classes pois todos os scripts que preciso carregar / apagar seguem essa definição.

Tens ideia de como eliminar uma class? Ou consegues indicar um artigo que me ajude a entender como o JavaScript define classes e faz a sua gestão na memória?  

 

Obrigado.

Cumps,

cc

Link to post
Share on other sites
coxosclassic

OK, consegui encontrar a solução. Queria pedir aos admins para o marcarem como resolvido.

Basicamente trata-se de um problema de scope.

O que se passa é que em javascript (es6) a declaração de uma "class" segue o mesmo padrão de declaração de "const". Não são guardadas como propriedades em "global object" (o window do browser) logo não podem ser apagadas ou "re-declaradas".

O motivo para esta convenção é que ainda não entendi bem...

 

No fundo a solução do @M6 (obrigado!) será a mais indicada, apenas precisava de mudar o script com a class para:

window.ClassA = class {
    constructor() {
        console.log("ClassA object created");
    }
}

ou:

(function(window) {
    class ClassA {
        constructor() {
            console.log("ClassA object created");
        }
    }
    window.ClassA = ClassA;
}(window));

Desta forma mantenho a class em "global object" (window) e consigo apagar e voltar a reutilizar:

let classAScript = document.createElement("script");

classAScript.onload = function() {

    new ClassA();

    document.head.removeChild(classAScript);
    delete ClassA;

    classAScript = document.createElement("script");
    classAScript.src = "ClassA.js";
    document.head.appendChild(classAScript);
};

classAScript.src = "ClassA.js";
document.head.appendChild(classAScript);

Espero que isto ajude quem vier a ter o mesmo problema.

cumps.

 

EDIT: Não sei se será "ético" colocar um link para o stackoverflow aqui, mas foi lá que também me ajudaram na solução e acho que contém informação bastante relevante. Se houver problema eu retiro este link. :)

cumps.

Edited by coxosclassic

Cumps,

cc

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.