source

JavaScript의 "with" 스테이트먼트에 정당한 용도가 있습니까?

manysource 2023. 1. 17. 21:22

JavaScript의 "with" 스테이트먼트에 정당한 용도가 있습니까?

성명에 대한 나의 답변에 대한 Alan Storm의 논평은 나를 생각하게 했다.저는 이 특별한 언어 기능을 사용해야 할 이유를 거의 찾지 못했고, 그것이 어떻게 문제를 일으킬지 생각해 본 적이 없습니다.이제, 어떻게 하면 이 모든 것들을 효과적으로 활용할 수 있을지 궁금하네요.with츠미야

디디????? 는 어디서 ?with움이이 되는 ?? ???

오늘 또 다른 용도가 떠올랐기 때문에 웹을 열심히 검색해 보니 블록 스코프 내의 변수 정의라는 기존의 언급이 있었습니다.

배경

JavaScript는 C 및 C++와 표면적으로 유사하지만 변수가 정의된 블록에 대해 범위를 지정하지 않습니다.

var name = "Joe";
if ( true )
{
   var name = "Jack";
}
// name now contains "Jack"

루프에서 폐쇄를 선언하는 것은 일반적인 작업이며, 이로 인해 오류가 발생할 수 있습니다.

for (var i=0; i<3; ++i)
{
   var num = i;
   setTimeout(function() { alert(num); }, 10);
}

스코프를 에, 「」의 와 같습니다.num값 - : :2세 기능 - 세 가지 기능 모두 공유됩니다.

스코프: " " " " 。let ★★★★★★★★★★★★★★★★★」with

「 」의 letES6에서는 필요에 따라 새로운 범위를 도입하여 다음 문제를 회피할 수 있습니다.

// variables introduced in this statement 
// are scoped to each iteration of the loop
for (let i=0; i<3; ++i)
{
   setTimeout(function() { alert(i); }, 10);
}

또는 다음과 같은 경우도 있습니다.

for (var i=0; i<3; ++i)
{
   // variables introduced in this statement 
   // are scoped to the block containing it.
   let num = i;
   setTimeout(function() { alert(num); }, 10);
}

ES6가 보편적으로 이용될 때까지, 이 사용은 최신 브라우저와 트랜스필러를 사용할 의사가 있는 개발자로 한정됩니다.이 가 쉽게 흉내 낼 수 있는 동작입니다.with:

for (var i=0; i<3; ++i)
{
   // object members introduced in this statement 
   // are scoped to the block following it.
   with ({num: i})
   {
      setTimeout(function() { alert(num); }, 10);
   }
}

이제 루프는 의도한 대로 작동하며 값이 0 ~2인 세 개의 개별 변수를 만듭니다.C++의 블록 동작과는 달리 블록 내에서 선언된 변수는 해당 블록으로 범위가 지정되지 않습니다(C의 경우 블록 시작 부분에서 변수를 선언해야 하므로 비슷한 방식으로 선언할 수 있습니다).이 동작은 실제로 이전 버전의 Mozilla 브라우저에서 도입된 블록 구문과 매우 유사하지만 다른 곳에서는 널리 채택되지 않습니다.

with 스테이트먼트를 스코프 Import의 간단한 형태로 사용하고 있습니다.예를 들어 마크업 빌더 같은 것이 있다고 합시다.쓰는 대신:

markupbuilder.div(
  markupbuilder.p('Hi! I am a paragraph!',
    markupbuilder.span('I am a span inside a paragraph')
  )
)

대신 다음과 같이 쓸 수 있습니다.

with(markupbuilder){
  div(
    p('Hi! I am a paragraph!',
      span('I am a span inside a paragraph')
    )
  )
}

이 사용 예에서는 과제를 하지 않기 때문에 그에 따른 애매함 문제는 없습니다.

이전의 코멘트대로, 어떠한 상황에서도 안심하고 사용할 수 있다고는 생각하지 않습니다.이 문제는 여기서 직접 다루지 않기 때문에 다시 한 번 말씀드리겠습니다.다음 코드를 고려합니다.

user = {};
someFunctionThatDoesStuffToUser(user);
someOtherFunction(user);

with(user){
    name = 'Bob';
    age  = 20;
}

