객체를 작성하는 방법(둘)

4511 단어
지난번에 대상을 만드는 데 가장 자주 사용하는 세 가지 방법을 말했습니다.공장 모델, 구조 함수 모델과 원형 모델.공장 모델은 대상의 유형을 정확하게 확정하지 못하고 구조 함수 모델의 봉인성이 좋지 않다. 이에 세 번째 모델이 화려하게 탄생했다. 이것이 바로 원형 모델이다.3. 원형 모드에서 우리가 만든 모든 함수는 prototype 속성이 있는데 이 속성은 하나의 바늘로 하나의 대상을 가리키며 이 대상의 용도는 특정 유형의 모든 실례가 공유할 수 있는 속성과 방법을 포함한다.글자의 뜻에 따라 이해한다면 prototype는 구조 함수를 호출하여 만든 그 대상의 실례적인 원형 대상이다.원형 대상을 사용하는 장점은 모든 대상이 포함된 속성과 방법을 실례적으로 공유할 수 있다는 것이다.구조 함수에서 대상의 실례적인 정보를 정의하지 않고 원형 대상에 직접 추가할 수 있다는 얘기다.
function Person () {
    //console.log(this);
}
Person.prototype.name = 'Nico';
Person.prototype.age = 23;
Person.prototype.job = 'FE';
Person.prototype.sayName = function () {
    console.log(this); // obj
    console.log(this.name);
}

var p1 = new Person();
p1.sayName();
var p2 = new Person();
p2.sayName();

모든 구조 함수는 ptototype 원형 대상이 있고 구조 함수가 만든 모든 실례는 하나__proto__ 속성을 가지고 구조 함수의 원형 대상을 가리킨다. 즉,
p1.__proto__ === Person.prototype

이상은 이 연결이 실례와 구조 함수의 원형 대상 사이에 존재하는 것이지 실례와 구조 함수 사이에 존재하는 것이 아니라는 것을 설명한다.이때 실례는 속성이 아니라 원형 체인을 통해 원형 대상의 속성을 공유하기 때문이다.따라서 sayName() 방법은 실례 대상에게 호출된 원형 대상의 방법이다.때문에
console.log(p1.sayName() === p2.sayName()); // true

대상의 실례에 하나의 속성을 추가할 때 이 속성은 원형 대상에 저장된 동명 속성을 차단한다.다시 말하면 이 속성을 추가하면 원형에 있는 그 속성에 접근하는 것을 막을 뿐 수정하지 않는다는 것이다.이 속성을 null로 설정해도 원형을 가리키는 링크는 실례에서만 설정됩니다.
function Person () {}
Person.prototype.name = 'Nico';
Person.prototype.age = 23;
Person.prototype.job = 'FE';
Person.prototype.sayName = function () {
    console.log(this.name);
}

var p1 = new Person();
p1.name = 'Ann';
p1.sayName(); // 'Ann'
var p2 = new Person();
p2.sayName(); // 'Nico'
console.log(p1.sayName === p2.sayName); // true

왜냐하면 실례에 속성을 부여할 때 실례가 이 속성을 가지게 되면 자연히 원형 체인을 위로 거슬러 올라가지 않고 원형 체인에 대해 아무런 변화가 없기 때문이다.그러나 이런 식으로 속성을 삭제하려면 delete 키워드를 사용해야 한다.
delete p1.name;
p1.sayName(); // 'Nico'

원형을 다시 쓰는 것은 시각적으로 더욱 편하고 코드를 쓸 때 더욱 힘을 절약하기 위해서다.일반적으로 모든 속성과 방법을 포함하는 대상으로 전체 원형 대상을 다시 쓴다.
function Person () {}
Person.prototype = {
    constructor: Person,
    name: 'Ann',
    age: 23,
    job: 'FE'
};

그러나 이런 방법은 원형 대상을 다시 쓰는 것과 같다. 비교적 뚜렷한 변화는 constructor 속성이 가리키는 것은Person이 아니라Object이다.
var f1 = new Person();
console.log(f1.constructor == Person); // false
console.log(f1.constructor == Object); // true

이 때 원형 대상을 글자 양으로 다시 쓰는 것은 다음과 같은 몇 걸음을 걷는 셈이다.
var obj = new Object();
//  obj constructor , 
obj.__proto__ = Object.prototype;
//  ,obj constructor Object 
 console.log(f1.constructor == Object); // true

원형 방식이 가져온 문제는 원형 대상에 인용 유형의 가치 속성을 포함하고 실례 대상을 수정하면 원형 대상의 속성 값의 변화에 영향을 줄 수 있다.
function Person () {}
Person.prototype = {
    constructor: Person,
    name: 'Ann',
    friends: ['a', 'b']
};

var p1 = new Person();
var p2 = new Person();
var p3 = new Person();

p1.friends = ['a', 'b', 'v'];
p3.friends.push('z');
console.log(p1.friends); // ['a', 'b', 'v']
console.log(p1.hasOwnProperty('friends')); // true
console.log(p3.friends); // ['a', 'b', 'z']
console.log(p3.hasOwnProperty('friends')); // false
console.log(p2.friends); // ['a', 'b', 'z']
console.log(p2.hasOwnProperty('friends')); // false

이를 통해 알 수 있듯이 p1 자신의 실례에서 진정으로 friends 속성을 만들었고 p3 이 속성을 가지지 않았기 때문에 그의 조작은 원형 대상에서 직접 조작한 것이다.4. 조합은 구조 함수 모델과 원형 모델 구조 함수 모델을 사용하여 실례 속성을 정의하고 원형 모델은 방법과 공유의 속성을 정의하는 데 사용한다.
function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ['r', 'g', 'b'];
}

Person.prototype = {
    constructor: Person,
    sayName: function () {
        console.log(this.name);
    }
}

var p1 = new Person('Nico', 23, 'FE');
var p2 = new Person('Ann', 24, 'RD');

p1.friends.push('y');
console.log(p1.friends); // ['r', 'g', 'b', 'y']
console.log(p2.friends); // ['r', 'g', 'b']
console.log(p1.friends === p2.friends); // false
console.log(p1.sayName === p2.sayName); // true

좋은 웹페이지 즐겨찾기