ProgramingTip

JavaScript : 좋은 부분 -`new`를 전혀 사용하지 않는 방법

bestdevel 2020. 12. 25. 10:29
반응형

JavaScript : 좋은 부분 -`new`를 전혀 사용하지 않는 방법


크록 포드의 저서 자바 스크립트 : 좋은 부품 에서는 생성자 함수에는 항상 초기 대문자 (예 : 포인트) 이름을 지정로해야 우리하며 초기 대문자로 된 함수 이름 은 생성자 함수 에서만 사용해야 한다고 말합니다 (114 페이지) . 나머지는 모두 lowerCase 택합니다).

이 규칙은 생성자 new함수와 함께 연산자 를 사용하는 것을 잊지 않도록 도와줍니다 .

"이라고 계속해서 "더 나은 전략은 전혀 사용하지 않는 것 new입니다.

내 질문은 전혀 사용하지 않고 JavaScript를 어떻게 사용하지 new않습니까?

  • 우리는 피할 수 new Object()new Array()리터럴로 {}[].
  • 우리는 피할 수 new Number(), new Boolean()new String()0, true''.
  • 우리는 new RegExp()같은 것을 피할 수 있습니다 /pattern/.

우리는 어떻게 피 new Date()가?

그리고 가장 중요한 것은 new자체 사용하는 방법 입니다.


Crockford는 http://developer.yahoo.com/yui/theater/에서 사용할 수있는 Javascript 강연 중 하나에서 JS 자체가 제공해야하는 생성 기능에 대한 예제를 제공합니다.

YUI (3) 팀 자체는 "new"를 사용하고 그의 권장 사항을 준수하고 있습니다 (그는 Yahoo의 최고 JS 설계자이기 때문에 (업데이트 : 계속 진행했지만 답변이 아직 작성되지 않았습니다.) .이 문제는 "학문"수준에 더 가깝다는 것입니다. 언어가 "올바"설계 되었어야만하고 기반 항목의 일부가 남아 있습니다. 그는 (IMHO가) 결과가 나왔다고 관계됩니다. 충돌하고 복합 기반이지만 "클래식 클래스"상속 언어에서 것입니다.

그러나 JS는 "new"를 사용하십시오.

그의 생성 기능은 http://javascript.crockford.com/prototypal.html 에서 사용할 수 있습니다.

 if (typeof Object.create !== 'function') {
     Object.create = function (o) {
         function F() {}
         F.prototype = o;
         return new F();
     };
 }
 newObject = Object.create(oldObject);


편집 : 기능의 Crockford 최신 버전을 사용하도록 업데이트되었습니다. 세 가지가 있습니다.


2015 년 6 월 업데이트 : 현재 모든 브라우저가 지원하는 (IE 9 이상 포함) 꽤 오랫동안 사용했기 때문에 크록 포드의 기능을 사용할 필요가 없었습니다.Object.create(...)

그러나 , 당신이 사용 Object.create한다면 그렇게 많이 사용하지 않아야합니다 : 그 기능은 사용하는 것보다 훨씬 느립니다 new Constructor()!

설명 http://mrale.ph/blog/2014/07/30/constructor-vs-objectcreate.html(V8 엔진의 경우)을 참조하고 http://jsperf.com/object-create-vs-를 참조 보강. 성능 테스트 용 crockford-vs-jorge-vs-constructor / 62

에 허리를 돌리지하는 또 다른 이유는 new Constructor(...)것입니다 ES6 클래스는 반드시 간단한 대부분의 자바 펼치기 개발자는 클래스 기반 언어에서 오는 경우에도 많은 것을 볼 수 있습니다.

또한 주장이 문서 체크 아웃 을 위해 Object.create : http://davidwalsh.name/javascript-objects-deconstruction를

좋든 싫든, 특히 다양한 사람들과 공유하고 싶은 프로젝트 (공간과 시간에 따라-시간이 지남에 따라 다른 사람들이 당신을 대신하는 것을 의미 함)에는 new.

2015 년 9 월 업데이트 : 나 자신을 위해 io.js 및 / 또는 바벨을 사용하여 모든 것에 ES 2015 자바 스크립트를 사용하기 시작했습니다. 나는 또한 사용하지 않는 모든 new 자바 펼쳐가를 제외하고 내 프로젝트를 내장 기능이 좋아 new Error(...)합니다. 나는 훨씬 더 강력한 기능적 접근 방식을 선호하고 시스템을 완전히 무시합니다. [my-object].prototype그리고 this완전히 내 프로젝트에서 사라졌다. 오랫동안 나는 "객체가 잘 작동하기 때문에"라는 아이디어에 대해 매우 회의적이었습니다. 그러나 새로운 (io.js) 시작할 때 매우 마지 못해 시도한 후 "클릭"왜 20 년을 사용할 수 없습니다. 좋아, 정답은 누구든지 JS 엔진과 하드웨어는 그 스타일에 훨씬 더 도움이됩니다. 특히 ES 2015에서는 thisclass(새로운 ES 2015 키워드 또는 사용에 따른 전체 개념 constructorFn.prototype) 시도. "클릭"하면 자발적으로 다시 돌아 가지 보장 고 약속합니다. 훨씬 더 강력하고 강력합니다.

2018 년 2 월 업데이트 : 이전 업데이트에서 작성한 작업을 수행하는 동안 가끔 수업이 괜찮다는 점을 추가하고 싶습니다 . 절대적인 것은 없습니다. :-)


