developer tip

JavaScript의 포인터?

optionbox 2020. 10. 16. 07:21
반응형

JavaScript의 포인터?


불변의 변수에 대한 참조를 함수의 인수로 전달할 수 있습니까?

예:

var x = 0;
function a(x)
{
    x++;
}
a(x);
alert(x); //Here I want to have 1 instead of 0

JavaScript는 참조에 의한 매개 변수 전달을 지원하지 않으므로 대신 변수를 객체로 만들어야합니다.

var x = {Value: 0};

function a(obj)
{
    obj.Value++;
}

a(x);
document.write(x.Value); //Here i want to have 1 instead of 0

이 경우은 x객체에 대한 참조입니다. x함수에가 전달 되면 a해당 참조가로 복사됩니다 obj. 따라서, objx메모리에 같은 일을 참조하십시오. 변화 Value의 특성은 obj에 영향을 미치는 Value의 속성을 x.

Javascript는 항상 값으로 함수 매개 변수를 전달합니다. 그것은 단순히 언어의 사양입니다. 당신은 할 수 만들 x두 기능의 로컬 범위에서, 모든에 변수를 전달하지.


이 질문이 도움이 될 수 있습니다 : 자바 스크립트에서 참조로 변수를 전달하는 방법? 둘 이상의 값을 반환하는 ActiveX 함수에서 데이터 읽기

요약하자면 Javascript 기본 유형은 항상 값으로 전달되는 반면 객체 내부의 값은 참조로 전달됩니다 (내 감독을 지적한 주석가에게 감사). 따라서이 문제를 해결하려면 정수를 객체 안에 넣어야합니다.

var myobj = {x:0};

function a(obj)
{
    obj.x++;
}

a(myobj);
alert(myobj.x); // returns 1

  


C 관점에서 더 일반적이고 이해하기 쉬운 포인터를 구현하는 약간 다른 방법을 발견했습니다 (따라서 사용자 예제의 형식에 더 적합합니다).

C에서와 같이 JavaScript에서 배열 변수는 실제로 배열에 대한 포인터 일 뿐이므로 포인터를 선언하는 것과 똑같이 배열을 사용할 수 있습니다. 이렇게하면 원래 개체에서 변수 이름을 지정 했음에도 불구하고 코드의 모든 포인터를 동일한 방식으로 사용할 수 있습니다.

또한 포인터의 주소와 포인터의 주소를 참조하는 두 가지 다른 표기법을 사용할 수 있습니다.

다음은 예입니다 (밑줄을 사용하여 포인터를 나타냄).

var _x = [ 10 ];

function foo(_a){
    _a[0] += 10;
}

foo(_x);

console.log(_x[0]);

수율

output: 20

창 개체에서 'x'를 참조합니다.

var x = 0;

function a(key, ref) {
    ref = ref || window;  // object reference - default window
    ref[key]++;
}

a('x');                   // string
alert(x);

늦게 답변했지만 클로저를 통해 참조로 원시 값을 전달하는 방법을 발견했습니다. 포인터를 만드는 것은 다소 복잡하지만 작동합니다.

function ptr(get, set) {
    return { get: get, set: set };
}

function helloWorld(namePtr) {
    console.log(namePtr.get());
    namePtr.set('jack');
    console.log(namePtr.get())
}

var myName = 'joe';
var myNamePtr = ptr(
    function () { return myName; },
    function (value) { myName = value; }
);

helloWorld(myNamePtr); // joe, jack
console.log(myName); // jack

ES6에서는 람다 식을 사용하도록 코드를 줄일 수 있습니다.

var myName = 'joe';
var myNamePtr = ptr(=> myName, v => myName = v);

helloWorld(myNamePtr); // joe, jack
console.log(myName); // jack

JavaScript에서 그것은 글로벌이 될 것입니다. 그러나 함수는 다음과 비슷합니다.

function a(){
   x++;
};

이후 x글로벌 맥락에서, 당신은 함수에 전달할 필요가 없습니다.


Javascript는 많은 문제를 해결하는 믹스 코즈에 포인터를 넣어야합니다. 이는 코드가 동적으로 생성 된 알 수없는 변수 이름 또는 변수를 참조 할 수 있음을 의미합니다. 또한 모듈 식 코딩과 삽입을 쉽게 할 수 있습니다.

이것은 실제로 c 포인터에 가장 가깝다고 생각하는 것입니다.

js에서 :

var a = 78;       // creates a var with integer value of 78 
var pointer = 'a' // note it is a string representation of the var name
eval (pointer + ' = 12'); // equivalent to: eval ('a = 12'); but changes value of a to 12

c에서 :