이러한 함수 호출을 주의 깊게 조사하지 않으면 이 코드가 실행된 후 프로그램 상태를 알 수 없습니다. ifuser.name되어 있습니다.이미설설설 now now now now now now now now now now now now now now로 하겠습니다.Bob있지 않은 「」의 「」의 「」name되거나 기 will will to to to to to to to to to로 됩니다.Bobuser는 오 a a a a a a a a object object object object object object object object 。name★★★★★★★★★★★★★★★★★★.

버그가 생기다.와 함께 사용하면 결과적으로 이 작업이 수행되고 프로그램이 실패할 가능성이 높아집니다.게다가 의도적으로 또는 작성자가 이 구성의 이 기호에 대해 알지 못하는 것을 통해 의 글로벌한 블록을 설정하는 작업 코드가 발생할 수 있습니다.이것은 스위치로 넘어지는 것과 매우 비슷합니다.작가가 의도한 것인지 아닌지는 알 수 없습니다.또, 코드를 「수정」하면, 회귀가 생기는지도 알 수 없습니다.

현대 프로그래밍 언어에는 기능이 가득합니다.일부 기능은 수년 동안 사용 후 불량으로 판명되므로 피해야 합니다.Javascript도 그 중 하나입니다.

는 실제로 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★를 발견했다.with최근 매우 유용하게 쓰이게 되었습니다.이 기술은 현재 프로젝트인 JavaScript로 작성된 명령줄 콘솔을 시작하기 전까지는 전혀 떠오르지 않았습니다.Firebug/WebKit 콘솔 API를 에뮬레이트하려고 했습니다.이 API에서는 특별한 명령어를 콘솔에 입력할 수 있지만 글로벌 스코프의 변수를 덮어쓰지는 않습니다.Shog9의 훌륭한 답변에 대한 댓글에서 언급했던 문제를 극복하려고 할 때 이런 생각을 했습니다.

이 효과를 얻기 위해 글로벌 스코프의 배후에 있는 스코프를 「레이어」하는 스테이트먼트를 2개 사용했습니다.

with (consoleCommands) {
    with (window) {
        eval(expression); 
    }
}

단점을 하고, with스테이트먼트는, 어쨌든 글로벌 스코프에서 평가되고 있기 때문에, 유사 데이터 이외의 변수가 수정될 위험은 없습니다.

놀랍게도, 다른 곳에서 사용되는 것과 같은 기술인 크롬 소스 코드를 발견했을 때, 저는 이 답을 올리도록 영감을 받았습니다!

InjectedScript._evaluateOn = function(evalFunction, object, expression) {
    InjectedScript._ensureCommandLineAPIInstalled();
    // Surround the expression in with statements to inject our command line API so that
    // the window object properties still take more precedent than our API functions.
    expression = "with (window._inspectorCommandLineAPI) { with (window) { " + expression + " } }";
    return evalFunction.call(object, expression);
}

편집: 방금 Firebug 소스를 확인했는데, 더 많은 레이어를 위해 스테이트먼트와 체인 4가 연결되어 있습니다.미쳤어!

const evalScript = "with (__win__.__scope__.vars) { with (__win__.__scope__.api) { with (__win__.__scope__.userVars) { with (__win__) {" +
    "try {" +
        "__win__.__scope__.callback(eval(__win__.__scope__.expr));" +
    "} catch (exc) {" +
        "__win__.__scope__.callback(exc, true);" +
    "}" +
"}}}}";

네, 네, 네.매우 정당한 용도가 있다.보기:

with (document.getElementById("blah").style) {
    background = "black";
    color = "blue";
    border = "1px solid green";
}

기본적으로 다른 모든 DOM 또는 CSS 후크는 와 함께 사용할 수 있습니다."CloneNode"가 정의되지 않고 글로벌 범위로 돌아가지는 않습니다. 단, 사용자가 이를 가능하게 하기로 결정하지 않는 한, "CloneNode는 정의되지 않고 글로벌 범위로 돌아갑니다.

크로크포드의 속도불만은 새로운 맥락이 와 함께 창조된다는 것이다.콘텍스트는 일반적으로 비용이 많이 듭니다.찬성합니다.단, div를 작성한 지 얼마 되지 않아 css를 설정하기 위한 프레임워크가 없고, 수동으로 15개 정도의 CSS 속성을 설정해야 하는 경우 콘텍스트를 작성하는 것이 변수 작성 및 15개의 derference보다 더 저렴할 수 있습니다.

