Nice programing

JavaScript의 "새"키워드가 유해한 것으로 간주됩니까?

nicepro 2020. 10. 3. 11:47
반응형

JavaScript의 "새"키워드가 유해한 것으로 간주됩니까? [닫은]


또 다른 질문 에서 사용자는 new키워드가 사용하기에 위험하다고 지적하고 사용하지 않는 객체 생성에 대한 해결책을 제안했습니다 new. 저는 그것이 사실이라고 믿지 않았습니다. 대부분 제가 Prototype, Scriptaculous 및 기타 우수한 JavaScript 라이브러리를 사용했고 그들 모두가 new키워드를 사용했기 때문 입니다.

그럼에도 불구하고 어제 YUI 극장에서 Douglas Crockford의 강연을보고 있었는데, 그는 new코드에서 더 이상 키워드를 사용하지 않았다고 똑같은 말 을했습니다. ( Crockford on JavaScript-Act III : Function the Ultimate-50:23 분 ).

new키워드 를 사용하는 것이 '나쁜' 가요? 사용의 장점과 단점은 무엇입니까?


Crockford는 좋은 JavaScript 기술을 대중화하기 위해 많은 일을했습니다. 언어의 핵심 요소에 대한 그의 견해는 많은 유용한 토론을 불러 일으켰습니다. 즉, "나쁘다"또는 "유해하다"고 선언 할 때마다 한 사람의 의견 이상을 보지 않으려는 사람들이 너무 많습니다. 때때로 약간 실망 스러울 수 있습니다.

new키워드에서 제공하는 기능을 사용하면 처음부터 각 개체를 빌드하는 것보다 몇 가지 장점이 있습니다.

  1. 프로토 타입 상속 . 클래스 기반 OO 언어에 익숙한 사람들이 종종 의심과 조롱을 혼합하여 보지만 JavaScript의 기본 상속 기술은 간단하고 놀랍도록 효과적인 코드 재사용 수단입니다. 그리고 새로운 키워드는이를 사용하는 표준 (그리고 크로스 플랫폼에서만 사용 가능한) 수단입니다.
  2. 공연. 이것은 # 1의 부작용입니다 : 내가 작성하는 모든 객체에 10 가지 방법을 추가 할 경우, 내가 단지 수동으로 각각의 새로운 객체에 각각의 방법을 지정하는 생성 기능을 쓰기 또는 난에 할당 할 수 생성 기능 prototype과 사용 new하여 새 개체를 스탬프 처리합니다. 이 방법이 더 빠를뿐만 아니라 (프로토 타입의 모든 메서드에 대해 코드가 필요하지 않음), 각 메서드에 대해 별도의 속성을 사용하여 각 개체의 풍선을 피할 수 있습니다. 느린 시스템 (특히 느린 JS 인터프리터)에서 많은 객체가 생성 될 때 이는 시간과 메모리를 크게 절약 할 수 있음을 의미합니다.

그리고 예, new다른 답변에서 잘 설명하는 한 가지 중요한 단점이 있습니다. 사용하는 것을 잊으면 경고없이 코드가 손상됩니다. 다행히도이 단점은 쉽게 완화됩니다. 함수 자체에 약간의 코드를 추가하기 만하면됩니다.

function foo()
{
   // if user accidentally omits the new keyword, this will 
   // silently correct the problem...
   if ( !(this instanceof foo) )
      return new foo();

   // constructor logic follows...
}

이제 new실수로 인한 오용으로 인한 문제에 대해 걱정할 필요없이 의 이점을 누릴 수 있습니다 . 깨진 코드가 조용히 작동한다는 생각이 당신을 괴롭히는 경우 검사에 어설 션을 추가 할 수도 있습니다. 또는 일부 언급했듯이 점검을 사용하여 런타임 예외를 도입하십시오.

if ( !(this instanceof arguments.callee) ) 
   throw new Error("Constructor called as a function");

(이 스 니펫은 이전 예제와 달리 실제로 객체를 인스턴스화 할 필요가 없기 때문에 생성자 함수 이름을 하드 코딩하는 것을 피할 수 있습니다. 따라서 수정없이 각 대상 함수에 복사 할 수 있습니다.)

John Resig는 간단한 "클래스"인스턴스화 게시물 에서이 기술에 대해 자세히 설명 하고 기본적으로이 동작을 "클래스"에 빌드하는 방법을 포함합니다. 확실히 가치가 읽기 ... 그의 곧 책이기 때문에 자바 스크립트 닌자의 비밀 이 많은 다른 "유해한"금을 숨겨 발견 자바 스크립트 언어의 기능을합니다 ( with, 특히 우리의 사람들을 위해 계몽이 처음 기각 사람 이 악의적 인 기능은 기믹으로).


