"new" 대신 "Object.create" 사용
1.는 Javascript 1.9.3/ECMAScript 5를 했습니다.Object.create
더글라스 크록포드가 오랫동안 지지해 온 것이다.치환 방법new
에는 「」가 붙어 있습니다.Object.create
var UserA = function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
}
UserA.prototype.sayHello = function() {
console.log('Hello '+ this.name);
}
var bob = new UserA('bob');
bob.sayHello();
(가定))MY_GLOBAL.nextId
존재합니다).
내가 생각해 낼 수 있는 최선의 방법은:
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.create(userB);
bob.init('Bob');
bob.sayHello();
장점이 없는 것 같아서 이해가 안 되는 것 같아요.내가 너무 신 고전주의적으로 구는 것 같아.★★★의 Object.create
용밥밥밥을을을을을을을을을?
상속 수준이 1개뿐일 경우 이 예에서는 의 실제 이점을 확인할 수 없을 수 있습니다.
이 방법을 사용하면 개체가 다른 개체에서 직접 상속할 수 있는 차등 상속을 쉽게 구현할 수 있습니다.
★★★★★★★★★★★★★★★★★★★★★★★에userB
를 들어, 나는 너의 '나'나 '나'가 '나'라고는하지 않는다init
.이 public이 존재합니다.기존 오브젝트인스턴스에서 이 메서드를 다시 호출하면id
★★★★★★★★★★★★★★★★★」name
속성이 변경됩니다.
Object.create
그럼 두 번째 인수를 사용하여 오브젝트 속성을 초기화할 수 있습니다.하다
var userB = {
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.create(userB, {
'id' : {
value: MY_GLOBAL.nextId(),
enumerable:true // writable:false, configurable(deletable):false by default
},
'name': {
value: 'Bob',
enumerable: true
}
});
두 로 속성을 할 수 .Object.create
하여, 에서 되는 구문과 Object.defineProperties
★★★★★★★★★★★★★★★★★」Object.defineProperty
★★★★★★★★★★★★★★★★★★.
속성)을 할 수 .enumerable
,writable
, 「」configurable
매우 편리합니다.
사용해도 이 없어요.Object.create(...)
에 걸쳐서new object
.
이 방법을 지지하는 사람들은 일반적으로 "확장성" 또는 "JavaScript에 보다 자연스러운" 등의 다소 애매한 이점을 언급합니다.
아직 를 못 요.Object.create
사용하는 것에 비해 이점이 있다new
반대로, 이미 알려진 문제가 있습니다.Sam Elsamman은 중첩된 개체가 있을 때 발생하는 작업을 설명합니다.
var Animal = {
traits: {},
}
var lion = Object.create(Animal);
lion.traits.legs = 4;
var bird = Object.create(Animal);
bird.traits.legs = 2;
alert(lion.traits.legs) // shows 2!!!
이유는 '먹다'가 '먹다'이기 때문입니다.Object.create(...)
새로운 오브젝트를 작성하기 위해 데이터를 사용하는 관행을 지지합니다.여기서Animal
은 시제품의 일부가 .lion
★★★★★★★★★★★★★★★★★」bird
공유 시 문제가 발생합니다.새로운 프로토타입을 사용할 경우 다음과 같이 명확하게 상속됩니다.
function Animal() {
this.traits = {};
}
function Lion() { }
Lion.prototype = new Animal();
function Bird() { }
Bird.prototype = new Animal();
var lion = new Lion();
lion.traits.legs = 4;
var bird = new Bird();
bird.traits.legs = 2;
alert(lion.traits.legs) // now shows 4
Object.create(...)
를 사용하여 추가할 수 있습니다.
object.create는 IE8, Opera v11.5, Konq 4.3 등 여러 브라우저에서 아직 표준이 아닙니다.이러한 브라우저에는 Douglas Crockford 버전의 Object.create를 사용할 수 있지만 CMS 응답에 사용된 두 번째 'initialization object' 파라미터는 포함되지 않습니다.
크로스 브라우저 코드의 경우 Crockford의 Object.create를 커스터마이즈하는 방법이 있습니다.다음은 한 가지 방법입니다.
Object.build = function(o) {
var initArgs = Array.prototype.slice.call(arguments,1)
function F() {
if((typeof o.init === 'function') && initArgs.length) {
o.init.apply(this,initArgs)
}
}
F.prototype = o
return new F()
}
그러면 Crockford 프로토타입 상속이 유지되고 객체의 init 메서드가 있는지 확인한 다음 new man('John' 'Smith')과 같이 매개 변수를 사용하여 실행됩니다.그 후 코드는 다음과 같습니다.
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}} // For example
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.build(userB, 'Bob'); // Different from your code
bob.sayHello();
따라서 bob은 sayHello 메서드를 상속하여 이제 자체 속성 id=1 및 name='Bob'을 가집니다.이러한 속성은 물론 쓰기 가능하고 열거할 수 있습니다.이 방법은 ECMA Object.create보다 훨씬 간단하게 초기화할 수 있습니다.특히 쓰기 가능, 열거 가능, 구성 가능한 속성이 염려되지 않는 경우에는 더욱 그렇습니다.
초기 방법 없이 초기화를 위해 다음과 같은 Crockford 모드를 사용할 수 있다.
Object.gen = function(o) {
var makeArgs = arguments
function F() {
var prop, i=1, arg, val
for(prop in o) {
if(!o.hasOwnProperty(prop)) continue
val = o[prop]
arg = makeArgs[i++]
if(typeof arg === 'undefined') break
this[prop] = arg
}
}
F.prototype = o
return new F()
}
userB 파라미터의 왼쪽에서 오른쪽 뒤에 Object.gen 파라미터를 사용하여 정의된 순서대로 사용자B 자신의 속성을 채웁니다.for(prop in o) 루프를 사용하기 때문에 ECMA 표준에서는 속성 정의 순서와 동일한 속성 열거 순서를 보장할 수 없습니다.단, (4)개의 메이저브라우저에서 테스트된 몇 가지 코드 예에서는 hasOwnProperty 필터가 사용되고 있는 경우 또는 사용되지 않는 경우라도 동일함을 알 수 있습니다.
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}; // For example
var userB = {
name: null,
id: null,
sayHello: function() {
console.log('Hello '+ this.name);
}
}
var bob = Object.gen(userB, 'Bob', MY_GLOBAL.nextId());
오브젝트보다 조금 더 간단하다고 말할 수 있습니다.사용자 B에는 init 메서드가 필요 없기 때문에 빌드합니다.또한 userB는 특별히 컨스트럭터가 아니라 일반적인 싱글톤 오브젝트처럼 보입니다.따라서 이 방법을 사용하면 일반 일반 개체에서 구성 및 초기화할 수 있습니다.
TL;DR:
new Computer()
함수를 합니다.Computer(){}
한 Object.create(Computer.prototype)
할 거예요.
모든 장점은 이 점에 근거를 두고 있다.
호출: 호출과 같은new Computer()
에 의해 되어 있기 에, 수 .Object.create
.
해서 만들 수 있어요.init
return " " " "this
해서 체인을 이렇게 체인을 하다, 하다, 하다, 하다
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
return this;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.create(userB).init('Bob');
Object.create를 사용할 수 있는 또 다른 방법은 값싸고 효과적인 방법으로 불변의 개체를 복제하는 것입니다.
var anObj = {
a: "test",
b: "jest"
};
var bObj = Object.create(anObj);
bObj.b = "gone"; // replace an existing (by masking prototype)
bObj.c = "brand"; // add a new to demonstrate it is actually a new obj
// now bObj is {a: test, b: gone, c: brand}
참고: 위의 스니펫은 소스 오브젝트의 클론을 만듭니다(cObj = aObj와 같이 참조가 아님).오브젝트 멤버 속성을 복사하지 않는다는 점에서 copy-properties 메서드(1 참조)보다 유리합니다.소스 객체에 설정된 프로토타입으로 다른 -destination 객체를 만듭니다.또한 대상 객체에서 속성이 수정되면 프로토타입(src)의 속성을 마스킹하여 "즉각"으로 생성됩니다.이것은 불변의 개체를 복제하는 효과적인 방법이 됩니다.
여기서 주의할 점은 이것이 작성 후 변경해서는 안 되는 소스 객체에 적용된다는 것입니다(불변).생성 후 소스 개체가 수정되면 모든 복제본의 마스킹되지 않은 속성도 수정됩니다.
여기를 클릭해 주세요(http://jsfiddle.net/y5b5q/1/) (Object.create capable browser 참조).
문제의은 - 이 차이를 합니다.new
★★★★★★★★★★★★★★★★★」Object.create
접근합니다.이 답변과 이 비디오에 따르면 new
키워드는 다음 작업을 수행합니다.
새 개체를 만듭니다.
함수컨스트럭터 함수)에 합니다.
prototype
를 참조해 주세요.내다
this
변수 포인트로 새 개체를 지정합니다.으로 수행합니다.
return this
;을 할당합니다.
constructor
.
Object.create
은 ""뿐입니다.1st
★★★★★★★★★★★★★★★★★」2nd
★★★★★★★★★★★★★★★★★★!
문제의 코드 예에서는 큰 문제가 되지 않지만 다음 예에서는 다음과 같습니다.
var onlineUsers = [];
function SiteMember(name) {
this.name = name;
onlineUsers.push(name);
}
SiteMember.prototype.getName = function() {
return this.name;
}
function Guest(name) {
SiteMember.call(this, name);
}
Guest.prototype = new SiteMember();
var g = new Guest('James');
console.log(onlineUsers);
부작용은 다음과 같습니다.
[ undefined, 'James' ]
Guest.prototype = new SiteMember();
할 필요는 됩니다.메서드만 만들면 됩니다.getName
게스트에서 사용할 수 있습니다. 때문에 는 래를 사용해야 합니다.Object.create
를 치환하는 경우Guest.prototype = new SiteMember();
로로 합니다.Guest.prototype = Object.create(SiteMember.prototype);
을 사용하다
[ 'James' ]
NEW를 사용하여 개체를 생성할 수 없지만 CREATE 메서드를 호출할 수 있는 경우가 있습니다.
예를 들어 커스텀 요소를 정의하려면 HTMLement에서 파생되어야 합니다.
proto = new HTMLElement //fail :(
proto = Object.create( HTMLElement.prototype ) //OK :)
document.registerElement( "custom-element", { prototype: proto } )
은 ★★★★★입니다.Object.create
으로 is is is is is보다 new
의
이 jsperf 예제에서는 Chromium에서 브라우저,new
보다 30배 빠르다Object.create(obj)
이데올로기이것은 모두 매우 이상합니다.이는 Object.create가 전달된 오브젝트를 프로토타입으로 사용하여 새로운 오브젝트를 작성해야 하기 때문입니다(Crockford-speak의 비밀 링크).
가 '만들기'를 것 .Object.create
효율적이다.new
에서도 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★」
요약:.
Object.create()
자바스크립트.- 첫 번째 인수는 새로 생성된 객체의 프로토타입이 될 객체입니다.
- 두 번째 인수는 새로 생성된 개체의 속성이 될 개체입니다.
예:
const proto = {
talk : () => console.log('hi')
}
const props = {
age: {
writable: true,
configurable: true,
value: 26
}
}
let Person = Object.create(proto, props)
console.log(Person.age);
Person.talk();
실용적인 응용 프로그램:
- 이 방법으로 객체를 작성하는 주된 장점은 프로토타입을 명시적으로 정의할 수 있다는 것입니다.오브젝트 리터럴을 사용하는 경우 또는
new
이 키워드는 사용자가 제어할 수 없습니다(단, 덮어쓸 수 있습니다). - 을 갖고 싶다.
new
키워드는 컨스트럭터 함수를 호출합니다.★★★★★★★★★★★★★★★★Object.create()
생성자 함수를 호출하거나 선언할 필요가 없습니다. - 기본적으로 매우 역동적인 방법으로 객체를 작성할 때 유용한 도구입니다.받은 인수에 따라 다른 프로토타입으로 객체를 생성하는 객체 팩토리 기능을 만들 수 있습니다.
.Object.create()
함수를 .Crockfords의 init.
이 조작은 유효합니다.
var userBPrototype = {
init: function(nameParam) {
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
function UserB(name) {
function F() {};
F.prototype = userBPrototype;
var f = new F;
f.init(name);
return f;
}
var bob = UserB('bob');
bob.sayHello();
여기서 UserB는 Object.create와 비슷하지만 필요에 따라 조정됩니다.
필요한 경우 다음 번호로 전화할 수도 있습니다.
var bob = new UserB('bob');
Douglas Crockford는 Object.create()의 열렬한 지지자였으며 기본적으로 이 구성이 javascript에 있는 이유는 Douglas Crockford였지만 그는 더 이상 이 의견을 가지고 있지 않습니다.
Object.create가 너무 많은 문제를 일으키기 때문에 이 키워드를 사용하지 않게 되었습니다.예를 들어 주의하지 않으면 글로벌 객체를 쉽게 가리킬 수 있으며, 이는 매우 나쁜 결과를 초래할 수 있습니다.그리고 그는 이 Object.create를 사용하지 않으면 의미가 없다고 주장합니다.
2014년 Nordic.js에서 그가 강연하는 비디오를 확인하실 수 있습니다.
https://www.youtube.com/watch?v=PSGEjv3Tqo0
new
★★★★★★★★★★★★★★★★★」Object.create
러러가가 목목목목목new
는 오브젝트 유형의 새 인스턴스를 작성하는 것을 목적으로 합니다. Object.create
단순히 새로운 객체를 만들고 프로토타입을 설정하기 위한 것입니다.게게왜 왜? ??? 을 실장하다__proto__
은 오브젝트인스턴스라고 불립니다[[Prototype]]
는 가상 머신의 내부 속성이며 직접 액세스하기 위한 것이 아닙니다. 할 수 유일한 [[Prototype]]
처 __proto__
이는 모든 주요 가상 머신의 ECMAScript 구현에 대한 사실상의 표준이며, 이 시점에서 ECMAScript를 제거하면 많은 기존 코드가 깨지기 때문입니다.
의한 로 7ochem의 는 안 .new
스테이트먼트는 동일한 프로토타입 컨스트럭터를 여러 번 호출할 필요가 없을 뿐만 아니라 동일한 클래스의 두 인스턴스가 생성된 후 프로토타입을 수정하면 결국 다른 동작으로 끝날 수 있기 때문입니다.두 예 모두 단순히 프로토타입 상속 체인의 의도된 동작을 오해하고 파괴한 결과로 인한 잘못된 코드입니다.
접속하는 __proto__
하려면 , 「인스턴스」를 사용해 Object.create
그 에 ★★★★★★★★★★★★★★★★★★★Object.setPrototypeOf
, 로 .Object.getPrototypeOf
★★★★★★★★★★★★★★★★★」Object.isPrototypeOf
.
또한 오브젝트의 Mozilla 문서로도 사용됩니다.setProtypeOf는 오브젝트 생성 후 오브젝트 프로토타입을 수정하는 것은 퍼포먼스상의 이유로 오브젝트 생성 후 오브젝트 프로토타입을 수정하는 것은 좋지 않다고 지적하고 있습니다.또한 오브젝트에 액세스하는 특정 코드가 변경되기 전에 오브젝트 프로토타입을 수정할 수 있는 경우 정의되지 않은 동작이 발생할 수 있습니다.단, c는 예외입니다.ode는 현재 프로토타입을 확인하거나 둘 사이에 차이가 있는 어떠한 속성에도 접근하지 않도록 매우 주의해야 합니다.
★★★★★★★★★★★★★★★★★」
const X = function (v) { this.v = v }; X.prototype.whatAmI = 'X'; X.prototype.getWhatIAm = () => this.whatAmI; X.prototype.getV = () => this.v;
의 VM 는, 「VM」의 합니다.const x0 = new X(1);
:
const x0 = {}; x0.[[Prototype]] = X.prototype; X.prototype.constructor.call(x0, 1);
는 임의의할 수 만, 이 값은 할 수 .new
된 오브젝트에대한 를 반환합니다.
다음 이에 해당합니다.const x1 = Object.create(X.prototype);
:
const x0 = {}; x0.[[Prototype]] = X.prototype;
와 같이 이 은 '하다'라는 밖에 없습니다.Object.create
도 반환할 수 오브젝트레퍼런스 「」를 할 뿐입니다.실제로 어떤 값도 반환할 수 있지만 단순히 새 개체 참조를 반환할 뿐입니다.this
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
다음 정의를 가진 서브클래스 Y를 작성하는 경우:
const Y = function(u) { this.u = u; } Y.prototype.whatAmI = 'Y'; Y.prototype.getU = () => this.u;
그럼 이렇게 X로부터 물려받으면 되겠네요__proto__
:
Y.prototype.__proto__ = X.prototype;
할 수 , 「이렇게 하면」에 된다.__proto__
라이선스:
Y.prototype = Object.create(X.prototype); Y.prototype.constructor = Y;
할 필요가 있습니다.new Y
않은 경우)new Y
합니다.X
가 원하는new Y
X
에서 Y를 사용하는 이 더 것입니다.X.call(this, u)
new
- 생성자 함수에서 개체를 만드는 데 사용됩니다.
new
함수도 합니다.
function Car() {
console.log(this) // this points to myCar
this.name = "Honda";
}
var myCar = new Car()
console.log(myCar) // Car {name: "Honda", constructor: Object}
console.log(myCar.name) // Honda
console.log(myCar instanceof Car) // true
console.log(myCar.constructor) // function Car() {}
console.log(myCar.constructor === Car) // true
console.log(typeof myCar) // object
Object.create
- 이 경우에도 하실 수 있습니다.
Object.create
- 그러나 생성자 함수는 실행되지 않습니다.
Object.create
때 사용합니다.
const Car = {
name: "Honda"
}
var myCar = Object.create(Car)
console.log(myCar) // Object {}
console.log(myCar.name) // Honda
console.log(myCar instanceof Car) // ERROR
console.log(myCar.constructor) // Anonymous function object
console.log(myCar.constructor === Car) // false
console.log(typeof myCar) // object
난 폐쇄적인 접근을 선호한다.
도 쓰고 요.new
는 안 써요.Object.create
는 안 써요.this
.
도 쓰고 요.new
나는 그것의 선언적인 성격을 좋아하기 때문입니다.
단순 상속으로 간주합니다.
window.Quad = (function() {
function Quad() {
const wheels = 4;
const drivingWheels = 2;
let motorSize = 0;
function setMotorSize(_) {
motorSize = _;
}
function getMotorSize() {
return motorSize;
}
function getWheelCount() {
return wheels;
}
function getDrivingWheelCount() {
return drivingWheels;
}
return Object.freeze({
getWheelCount,
getDrivingWheelCount,
getMotorSize,
setMotorSize
});
}
return Object.freeze(Quad);
})();
window.Car4wd = (function() {
function Car4wd() {
const quad = new Quad();
const spareWheels = 1;
const extraDrivingWheels = 2;
function getSpareWheelCount() {
return spareWheels;
}
function getDrivingWheelCount() {
return quad.getDrivingWheelCount() + extraDrivingWheels;
}
return Object.freeze(Object.assign({}, quad, {
getSpareWheelCount,
getDrivingWheelCount
}));
}
return Object.freeze(Car4wd);
})();
let myQuad = new Quad();
let myCar = new Car4wd();
console.log(myQuad.getWheelCount()); // 4
console.log(myQuad.getDrivingWheelCount()); // 2
console.log(myCar.getWheelCount()); // 4
console.log(myCar.getDrivingWheelCount()); // 4 - The overridden method is called
console.log(myCar.getSpareWheelCount()); // 1
피드백 장려.
언급URL : https://stackoverflow.com/questions/2709612/using-object-create-instead-of-new
'source' 카테고리의 다른 글
disk mysql의 tmp 테이블로 복사 건너뛰기 (0) | 2023.01.19 |
---|---|
$물건을 보다 (0) | 2023.01.19 |
Window.resize 또는 document.resize 중 어느 것이 동작하고 어떤 것이 동작하지 않는가?VueJS (0) | 2023.01.19 |
실행 중인 Python 응용 프로그램의 스택 추적 표시 (0) | 2023.01.19 |
코멘트를 사용하여 PHPCS 경고를 억제하려면 어떻게 해야 합니까? (0) | 2023.01.19 |