var element = document.createElement("div"),
    elementStyle = element.style;

elementStyle.fontWeight = "bold";
elementStyle.fontSize = "1.5em";
elementStyle.color = "#55d";
elementStyle.marginLeft = "2px";

기타...

하면 '조금만 있으면 된다'의 수 .with다음 중 하나:

var with_ = function (obj, func) { func (obj); };

with_ (object_name_here, function (_)
{
    _.a = "foo";
    _.b = "bar";
});

다음을 수행할 수 있기 때문에 가치가 거의 없는 것 같습니다.

var o = incrediblyLongObjectNameThatNoOneWouldUse;
o.name = "Bob";
o.age = "50";

절대 사용하지 않고, 사용할 이유도 없고, 추천하지도 않습니다.

withECMAScript 구현이 수행할 수 있는 수많은 어휘 최적화를 방지하는 것입니다.빠른 JIT 기반의 엔진이 부상하고 있는 것을 고려하면, 이 문제는 가까운 장래에 더욱 중요해질 것입니다.

은 「 「 」라고 될 수 있습니다.with보다 깔끔한 구성(예를 들어 일반적인 익명 함수 래퍼 대신 새로운 스코프를 도입하거나 상세 에일리어싱을 대체하는 경우)을 사용할 수 있지만, 실제로는 그럴 가치가 없습니다.성능 저하 외에도 잘못된 개체의 속성에 할당되거나(삽입된 범위의 개체에서 속성을 찾을 수 없는 경우) 글로벌 변수가 잘못 유입될 위험이 항상 있습니다.IIRC, 후자 호가 크록포드에게 권고한 동기부여입니다with.

Visual Basic.에는, NET 가 있습니다.With제가 사용하는 가장 일반적인 방법 중 하나는 다수의 속성을 빠르게 설정하는 것입니다.★★★★

someObject.Foo = ''
someObject.Bar = ''
someObject.Baz = ''

, 쓸 수 있다:

With someObject
    .Foo = ''
    .Bar = ''
    .Baz = ''
End With

이것은 단지 게으름의 문제가 아니다.그것은 또한 훨씬 더 읽기 쉬운 코드를 만든다. JavaScript와는 을 받는 에 "JavaScript"를 프리픽스로 애매모호함을 ..두이 됩니다 (점) ㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴㄴ.

With someObject
    .Foo = ''
End With

대.

With someObject
    Foo = ''
End With

는 자자입니다.someObject.Foo는;;이다.Foo바깥의 범위 내에서 someObject.

JavaScript의 구별이 부족하기 때문에 모호성의 위험이 너무 높기 때문에 Visual Basic의 변형보다 훨씬 유용하지 않다는 것을 알게 되었습니다.외는 ★★★★★★★★★★★★★★★★★★.with가독성을 높일 수 있는 강력한 아이디어입니다.

나는 명백한 용도가 지름길이라고 생각한다.예를 들어 개체를 초기화하는 경우 "ObjectName"을 많이 입력하면 됩니다.lisp의 "슬롯이 있는" 처럼요.