그의 Crockfords 책 "Javascript : The Good Parts"의 일부를 방금 읽었습니다. 나는 그가 그를 물린 모든 것을 해로운 것으로 여기는 느낌을 받는다.

스위치 폴 스루 정보 :

나는 스위치 케이스가 다음 케이스로 넘어가는 것을 결코 허용하지 않습니다. 나는 왜 쓰러지는 것이 때때로 유용한 지에 대한 격렬한 연설을 한 직후 의도하지 않은 쓰러짐으로 인한 내 코드에서 버그를 발견했습니다. (97 쪽, ISBN 978-0-596-51774-8)

++ 및-

++ (증가) 및-(감소) 연산자는 exessive 속임수를 조장하여 잘못된 코드에 기여하는 것으로 알려져 있습니다. 그들은 바이러스 및 기타 보안 위협을 가능하게하는 결함있는 아키텍처에 이어 두 번째입니다. (122 쪽)

새로운 정보 :

당신은 포함시키지 않으면 생성자 함수를 호출 할 때 접두사를, 다음 이이 새 개체에 바인딩되지 않습니다. 슬프게도 이것은 전역 개체에 바인딩되므로 새 개체를 늘리는 대신 전역 변수를 뭉개지게 할 것입니다. 정말 나쁘다. 컴파일 경고가없고 런타임 경고가 없습니다. (49 쪽)

더 많이 있지만 사진을 얻으시기 바랍니다.

귀하의 질문에 대한 나의 대답 : 아니오, 그것은 해롭지 않습니다. 그러나 당신이 그것을 사용해야 할 때 그것을 사용하는 것을 잊으면 몇 가지 문제가 생길 수 있습니다. 좋은 환경에서 개발하고 있다면 그것을 알 수 있습니다.

최신 정보

About a year after this answer was written the 5th edition of ECMAScript was released, with support for strict mode. In strict mode, this is no longer bound to the global object but to undefined.


Javascript being dynamic language there a zillion ways to mess up where another language would stop you.

Avoiding a fundamental language feature such as new on the basis that you might mess up is a bit like removing your shiny new shoes before walking through a minefield just in case you might get your shoes muddy.

I use a convention where function names begin with a lower case letter and 'functions' that are actually class definitions begin with a upper case letter. The result is a really quite compelling visual clue that the 'syntax' is wrong:-

var o = MyClass();  // this is clearly wrong.

On top of this good naming habits help. After all functions do things and therefore there should be a verb in its name whereas classes represent objects and are nouns and adjectives with no verb.

var o = chair() // Executing chair is daft.
var o = createChair() // makes sense.

Its interesting how SO's syntax colouring has interpretted the code above.


I am newbie to Javascript so maybe I am just not too experienced in providing a good view point to this. Yet I want to share my view on this "new" thing.

I have come from the C# world where using the keyword "new" is so natural that it is the factory design pattern that looks weird to me.

When I first code in Javascript, I don't realize that there is the "new" keyword and code like the one in YUI pattern and it doesn't take me long to run into disaster. I lose track of what a particular line is supposed to be doing when looking back the code I've written. More chaotic is that my mind can't really transit between object instances boundaries when I am "dry-running" the code.

Then, I found the "new" keyword which to me, it "separate" things. With the new keyword, it creates things. Without the new keyword, I know I won't confuse it with creating things unless the function I am invoking gives me strong clues of that.

For instance, with var bar=foo(); I have no clues as what bar could possibly be.... Is it a return value or is it a newly created object? But with var bar = new foo(); I know for sure bar is an object.


Another case for new is what I call Pooh Coding. Winnie the Pooh follows his tummy. I say go with the language you are using, not against it.

Chances are that the maintainers of the language will optimize the language for the idioms they try to encourage. If they put a new keyword into the language they probably think it makes sense to be clear when creating a new instance.

Code written following the language's intentions will increase in efficiency with each release. And code avoiding the key constructs of the language will suffer with time.

EDIT: And this goes well beyond performance. I can't count the times I've heard (or said) "why the hell did they do that?" when finding strange looking code. It often turns out that at the time when the code was written there was some "good" reason for it. Following the Tao of the language is your best insurance for not having your code ridiculed some years from now.


I wrote a post on how to mitigate the problem of calling a constructor without the new keyword.
It's mostly didactic, but it shows how you can create constructors that work with or without new and doesn't require you to add boilerplate code to test this in every constructor.

