>웹 프론트엔드 >JS 튜토리얼 >이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

coldplay.xixi
coldplay.xixi앞으로
2020-10-22 18:30:341711검색

javascript 칼럼에서는 프로토타입과 프로토타입 체인을 간단하고 명확하게 소개합니다.

이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

JavaScript에서 프로토타입과 프로토타입 체인은 필연적이고 중요한 개념인데, 프로토타입과 프로토타입 체인을 어떻게 이해해야 할까요? 다음은 프로토타입과 프로토타입 체인에 대한 나의 이해와 요약입니다. 아마도 일부 이해는 여전히 상대적으로 얕을 수 있습니다. 시간이 흐르고 이해가 깊어지면 앞으로 더 많은 것이 추가될 것입니다. 제가 이해한 내용에 잘못된 부분이 있다고 생각되면 댓글로 정정해 주시기 바랍니다.

1. JavaScript가 프로토타입 기반 모델로 설계된 이유

지난 학습 과정에서 우리는 객체지향 언어인 Java에서 캡슐화, 상속, 다형성이라는 세 가지 요소를 가지고 있다는 것을 배웠습니다. 상속과 관련하여 java와 javascript는 실제로 완전히 동일하지 않습니다.
그렇다면 자바스크립트는 어떻게 설계되었나요? 초기에는 브라우저가 웹 콘텐츠를 검색할 수만 있었고 사용자 상호 작용을 수행할 수 없었습니다. 즉, 로그인하기 위해 계정과 비밀번호를 입력하면 브라우저가 입력 콘텐츠를 판단할 수 없었고 사용자의 판단을 받아야 했습니다. 이 문제를 해결하기 위해 Netscape는 Java와 함께 사용되며 구문이 다소 유사한 보조 스크립트 언어를 개발합니다. 이를 통해 javascript는 모두 객체 유형이라는 것을 알 수 있습니다. 객체가 있으면 상속 메커니즘이 관련됩니다.
        JS는 Java의 디자인을 참조하며 new 연산자를 사용하여 객체를 생성하지만 Java와 다른 점은 new 뒤에 Class 대신 Construtor가 옵니다.

// java 中生成一个对象
Person p = new Person() // Person 指的是类名

// js 生成一个对象
function Person (age) {
    this.age = age
    this.nation = 'China'
}
var father = new Person(42) // Person 指的是构造函数
var mingming = new Person(11)复制代码

2. 생성자

생성자 역시 일반 함수이고, 프로토타입 속성도 가지고 있습니다. 일반 함수와의 차이점은 첫 글자를 대문자로 써야 한다는 점입니다. new 연산자를 사용하여 생성자를 호출하는 경우 다음 네 단계를 수행해야 합니다.
  1. 새 개체 만들기
  2. 이 새로운 개체를 가리킵니다
 ​ 3. 생성자를 실행하고 새 개체에 속성과 메서드를 추가합니다
       4. 이 새 객체 반환

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')复制代码

3. 프로토타입 프로토타입

                                          모든 함수에는 프로토타입 객체를 가리키는 프로토타입 속성이 있습니다. 그러면 프로토타입은 실제로 객체입니다. 상속(new 연산자에 의해 구현됨)을 통해 프로토타입에 정의된 속성은 인스턴스화된 객체에도 이 속성을 갖습니다.
        프로토타입과 생성자의 관계: 생성자에는 프로토타입에 액세스할 수 있는 프로토타입 속성이 있습니다.

이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

생성자의 코드를 예로 들면 Food는 생성자, Food.prototype은 프로토타입, food는 Food.prototype을 참조하여 생성된 객체입니다. St4. 예제 인스턴스

인스턴스는 프로토타입에서 "상속"할 수 있는 속성과 메서드를 생성하고 new 연산자에 의해 생성된 생성자를 의미합니다.使用 간단히 말해서 NEW 연산자를 사용하여 Food 인스턴스를 생성하고 Instanceof 테스트 인스턴스와 생성자 간의 관계를 전달할 수 있습니다. 이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
var res = food instanceof Food // 检查 food 是否为 Food 实例
console.log(res) // true复制代码
프로토타입에 속성을 정의하면 인스턴스도 이 속성을 "상속"합니다.

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
var res = food instanceof Food // 检查 food 是否为 Food 实例
console.log(res) // true