(with-slots (foo bar) objectname
   "some code that accesses foo and bar"

그것은 글쓰기와 같다.

"some code that accesses (slot-value objectname 'foo) and (slot-value objectname 'bar)""

언어가 "Objectname"을 허용하는 경우보다 이것이 왜 바로 가기인지 더 명확합니다.'푸우' 하지만 여전히.

하시면 됩니다.with작은 템플릿 엔진을 사용하는 것처럼 객체의 내용을 블록에 로컬 변수로 도입합니다.

"with"를 사용하면 코드가 더 건조해질 수 있습니다.

다음 코드를 고려합니다.

var photo = document.getElementById('photo');
photo.style.position = 'absolute';
photo.style.left = '10px';
photo.style.top = '10px';

다음과 같이 건조할 수 있습니다.

with(document.getElementById('photo').style) {
  position = 'absolute';
  left = '10px';
  top = '10px';
}

당신이 읽기 쉬운 것을 좋아하는지 표현하기 쉬운 것을 좋아하는지에 따라 다르다고 생각합니다.

첫 번째 예는 읽기 쉽고 대부분의 코드에 권장됩니다.하지만 어쨌든 대부분의 코드는 꽤 길들여져 있다.두 번째는 좀 더 모호하지만 언어의 표현성을 사용하여 코드 크기와 불필요한 변수를 줄입니다.

자바나 C#을 좋아하는 사람은 첫 번째 방법(object.member)을 선택하고, 루비나 파이썬을 좋아하는 사람은 후자를 선택할 것이라고 생각합니다.

Delphi를 사용해 본 경험이 있기 때문에, 와 함께 사용하는 것은 마지막 크기 최적화이며, 안전성을 검증하기 위해 정적 코드 해석에 액세스 할 수 있는 자바스크립트 미니마이저 알고리즘일 가능성이 있다고 생각합니다.

a**에서는 자유롭게 스테이트먼트를 사용하여 스코핑할 수 있는 문제가 왕실의 문제가 될 수 있습니다.또, 디버깅 세션을 실시해, 그 문제를 특정하는 일은 하고 싶지 않습니다.코드 내에서 진행 중인데 의도한 전역 또는 외부 범위 변수가 아닌 오브젝트멤버 또는 잘못된 로컬 변수를 캡처한 것을 알 수 있습니다.

스테이트먼트가 있는 VB는 스코핑을 명확하게 하기 위해 점이 필요하다는 점에서 더 좋지만 스테이트먼트가 있는 델파이는 헤어트리거가 있는 장전된 총이며, javascript는 같은 경고를 받을 수 있을 만큼 충분히 유사한 것으로 보입니다.

와의 사용은 권장되지 않으며 ECMAScript 5 strict 모드에서는 금지됩니다.또는 속성을 가진 개체를 임시 변수에 할당하는 것이 좋습니다.

출처 : Mozilla.org

with 문은 코드사이즈를 줄이거나 프라이빗클래스 멤버의 경우 다음과 같이 사용할 수 있습니다.

// demo class framework
var Class= function(name, o) {
   var c=function(){};
   if( o.hasOwnProperty("constructor") ) {
       c= o.constructor;
   }
   delete o["constructor"];
   delete o["prototype"];
   c.prototype= {};
   for( var k in o ) c.prototype[k]= o[k];
   c.scope= Class.scope;
   c.scope.Class= c;
   c.Name= name;
   return c;
}
Class.newScope= function() {
    Class.scope= {};
    Class.scope.Scope= Class.scope;
    return Class.scope;
}

// create a new class
with( Class.newScope() ) {
   window.Foo= Class("Foo",{
      test: function() {
          alert( Class.Name );
      }
   });
}
(new Foo()).test();

with-statement는 실행 시 조작할 수 있는 독자적인 글로벌스코프를 보유하기 위해 필요한 범위를 변경하는 경우에 매우 유용합니다.상수 또는 자주 사용되는 특정 도우미 함수를 추가할 수 있습니다."상위", "하위", "isNumber", "clipNumber" aso..

나쁜 퍼포먼스에 대해서는 자주 읽습니다.함수의 범위를 지정해도 퍼포먼스에 영향을 주지 않습니다.실제로 FF에서는 범위 지정 함수가 범위 지정되지 않은 함수에 비해 더 빨리 실행됩니다.

var o={x: 5},r, fnRAW= function(a,b){ return a*b; }, fnScoped, s, e, i;
with( o ) {
    fnScoped= function(a,b){ return a*b; };
}

s= Date.now();
r= 0;
for( i=0; i < 1000000; i++ ) {
    r+= fnRAW(i,i);
}
e= Date.now();
console.log( (e-s)+"ms" );

s= Date.now();
r= 0;
for( i=0; i < 1000000; i++ ) {
    r+= fnScoped(i,i);
}
e= Date.now();
console.log( (e-s)+"ms" );

따라서 위에서 설명한 방법으로 with-statement를 사용하면 퍼포먼스에 부정적인 영향을 주지 않지만 코드 크기를 줄이면 모바일 디바이스의 메모리 사용량에 영향을 미칩니다.

와 함께 사용하면 많은 구현에서 코드가 느려집니다. 이제 모든 것이 검색의 추가 범위에 포함되기 때문입니다.JavaScript에서 를 사용하는 정당한 이유는 없습니다.

템플릿 언어를 JavaScript로 변환할 때 with-statement가 편리하다고 생각합니다.를 들어 Base2의 JST는 자주 볼 수 있습니다.

설명 없이 프로그래밍할 수 있다는 것에 동의합니다.하지만 아무런 문제가 없기 때문에 그것은 합법적인 사용이다.

비교적 복잡한 환경에서 실행되는 코드를 컨테이너에 넣는 데 유용합니다."윈도"의 로컬 바인딩을 만들고 웹 브라우저용 코드를 실행하기 위해 사용합니다.

오브젝트 리터럴 사용이 흥미롭다고 생각합니다.마치 클로저를 사용하기 위한 드롭인 치환과 같습니다.

for(var i = nodes.length; i--;)
{
       // info is namespaced in a closure the click handler can access!
       (function(info)
       {           
            nodes[i].onclick = function(){ showStuff(info) };
       })(data[i]);
}

또는 with the statement for closure(종료에 대한 애매한 진술)

for(var i = nodes.length; i--;)
{
       // info is namespaced in a closure the click handler can access!
       with({info: data[i]})
       {           
            nodes[i].onclick = function(){ showStuff(info) };
       }        
}

실제 위험은 실수로 with 스테이트먼트의 일부가 아닌 변수를 축소하는 것이라고 생각합니다.그래서 오브젝트 리터럴이 전달되는 것을 좋아합니다.코드의 추가된 컨텍스트에서 정확히 무엇을 할 수 있는지 알 수 있습니다.

'.with★★★★★★★★

if (typeof Object.merge !== 'function') {
    Object.merge = function (o1, o2) { // Function to merge all of the properties from one object into another
        for(var i in o2) { o1[i] = o2[i]; }
        return o1;
    };
}

와 마찬가지로 사용할 수 있습니다.with하지만 제가 의도하지 않은 범위에는 영향을 미치지 않는다는 것을 알 수 있습니다.

사용방법:

var eDiv = document.createElement("div");
var eHeader = Object.merge(eDiv.cloneNode(false), {className: "header", onclick: function(){ alert("Click!"); }});
function NewObj() {
    Object.merge(this, {size: 4096, initDate: new Date()});
}

조각의 , 저는 .sin,cos사사모모모모닌닌등등등등등등등등등등등 。위해 저는 '아예', '아예', '아예'를 합니다.AngularDegree " " 젝 object : " :

AngularDegree = new function() {
this.CONV = Math.PI / 180;
this.sin = function(x) { return Math.sin( x * this.CONV ) };
this.cos = function(x) { return Math.cos( x * this.CONV ) };
this.tan = function(x) { return Math.tan( x * this.CONV ) };
this.asin = function(x) { return Math.asin( x ) / this.CONV };
this.acos = function(x) { return Math.acos( x ) / this.CONV };
this.atan = function(x) { return Math.atan( x ) / this.CONV };
this.atan2 = function(x,y) { return Math.atan2(x,y) / this.CONV };
};

더 도할 수 .with 블::

function getAzimut(pol,pos) {
  ...
  var d = pos.lon - pol.lon;
  with(AngularDegree) {
    var z = atan2( sin(d), cos(pol.lat)*tan(pos.lat) - sin(pol.lat)*cos(d) );
    return z;
    }
  }

이것은 다음을 의미합니다.오브젝트를 함수의 집합으로 사용하고 있으며, 이를 제한된 코드 영역에서 직접 액세스할 수 있습니다.난 이게 유용하다고 생각해.

는 의은의 이 있다고 한다.with코드가 얼마나 잘 쓰여져 있는지에 따라 달라질 수 있습니다.예를 들어, 다음과 같이 표시되는 코드를 쓰는 경우:

var sHeader = object.data.header.toString();
var sContent = object.data.content.toString();
var sFooter = object.data.footer.toString();

따질 수 요.with에서는 다음과같이 시킵니다.

var sHeader = null, sContent = null, sFooter = null;
with(object.data) {
    sHeader = header.toString();
    sContent = content.toString();
    sFooter = content.toString();
}

반대로, 당신이 디메터의 법칙을 위반하고 있다고 주장될 수 있지만, 다시 말하지만, 아닐 수도 있습니다.=)를 꺼냅니다.