http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html

Here's the gist of the technique:

/**
 * Wraps the passed in constructor so it works with
 * or without the new keyword
 * @param {Function} realCtor The constructor function.
 *    Note that this is going to be wrapped
 *    and should not be used directly 
 */
function ctor(realCtor){
  // This is going to be the actual constructor
  return function wrapperCtor(){
    var obj; // object that will be created
    if (this instanceof wrapperCtor) {
      // Called with new
      obj = this;
    } else {
      // Called without new. Create an empty object of the
      // correct type without running that constructor
      surrogateCtor.prototype = wrapperCtor.prototype;
      obj = new surrogateCtor();
    }
    // Call the real constructor function
    realCtor.apply(obj, arguments);
    return obj;
  }

  function surrogateCtor() {}
}

Here's how to use it:

// Create our point constructor
Point = ctor(function(x,y){
  this.x = x;
  this.y = y;
});

// This is good
var pt = new Point(20,30);
// This is OK also
var pt2 = Point(20,30);

The rationale behind not using the new keyword, is simple:

By not using it at all, you avoid the pitfall that comes with accidentally omitting it. The construction pattern that YUI uses, is an example of how you can avoid the new keyword altogether"

var foo = function () {
    var pub= { };
    return pub;
}
var bar = foo();

Alternatively you could so this:

function foo() { }
var bar = new foo();

But by doing so you run risk of someone forgetting to use the new keyword, and the this operator being all fubar. AFAIK there is no advantage to doing this (other than you are used to it).

At The End Of The Day: It's about being defensive. Can you use the new statement? Yes. Does it make your code more dangerous? Yes.

If you have ever written C++, it's akin to setting pointers to NULL after you delete them.


I think "new" adds clarity to the code. And clarity is worth everything. Good to know there are pitfalls, but avoiding them by avoiding clarity doesn't seem like the way for me.


Case 1: new isn't required and should be avoided

var str = new String('asd');  // type: object
var str = String('asd');      // type: string

var num = new Number(12);     // type: object
var num = Number(12);         // type: number

Case 2: new is required, otherwise you'll get an error

new Date().getFullYear();     // correct, returns the current year, i.e. 2010
Date().getFullYear();         // invalid, returns an error

Here is the briefest summary I could make of the two strongest arguments for and against using the new operator:

Argument against new

  1. Functions designed to be instantiated as objects using the new operator can have disastrous effects if they are incorrectly invoked as normal functions. A function's code in such a case will be executed in the scope where the function is called, instead of in the scope of a local object as intended. This can cause global variables and properties to get overwritten with disastrous consequences.
  2. Finally, writing function Func(), and then calling Func.prototype and adding stuff to it so that you can call new Func() to construct your object seems ugly to some programmers, who would rather use another style of object inheritance for architectural and stylistic reasons.

For more on this argument check out Douglas Crockford's great and concise book Javascript: The Good Parts. In fact check it out anyway.

Argument in favor of new

  1. Using the new operator along with prototypal assignment is fast.
  2. That stuff about accidentally running a constructor function's code in the global namespace can easily be prevented if you always include a bit of code in your constructor functions to check to see if they are being called correctly, and, in the cases where they aren't, handling the call appropriately as desired.

See John Resig's post for a simple explanation of this technique, and for a generally deeper explanation of the inheritance model he advocates.


I agree with pez and some here.

It seems obvious to me that "new" is self descriptive object creation, where the YUI pattern Greg Dean describes is completely obscured.

The possibility someone could write var bar = foo; or var bar = baz(); where baz isn't an object creating method seems far more dangerous.


I think new is evil, not because if you forget to use it by mistake it might cause problems but because it screws up the inheritance chain, making the language tougher to understand.

JavaScript is prototype-based object-oriented. Hence every object MUST be created from another object like so var newObj=Object.create(oldObj). Here oldObj is called the prototype of newObj (hence "prototype-based"). This implies that if a property is not found in newObj then it will be searched in oldObj. newObj by default will thus be an empty object but due to its prototype chain it appears to have all the values of oldObj.

On the other hand if you do var newObj=new oldObj(), the prototype of newObj is oldObj.prototype, which is unnecessarily difficult to understand.

The trick is to use

Object.create=function(proto){
  var F = function(){};
  F.prototype = proto;
  var instance = new F();
  return instance;
};

It is inside this function and only here that new should be used. After this simply use the Object.create() method. The method resolves the prototype problem.

참고URL : https://stackoverflow.com/questions/383402/is-javascripts-new-keyword-considered-harmful

반응형