JavaScript_기본 지식의 프로토타입 상속에 대한 기본 학습 튜토리얼

WBOY
풀어 주다: 2016-05-16 15:01:46
원래의
1358명이 탐색했습니다.

대부분의 프로그래밍 언어에는 클래스와 객체가 있으며, 한 클래스가 다른 클래스를 상속할 수 있습니다.
JavaScript에서 상속은 프로토타입 기반입니다. 즉, JavaScript에는 클래스가 없고 대신 한 개체가 다른 개체를 상속합니다. :)

1. 상속, 프로토
JavaScript에서 토끼 객체가 다른 객체 동물을 상속받는 경우 이는 토끼 객체에 특별한 속성이 있음을 의미합니다. Rabbit.__proto__ = 동물;
토끼 개체에 접근할 때 인터프리터가 토끼에서 속성을 찾을 수 없으면 __proto__ 체인을 따라가며 동물 개체에서
를 찾습니다. 밤나무의 __proto__ 속성은 Chrome 및 FireFox에서만 액세스할 수 있습니다. 밤나무를 참조하세요.

var animal = { eats: true }
var rabbit = { jumps: true }

rabbit.__proto__ = animal // inherit

alert(rabbit.eats) // true

로그인 후 복사

eats 속성은 동물 개체에서 액세스됩니다.
해당 속성이 토끼 개체에서 발견된 경우 proto 속성은 확인되지 않습니다.
또 다른 예를 들어, 하위 클래스에 eats 속성도 있으면 상위 클래스에 있는 클래스에는 액세스할 수 없습니다.

var animal = { eats: true }
var fedUpRabbit = { eats: false}

fedUpRabbit.__proto__ = animal 

alert(fedUpRabbit.eats) // false

로그인 후 복사

동물에서도 기능을 추가할 수 있고, 토끼에서도 접근이 가능합니다.

var animal = {
 eat: function() {
  alert( "I'm full" )
  this.full = true
 }
}


var rabbit = {
 jump: function() { /* something */ }
}

rabbit.__proto__ = animal 

로그인 후 복사

(1) Rabbit.eat():
Rabbit.eat() 함수는 다음 두 단계로 실행됩니다.
먼저, 인터프리터는 Rabbit.eat를 찾습니다. Rabbit에는 eat 함수가 없으므로, Rabbit.__proto__를 찾아 Animal에서 찾습니다.
함수는 this = Rabbit으로 실행됩니다. this 값은 __proto__ 속성과 전혀 관련이 없습니다.
따라서 토끼에서는 this.full = true입니다.
여기서 어떤 새로운 발견이 있는지 살펴보겠습니다. 객체가 상위 클래스 함수를 호출하지만 이는 여전히 객체 자체를 가리킵니다.
__proto__가 참조하는 객체를 프로토타입이라고 하며, 동물은 토끼의 프로토타입입니다. (역자 주: 토끼의 __proto__ 속성이 동물의 프로토타입 속성을 참조하기 때문입니다.)
(2) 쓸 때가 아닌 읽을 때 검색
this.prop과 같은 객체를 읽을 때 인터프리터는 해당 프로토타입에서 속성을 찾습니다.
this.prop = value와 같은 속성 값을 설정할 때 이를 찾을 이유가 없으며 속성(prop)이 객체(여기서는 this)에 직접 추가됩니다. delete obj.prop도 비슷합니다. 객체 자체의 속성만 삭제하고 프로토타입의 속성은 그대로 유지됩니다.
(3) 프로토 소개
가이드를 읽고 계시다면 여기서 __proto__라고 부르는 것이 가이드에서 [[Prototype]]으로 표시됩니다. 프로토타입이라는 또 다른 속성이 있기 때문에 이중 괄호가 중요합니다.

2. Object.create, Object.getPrototypeOf
__proto__는 Chrome/FireFox에서 제공하는 비표준 속성이며 다른 브라우저에서는 표시되지 않습니다.
Opera(IE > 9)를 ​​제외한 모든 최신 브라우저는 프로토타입 문제를 처리하기 위해 두 가지 표준 기능을 지원합니다.

Object.ceate(prop[,props])
로그인 후 복사

주어진 proto로 빈 개체 만들기:

var animal = { eats: true }

rabbit = Object.create(animal)

alert(rabbit.eats) // true

로그인 후 복사

위 코드는 빈 토끼 객체를 생성하고 프로토타입을 동물로 설정합니다
토끼 개체가 생성된 후 속성을 추가할 수 있습니다.

var animal = { eats: true }

rabbit = Object.create(animal)
rabbit.jumps = true

로그인 후 복사

Object.creat 함수의 두 번째 매개변수 props는 선택사항이며, 이를 통해 새 객체와 같은 속성을 설정할 수 있습니다. 우리 관계의 상속으로 인해 여기서는 생략합니다.
(1) Object.getPrototypeOf(obj)
obj.__proto__의 값을 반환합니다. 이 기능은 표준이며 __proto__ 속성에 직접 액세스할 수 없는 브라우저에서 사용할 수 있습니다.

var animal = {
 eats: true
}

rabbit = Object.create(animal)

alert( Object.getPrototypeOf(rabbit) === animal ) // true

로그인 후 복사

최신 브라우저에서는 __proto__ 속성 ​​값을 읽을 수는 있지만 설정할 수는 없습니다.