int a = 78;       // creates a var with integer value of 78 
int pointer = &a; // makes pointer  to refer to the same address mem as a
*pointer = 12;   // changes the value of a to 12

JavaScript가 Perl의 "\"연산자를 가지고 있지 않기 때문에 참조로 프리미티브를 얻는 것이 불가능할 수도 있지만,이 패턴을 사용하여 프리미티브에 대해 "효과적으로 포인터"객체를 생성하는 방법이 있습니다.

This solution makes the most sense for when you already have the primitive(so you can't put it into an object anymore without needing to modify other code), but still need to pass a pointer to it for other parts of your code to tinker with its state; so you can still tinker with its state using the seamless proxy which behaves like a pointer.

var proxyContainer = {};

// | attaches a pointer-lookalike getter/setter pair
// | to the container object.
var connect = function(container) {
    // | primitive, can't create a reference to it anymore
    var cant_touch_this = 1337;

    // | we know where to bind our accessor/mutator
    // | so we can bind the pair to effectively behave
    // | like a pointer in most common use cases.
    Object.defineProperty(container, 'cant_touch_this', {
        'get': function() {
            return cant_touch_this;
        },                
        'set': function(val) {
            cant_touch_this = val;
        }
    });
};

// | not quite direct, but still "touchable"
var f = function(x) {
    x.cant_touch_this += 1;
};

connect(proxyContainer);

// | looks like we're just getting cant_touch_this
// | but we're actually calling the accessor.
console.log(proxyContainer.cant_touch_this);

// | looks like we're touching cant_touch_this
// | but we're actually calling the mutator.
proxyContainer.cant_touch_this = 90;

// | looks like we touched cant_touch_this
// | but we actually called a mutator which touched it for us.
console.log(proxyContainer.cant_touch_this);

f(proxyContainer);

// | we kinda did it! :)
console.log(proxyContainer.cant_touch_this);

In JavaScript, you cannot pass variables by reference to a function. However you can pass an object by reference.


I'm thinking that in contrary to C or any language with pointers :

/** Javascript **/
var o = {x:10,y:20};
var o2 = {z:50,w:200};
  • obviously in javascript you cannot access to objects o and o2 addresses in memory
  • but you can't compare their address neither : (no trivial possibility to sort them, and then access by dichotomy)

.

o == o2 // obviously false : not the same address in memory
o <= o2 // true !
o >= o2 // also true !!

that's a huge problem :

  • it means that you can list/manage every objects created (allocated) by your application,

  • from that huge list of objects, compute some information about these (how they are linked together for example)

  • but when you want to retrieve the information you created about a specific object, you cannot find it in your huge list by dichotomy : there is no unique identifier per object that could be used as a replacement of the real memory address

this finally means that this is a huge problem, if you want to write in javascript :

  • a javascript debugger / IDE
  • or a specially optimized garbage collector
  • a data structure drawer / analyzer

JavaScript doesn't support passing primitive types by reference. There is a workaround, though.

Put all the variables you need to pass in an object. In this case, there's only one variable, x. Instead of passing the variable, pass the variable name as a string, which is "x".

var variables = {x:0};
function a(x)
{
    variables[x]++;
}
a("x");
alert(variables.x);


Depending on what you would like to do, you could simply save the variable name, and then access it later on like so:

function toAccessMyVariable(variableName){
  alert(window[variableName]);
}

var myFavoriteNumber = 6; 

toAccessMyVariable("myFavoriteNumber");

To apply to your specific example, you could do something like this:

var x = 0;
var pointerToX = "x";

function a(variableName)
{
    window[variableName]++;
}
a(pointerToX);
alert(x); //Here I want to have 1 instead of 0

It just doesn't support pointers, end of story :-(.

I would like to add that, while I'm brand new and coming from a C background, from what I'm reading about the event loop and stack, you should keep whichever object as close to its caller as possible. As I'm brand new, I could have this wrong.

A lot of answers here suggest to make it global, but again if I'm reading correctly, that could possibly increase the stack hops and in a way, possibly fragment your event loop needlessly (depending on what the called object is currently doing) .

Also, any example given that mimics pointers, is just 1 in many ways to do the same thing, which will not be a pointer.


No you cannot. The browser doesn't give u access to the system memory, and its varibles. It should be possible with an envirovment like node, but inside the browser its not quite possible unless you are a hacker.


In your example you actually have 2 variables with the same name. The (global) variable x and the function scoped variable x. Interesting to see that javascript, when given a choice of what to do with 2 variables of the same name, goes with the function scoped name and ignores the out-of-scope variable.

It's probably not safe to presume javascript will always behave this way...

Cheers!

참고URL : https://stackoverflow.com/questions/10231868/pointers-in-javascript

반응형