무엇보다도 더글라스 크록포드는 이 제품을 사용하지 말 것을 권장합니다.withwith대안을 제시합니다.

object.member를 입력하는 것보다 를 와 함께 사용하는 것이 더 읽기 쉽다고는 생각되지 않습니다.가독성은 떨어지지만, 더 이상 읽을 수 있는 것도 아닌 것 같아요.

lassevk가 말했듯이 object.member 구문을 사용하는 것보다 와 함께 사용하는 것이 오류 발생 가능성이 높다는 것을 알 수 있습니다.

javascript의 폼 검증은 W3schools http://www.w3schools.com/js/js_form_validation.asp에서 확인할 수 있습니다.여기서 오브젝트 폼은 "mail"로 되어 있습니다.

그러나 폼의 필드 이름이나 수량에 관계없이 모든 필드가 비어 있지 않은 것으로 확인되도록 수정했습니다.텍스트 필드만 테스트했습니다.

그러나 with()를 사용하면 일이 간단해집니다.코드는 다음과 같습니다.

function validate_required(field)
{
with (field)
  {
  if (value==null||value=="")
    {
    alert('All fields are mandtory');return false;
    }
  else
    {
    return true;
    }
  }
}

function validate_form(thisform)
{
with (thisform)
  {
    for(fiie in elements){
        if (validate_required(elements[fiie])==false){
            elements[fiie].focus();
            elements[fiie].style.border='1px solid red';
            return false;
        } else {elements[fiie].style.border='1px solid #7F9DB9';}
    }

  }
  return false;
}