// 原型定义属性
Food.prototype.type = 'object named Food'
var foodRes = food.type // 实例继承的属性
console.log(foodRes) // object named Food复制代码

5. 암시적 프로토타입 _

_proto__

이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다. 모든 객체는 생성될 때 현재 객체를 생성한 생성자의 프로토타입 객체를 가리키는 _

_proto__

속성을 갖습니다. 이 속성은 표준 속성이 아니므로 프로토타입 체인의 손상을 방지하기 위해 이 속성의 값을 임의로 변경하지 마십시오. 즉, 인스턴스는 _

_proto__

속성을 통해 프로토타입에 액세스할 수 있습니다.

        对象中的 __proto__ 属性在所有实现中是无法访问到的,但是可以通过 isPrototypeOf() 方法来确定对象之间是否存在着这种关系。

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
console.log(food.__proto__ === Food.prototype) // true
console.log(Food.prototype.isPrototypeOf(food)) // true复制代码

6. 构造函数 constructor

        构造函数可以通过 prototype 属性访问到原型,那么原型也是能够通过某种途径访问到构造函数的,其就是原型中的一个属性 constructor ,该属性并不是真正的构造函数,真正的构造函数是指 Constructor,两者不要混淆了。

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')
console.log(Food.prototype.constructor === Food) //true复制代码

이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

        关键:prototype 的 constructor 指向构造函数本身    

        那么构造函数、原型、实例三者的关系应该是这样的:

이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

         为了更好地理解这一过程,我通过一个故事给大家梳理一下:
       1. 很久以前,有个雕刻家偶然看到一个很精致的花瓶(原型 Food.prototype)
       2. 一天,他想通过大批生产复刻这个花瓶来发家致富,于是他先分析这个花瓶,还原了雕刻的过程,并设计出了一条生产线(构造器 Food)
       3. 然后通过这条生产线,雕刻出许许多多的复刻花瓶。(实例 food)

7. 原型链

         proto 是任何对象都有的属性,在js中会形成一条 proto 连接起来的链条,递归访问 proto 直到值为 null ,这个搜索过程形成的链状关系就是原型链。

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
// 原型链
console.log(food.__proto__) // Food {}
console.log(food.__proto__.__proto__) // {}
console.log(food.__proto__.__proto__.__proto__) // null复制代码

        如下图:

이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.

总结

        1. 每创建一个函数都会有一个 prototype 属性,该属性是一个指针,指向一个对象,该对象为原型对象(Food.prototype)。
        2. 原型对象上的默认属性 constructor 也是一个指针,指向其相关的构造函数。
       3. 通过 new 操作符产生的实例对象都会有一个内部属性指向原型对象,该实例对象可以访问原型对象上的所有属性和方法。
       4. 实例可以通过内部指针访问到原型对象,原型对象也可以通过 constructor 找到构造函数。
       5. 每个构造函数都有一个原型对象,原型对象上包含一个指向构造函数的指针,实例包含一个指向原型对象的内部指针。
       6. __proto___ 的指向取决于对象创建时的实现方式。
       7. 构造函数实例,封装的函数,如果通过 new 操作符来调用则是构造函数,否则则不是。           8. 在整个原型链上寻找某个属性,对性能有影响,越是上层的原型对象,对性能的影响越大。
       9. js中一切皆对象,通过 new Function 的是函数对象,其构造函数是 Function,而普通对象的构造函数则是 Object 。
       10. 每一个对象都有 __proto__ 属性,而每一个函数对象才有 prototype 属性。

参考来源

1.《JavaScript 高级程序设计》
2.developer.mozilla.org/zhCN/docs/W…

最后

        如果你仔细阅读完本文,相信你对 JavaScript 中的原型和原型链会有新的认识。如果你觉得对你有帮助,记得 点赞 哦!如果你发现我理解的有问题,也欢迎你在评论中指正出来。

相关免费学习推荐:javascript(视频)

위 내용은 이렇게 보면 프로토타입과 프로토타입 체인은 어렵지 않을 것 같습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제