자바 스크립트 변수 참조 / 별칭


89

자바 스크립트에서 로컬 var에 별칭 / 참조를 할당하는 것이 가능합니까?

나는 C와 같은 것을 의미합니다.

function foo() {
  var x = 1;
  var y = &x;
  y++;
  alert(x); // prints 2 
}

= 편집하다 =

이 코드에서 arguments.callee 별칭을 사용할 수 있습니까? :

function foo() {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 0;
  arguments.callee.myStaticVar++;
  return arguments.callee.myStaticVar;
}

5
간단한 대답은 아니오입니다. 하지만 SO에있는 사람이 :)을 할 수있는 해킹으로 올 것이라는 느낌했습니다
Amarghosh

답변:


173

JavaScript에서 정수 및 문자열과 같은 기본 유형은 값으로 전달되는 반면 객체는 참조로 전달됩니다. 따라서이를 달성하려면 객체를 사용해야합니다.

// declare an object with property x
var obj = { x: 1 };
var aliasToObj = obj;
aliasToObj.x ++;
alert( obj.x ); // displays 2

그것은 빠르다 =) 내 함수 내에서 arguments.callee에 대한 별칭을 만들고 싶습니다 (매번 arguments.callee 입력을 피하기 위해). 이 방법으로 이것이 가능합니까? 이해하면 "인수"라는 별칭을 사용할 수 있지만 어쨌든 "callee"를 작성해야합니다. 그렇지 않습니까?
gpilotino

9
@Darin : 이것은 그것을 약간 지나치게 단순화 한 것입니다. 원시 유형 대 객체가 아닌 불변 유형 대 가변 유형입니다. JavaScript에서 모든 것은 어떤 형태의 객체입니다.
Crescent Fresh

7
JS에서 참조는 값으로 전달됩니다. "참조로 전달"과 "값으로 참조를 전달"에는 차이가 있습니다. Javascript에서 참조에 의한 매개 변수 전달은 지원되지 않습니다.
Corneliu

15

어느 정도 가능하면 클로저를 사용하여 변수에 대한 별칭을 만들 수 있습니다.

Function.prototype.toString = function() {
    return this();
}

var x = 1;
var y = function() { return x }
x++;
alert(y); // prints 2, no need for () because of toString redefinition 

1
"alert (y); // prints 2"는 다음과 같아야합니다. "alert (y ()); // prints 2"결과를 얻으려면 실제로 함수를 호출해야합니다. 제안 된 구문이 특정 상황에서 도움이 될 것이기 때문에 너무 나쁩니다.
Nathan Labenz 2013

3
그 toString 재정의에는 이유가 있으므로 alert(y)실제로 옳습니다. Function 프로토 타입 메서드를 재정의하는 것은 매우 나쁜 스타일입니다. 하지만 작동합니다!
metalim

8

별칭을 사용할 수 있는지 여부는 데이터 유형에 따라 다릅니다. 객체, 배열 및 함수는 참조로 처리되며 앨리어싱이 가능합니다. 다른 유형은 본질적으로 원자 적이며 변수는 값에 대한 참조가 아닌 값을 저장합니다.

arguments.callee는 함수이므로 이에 대한 참조를 갖고 해당 공유 객체를 수정할 수 있습니다.

function foo() {
  var self = arguments.callee;
  self.myStaticVar = self.myStaticVar || 0;
  self.myStaticVar++;
  return self.myStaticVar;
}

위의 코드에서 말한다면 있음을 참고 self = function() {return 42;};한 후 self다음을 참조 할 다른 개체 보다 더 arguments.callee에 대한 참조를 유지 foo. 복합 객체가있는 경우 할당 연산자가 참조를 대체하지만 참조 된 객체는 변경되지 않습니다. 원자 값을 사용하는 경우와 같은 경우 는 변수에 '새로운'정수를 할당하는와 y++동일 y = y + 1합니다.


arguments.callee함수의 이름 인 별칭 이 이미 있다는 것은 말할 것도 없습니다 . 이 예에서는 그냥 사용할 수 있습니다 foo.myStaticVar(2009 년에는
그렇지 않았을까요

1

내 이전 답변 편집 : 함수 호출을 계산하려면 다음을 시도해 볼 수 있습니다.

var countMe = ( function() {
  var c = 0;

  return function() {
    c++;
    return c;
  }
})();

alert(countMe()); // Alerts "1"
alert(countMe()); // Alerts "2"

여기서 c는 카운터 역할을하며 arguments.callee를 사용할 필요가 없습니다.


또는 당신은 정적 변수 사용할 수 있습니다 countMe = function f(){ return ++f.c || (f.c = 1); }
aljgom

1

user187291의 게시물을 확장 하면 getter / setter를 사용하여 함수를 사용해야하는 상황을 해결할 수도 있습니다.

var x = 1;
var ref = {
    get x()  { return x; },
    set x(v) { x = v; }
};
(ref.x)++;
console.log(x); // prints '2'
x--;
console.log(ref.x); // prints '1'

0

2019 년에는 축소 된 jquery 플러그인을 작성해야 하므로이 별칭이 필요하므로 다른 소스에서 이러한 예제와 기타를 테스트하여 전체 객체의 메모리에 복사하지 않고 참조 만 생성하는 방법을 찾았습니다. 나는 이미 파이어 폭스로 이것을 테스트하고 전에 파이어 폭스에서 작업 관리자의 탭 메모리를 보았습니다. 코드는 다음과 같습니다.

var {p: d} ={p: document};
console.log(d.body);

이것은 참조로 아무것도 전달하지 않으며 문서를 직접 전달할 수 있습니다 (이미 객체에 대한 참조이며 값으로 전달됨). 구조 해제는 별칭을 생성하지 않습니다.
모니카 기억
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.