CoffeeScript의 Coco 포크는with 「이러다」를 만 하면 됩니다.this (기입 가능))@CoffeeScript/Coco)를 사용합니다.이것에 의해, 애매함이 해소되어 ES5 완전 모드의 준거가 실현됩니다.

with long.object.reference
  @a = 'foo'
  bar = @b

나의

switch(e.type) {
    case gapi.drive.realtime.ErrorType.TOKEN_REFRESH_REQUIRED: blah
    case gapi.drive.realtime.ErrorType.CLIENT_ERROR: blah
    case gapi.drive.realtime.ErrorType.NOT_FOUND: blah
}

결론부터 말하면.

with(gapi.drive.realtime.ErrorType) {switch(e.type) {
    case TOKEN_REFRESH_REQUIRED: blah
    case CLIENT_ERROR: blah
    case NOT_FOUND: blah
}}

그렇게 질이 낮은 코드를 믿을 수 있나요?아뇨, 전혀 읽을 수 없게 만들어졌군요이 예에서는 가독성을 중시하고 있는 경우에는 with-statement가 필요없음을 부인할 수 없습니다.

프록시 개체와 함께 "with" 문 사용

최근에 매크로를 사용할 수 있는 babel용 플러그인을 쓰고 싶습니다.매크로 변수를 유지하는 별도의 변수 네임스페이스를 가지고 그 공간에서 매크로 코드를 실행할 수 있도록 하고 싶습니다.또, 매크로 코드에 정의되고 있는 새로운 변수(새로운 매크로이기 때문에)를 검출하고 싶다.

먼저 VM 모듈을 선택했는데 어레이, 오브젝트 등의 VM 모듈의 글로벌 변수가 메인 프로그램과 달라 구현할 수 없습니다.module ★★★★★★★★★★★★★★★★★」require(핵심 모듈을 재구성할 수 없기 때문에) 글로벌 객체와 완전히 호환됩니다.함께하다

const runInContext = function(code, context) {
    context.global = context;
    const proxyOfContext = new Proxy(context, { has: () => true });
    let run = new Function(
        "proxyOfContext",
        `
            with(proxyOfContext){
                with(global){
                        ${code}
                }
            }
        `
    );
    return run(proxyOfContext);
};

는 모든 과 같이 말합니다"Ivariable." 해당 을 "Yes, I have that variable"로 표시합니다 프록시 객체에 실제로 해당 변수가 없는 경우 값을 다음과 같이 표시합니다.undefined.

되어 있는 codevar스테이트먼트. 컨텍스트 오브젝트(VM 모듈 등)에서 찾을 수 있습니다., 되어 있는 는 but음음으로 정의되어 있습니다.let ★★★★★★★★★★★★★★★★★」const해당 시간에만 사용할 수 있으며 컨텍스트 개체에 저장되지 않습니다(VM 모듈이 저장하지만 노출되지 않음).