3. 프로토타입
생성자 함수를 사용하는 __proto__ 속성을 설정하는 여러 브라우저 간 좋은 방법이 있습니다. 기억하다! 모든 함수는 new 키워드를 통해 객체를 생성합니다.
밤 :

function Rabbit(name) {
 this.name = name
}

var rabbit = new Rabbit('John')

alert(rabbit.name) // John

로그인 후 복사

새 작업은 프로토타입의 속성을 토끼 개체의 __proto__ 속성으로 설정합니다.
예를 들어 새로운 Rabbit 객체와 Rabbit이 동물로부터 상속받는 경우가 어떻게 작동하는지 살펴보겠습니다.

var animal = { eats: true }

function Rabbit(name) {
 this.name = name
}

Rabbit.prototype = animal

var rabbit = new Rabbit('John')

alert( rabbit.eats ) // true, because rabbit.__proto__ == animal

로그인 후 복사

Rabbit.prototype = 동물 리터럴은 새 Rabbit이 생성한 모든 개체에 대해 __proto__ = 동물

을 설정한다는 의미입니다.

4. 크로스 브라우저 Object.create(proto)
Object.create(prop) 함수는 주어진 객체로부터 직접 상속을 허용하므로 강력합니다. 다음 코드로 시뮬레이션할 수 있습니다.

function inherit(proto) {
 function F() {}
 F.prototype = proto
 return new F
}
로그인 후 복사

inherit(animal)은 Object.create(animal)과 완전히 동일하며 빈 개체를 반환하고 object.__proto__ = 동물입니다.
밤 :

var animal = { eats: true }

var rabbit = inherit(animal)

alert(rabbit.eats) // true
alert(rabbit.hasOwnProperty('eats')) // false, from prototype

로그인 후 복사

작동 방식을 살펴보겠습니다.

function inherit(proto) {
 function F() {}   // (1)
 F.prototype = proto // (2)
 return new F()   // (3)
}
로그인 후 복사

(1) 创建了一个新函数,函数没有向this设置任何属性,以此`new F` 会创建一个空对象。
(2) `F.prototype`被设置为proto
(3) `new` F创建了一个空对象,对象的`__proto__ = F.prototype`
(4) Bingo! 我们得到了一个继承`proto`的空对象
这个函数广泛适用于各种库和框架之中。
你的函数接受了一个带有options 的对象

/* options contains menu settings: width, height etc */
function Menu(options) {
 // ...
}
你想设置某些options
function Menu(options) {
 options.width = options.width || 300 // set default value
 // ...
}
로그인 후 복사

。。。但是改变参数值可能会产生一些错误的结果,因为options可能会在外部代码中使用。一个解决办法就是克隆options对象,复制所有的属性到一个新的对象中,在新对象中修改,
怎样用继承来解决这个问题呢? P.S. options可以添加设设置,但是不能被删除。
Solution
你可以继承options,并且在它的子类的中修改或者添加新的属性。

function inherit(proto) {
 function F() {}
 F.prototype = proto
 return new F
}

function Menu(options) {
 var opts = inherit(options)
 opts.width = opts.width || 300
 // ...
}

로그인 후 복사

所有的操作只在子对象中有效,当Menu方法结束时,外部代码仍然可以使用没有修改的过的options对象。delete操作在这里非常重要,如果width是一个prototype中的属性,delete opts.width不会产生任何作用

5. hasOwnProperty
所有的对象都有hasOwnProperty函数,它可以用来检测一个属性是否对象自身还是属于原型
一个栗子:

function Rabbit(name) {
 this.name = name
}

Rabbit.prototype = { eats: true }

var rabbit = new Rabbit('John')

alert( rabbit.hasOwnProperty('eats') ) // false, in prototype

alert( rabbit.hasOwnProperty('name') ) // true, in object

로그인 후 복사

6. Looping with/without inherited properties
for..in循环输出一个对象的所有属性,包括自身的和原型的。

function Rabbit(name) {
 this.name = name
}

Rabbit.prototype = { eats: true }

var rabbit = new Rabbit('John')

for(var p in rabbit) {
 alert (p + " = " + rabbit[p]) // outputs both "name" and "eats"
}

로그인 후 복사

用hasOwnProperty可以过滤得到属于对象自己的属性:

function Rabbit(name) {
 this.name = name
}

Rabbit.prototype = { eats: true }

var rabbit = new Rabbit('John')

for(var p in rabbit) {
 if (!rabbit.hasOwnProperty(p)) continue // filter out "eats"
 alert (p + " = " + rabbit[p]) // outputs only "name"
}

로그인 후 복사

7. Summary
JavaScript是通过一个特殊的属性proto来实现继承的
当访问一个对象的属性时,如果解释器不能在对象中找到,它就会去对象的原型中继续寻找 对函数属性来说,this指向这个对象,而不是它的原型。
赋值obj.prop = value, 删除delete obj.prop
管理proto:
Chrome和FireFox可以直接访问对象的__proto__属性,大多数现代浏览器支持用Object.getPrototypeOf(obj)只读访问。
Object.create(proto) 可以用给定的proto生成空的子对象,或者通过如下代码达到相同的功能:

function inherit(proto) {
   function F() {}   
   F.prototype = proto
   return new F()  
  }
로그인 후 복사

其他方法:
for..in循环输出一个对象的所有属性(包括自身的和原型的)和对象的原型链。
如果一个属性prop属于对象obj那么obj.hasOwnProperty(prop)返回true,否则返回false。

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