나는 피하는 방법 new Date()또는 new XMLHttpRequest()둘 중 하나 하나 . 그러나 나는 내 유형에 대해 새로운 것을 사용하지 않는 방법을 알고 있습니다.

먼저 Object.create(). 이 ES5 방법은 모든 곳에서 사용할 수 있습니다. es5-shim , 광고를 사용하여 추가합니다 .

저는 모듈 패턴이 마음에 들어서 자체 실행 익명 함수 인 var Xyz = (function() {...})(). 즉, 전역 네임 스페이스를 엉망으로 만들지 않고 작업 할 수있는 개인 공간이 있습니다. create()함수와 prototype속성이 있는 객체를 반환합니다 . create()기능은 내 유형의 사용자를위한 것입니다. 원하는 경우를 호출 Xyz.create()하고 내 유형의 초기화 된 새 객체를 반환합니다. prototype사람들이 상속 할 경우 속성을 사용할 수 있습니다.

예를 들면 다음과 같습니다.

var Vehicle = (function(){
        var exports = {};
        exports.prototype = {};
        exports.prototype.init = function() {
                this.mph = 5;
        };
        exports.prototype.go = function() {
                console.log("Going " + this.mph.toString() + " mph.");
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports;
})();

상속은 다음과 가변합니다.

var Car = (function () {
        var exports = {};
        exports.prototype = Object.create(Vehicle.prototype);
        exports.prototype.init = function() {
                Vehicle.prototype.init.apply(this, arguments);
                this.wheels = 4;
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports; 

})();

newCrockford를 사용하지 않고 맹목적으로 따르는 것은 어리 석습니다.

JavaScript를 이해하고 좋은 코드를 작성하십시오. new키워드 사용 은 JavaScript OO 초석 입니다.

.NET Framework를 피하면 좋은 JavaScript 코드를 많이 놓칠 수 있습니다 new.

툴킷에서 임의로 거대한 덩어리를 잘라 내지 말고 배우고 적절하게 사용하십시오.

Crockford는 자신의 코드에 버그를 준 JavaScript의 모든 것이 나쁘다고 말하는 습관이 있습니다.

저는 개인적으로 "더 나은 대처 전략은 능력이있는" 이라고 말하고 싶습니다 .


공장 기능을 생성하여 피할 있습니다new .

var today = Date.getToday();

(궁금하신 다면 공장 기능 자체 에서는 피할 수 없습니다.)

Date.getToday = function() { return new Date(); };

위의 경우와 같이 의미 값을 추가하거나 생성자 매개 변수 중 일부를 기본값으로 설정할 수있는 경우에만 이러한 함수를 만들어야한다고 생각합니다. 즉, 단지 그것을하지 않도록 사용 new.


이 질문은 이미 묻고 답했습니다. 자바 스크립트의 "새로운"키워드가 유해한 것으로 간주됩니까?

Raynos가 말했듯이, 그들이하는 일을 말하는 이유이해하지 않고 Crockford (또는 그 문제에 대해 다른 사람)를 맹목적으로 따르는 것은 어리석은 일입니다.


내가 사용하지 않는 자신의 조언을 생각 new 전혀이 (교육) 개념이 아니라 문자 그대로 될 것입니다. Date어떻게 다른 당신이 표준 인 ECMAScript를 사용하여 현재 (또는 임의) 날짜 개체를 얻을 수 있기 때문에 클래스는 규칙에 완벽한 예외?

그러나 new사용자 지정 개체를 사용하지 않는 경우 몇 가지 전략을 사용할 수 있습니다. 하나는 생성자 대신 팩토리와 같은 메소드를 사용하는 것입니다. 이는 객체 인스턴스를 인수로 사용하여 새 유형에 "축복"하거나 기본적으로 새 객체 리터럴을 사용할 수 있습니다. 다음을 고려하세요:

var newCar = function(o) {
  o = o || {};
  // Add methods and properties to "o"...
  return o;
}

function F() { return { /* your fields and methods here */ } }

익명 객체를 반환하고 생성자에서 클로저를 사용하여 "new"를 피할 수 있습니다. 이것은 또한 개인 데이터를 숨기는 데 도움이됩니다.

중히 여기다:

function SomeCounter(start) {

    var counter = start;

    return {
        getCounter : function() {
            return counter;
        },

        increaseCounter : function() {
            counter++;
        }

    };
}

이제 이것을 사용하기 위해해야 ​​할 일은

var myCounter = SomeCounter(5);
myCounter.increaseCounter();
console.log(myCounter.getCounter()); //should log 6

이것의 장점은 "new"를 사용하는 것을 기억할 필요가 없다는 것입니다. 그러나 당신이 그렇게해도 당신을 해치지 않을 것입니다.

var myCounter = new SomeCounter(5); //still works

다른 사람들의 개체를 인스턴스화하기 위해 'new'를 사용하는 데 집착합니다. 그러나 자신의 코드의 경우 'this'와 'new'의 함정을 피할 수 있습니다.

(그런데 문제는 실제로 'new'자체가 아닙니다. 그러나 'new'로 인스턴스화되는 객체는 아마도 내부적으로 'this'를 사용하고있을 것입니다. 'this'를 사용하면 자바 스크립트의 'this'가 빈번하고 미묘한 버그가 발생하기 때문입니다. ' 호출자 는 호출 된 메서드를 올바른 개체에 바인딩하기 위해 추가 작업을 수행해야하며, 잘못된 바인딩은 런타임 전에 린트하거나 감지하기 어렵습니다.)

짧은 버전 :

작성한 객체를 인스턴스화하는 데 'new'를 사용하지 않으려면 아무 함수에서나 객체를 반환하면됩니다. 해당 함수 내에서 해당 객체에 메서드를 연결하고 초기화를 수행합니다. 완료되었습니다.이 함수는 클래스 정의이자 생성자입니다.

긴 버전 (예 :

다음 'self'패턴은 'new'와 'this'를 모두 사용하지 않습니다. 패턴은 각 객체에 메서드 복사본을 저장하지만 런타임에 많은 객체를 생성하지 않는 한 이것은 중요하지 않습니다. 이 경우 http://justjs.com/posts/this-considered-harmful 의 'flyweight'패턴을 항상 사용할 수 있습니다 . (해당 페이지의 예제에서는 여전히 'this'를 약간 사용하지만 다음 패턴에도 적용하기 위해 약간의 조정이 필요합니다.)

// this function defines a "class" -- the whole function is the constructor
function Foo(x) {
    // create/init whatever object type you want here
    var self = {x: x};
    // if subclassing, for instance, you can do:
    // var self = Baz(x);

    // public method
    self.foo = function() {
        return self.x;
    };

    // public method
    self.bar = function() {
        console.log(self.x);
        logger();
    };

    // private method
    function logger() {
        console.log(self.x);
    }

    // ...more constructor bits can go here

    // don't forget to return self
    return self;
}

var f = Foo(1); 
var g = Foo(2); 
setTimeout(f.bar, 1000);
setTimeout(g.bar, 1000);

console.log(g.foo()); // 2
g.x = 5;
console.log(f.foo()); // 1
console.log(g.foo()); // 5

// ...then, 1 second later:
// 1  (from f.bar)
// 1  (from f.logger)
// 5  (from g.bar)
// 5  (from g.logger)

// blows up if uncommented
// f.logger();

참조 URL : https://stackoverflow.com/questions/5224295/javascript-the-good-parts-how-to-not-use-new-at-all

반응형