퍼포먼스: 이 방법의 퍼포먼스는vm.runInContext.

safety: 샌드박스에서 코드를 실행하려면 안전하지 않으므로 vm 모듈을 사용해야 합니다.새 네임스페이스만 제공합니다.

좋은 .with새이 값은 오브젝트에 오브젝트 리터럴에 새 요소를 추가합니다.이 오브젝트에 저장된 값을 기반으로 합니다.하다

사용할 수 있는 타일 세트(위, 아래, 왼쪽 또는 오른쪽 개구부)가 있었고, 게임 시작 시 항상 배치하고 잠글 수 있는 타일 목록을 빠르게 추가하고 싶었습니다. 입력하기요.types.tbr각 in른 른른른른 른른 른른 른른 른른 른른 른른 른 for 른 for for for for for for for for for for for for for for for 。with.

Tile.types = (function(t,l,b,r) {
  function j(a) { return a.join(' '); }
  // all possible types
  var types = { 
    br:  j(  [b,r]),
    lbr: j([l,b,r]),
    lb:  j([l,b]  ),  
    tbr: j([t,b,r]),
    tbl: j([t,b,l]),
    tlr: j([t,l,r]),
    tr:  j([t,r]  ),  
    tl:  j([t,l]  ),  
    locked: []
  };  
  // store starting (base/locked) tiles in types.locked
  with( types ) { locked = [ 
    br,  lbr, lbr, lb, 
    tbr, tbr, lbr, tbl,
    tbr, tlr, tbl, tbl,
    tr,  tlr, tlr, tl
  ] } 
  return types;
})("top","left","bottom","right");

와 같이 Andy E shog Shog9을 사용할 때 치 않은 동작이 할 수 .with★★★★★★★★★★★★★★★★★★★:

for (var i = 0; i < 3; i++) {
  function toString() {
    return 'a';
  }
  with ({num: i}) {
    setTimeout(function() { console.log(num); }, 10);
    console.log(toString()); // prints "[object Object]"
  }
}

그 돌발적인 행동이 이미 이 사건의 특징이 아니었던 은 아니다with.

이 기술을 계속 사용하려면 적어도 Null 프로토타입이 있는 개체를 사용하십시오.

function scope(o) {
  var ret = Object.create(null);
  if (typeof o !== 'object') return ret;
  Object.keys(o).forEach(function (key) {
    ret[key] = o[key];
  });
  return ret;
}

for (var i = 0; i < 3; i++) {
  function toString() {
    return 'a';
  }
  with (scope({num: i})) {
    setTimeout(function() { console.log(num); }, 10);
    console.log(toString()); // prints "a"
  }
}

ES5+로 하다, 이 경우는 사용하지.with.

저는 애플리케이션 일부의 동작을 수정하기 위해 사용자가 코드를 업로드 할 수 있는 프로젝트를 진행하고 있습니다. 시나리오에서는, 「 」를 .with코드를 수정하지 않도록 하기 위한 조항입니다.이를 위해 사용하는 코드의 (간소화된) 부분은 다음과 같습니다.

// this code is only executed once
var localScope = {
    build: undefined,

    // this is where all of the values I want to hide go; the list is rather long
    window: undefined,
    console: undefined,
    ...
};
with(localScope) {
    build = function(userCode) {
        eval('var builtFunction = function(options) {' + userCode + '}');
        return builtFunction;
    }
}
var build = localScope.build;
delete localScope.build;

// this is how I use the build method
var userCode = 'return "Hello, World!";';
var userFunction = build(userCode);

를 사용하면 가 " " " "와 같이 오브젝트에 수 window어떤 지역 변수에도 접근할 수 없습니다.

현명한 분들에게 한마디로, 사용자가 제출한 코드에 대해 정적 코드 체크를 수행하여 글로벌 스코프에 접근하기 위해 다른 교활한 방법을 사용하지 않도록 해야 합니다.를 들어, 정의 는 for를, 음음음음음음 to to to to에 합니다.window:

test = function() {
     return this.window
};
return test();

언급URL : https://stackoverflow.com/questions/61552/are-there-legitimate-uses-for-javascripts-with-statement