javascript 칼럼에서는 프로토타입과 프로토타입 체인을 간단하고 명확하게 소개합니다.
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)复制代码
생성자 역시 일반 함수이고, 프로토타입 속성도 가지고 있습니다. 일반 함수와의 차이점은 첫 글자를 대문자로 써야 한다는 점입니다. new 연산자를 사용하여 생성자를 호출하는 경우 다음 네 단계를 수행해야 합니다.
1. 새 개체 만들기
2. 이 새로운 개체를 가리킵니다
3. 생성자를 실행하고 새 개체에 속성과 메서드를 추가합니다
4. 이 새 객체 반환
function Food (name) { this.name = name this.eat = function () { console.log('eat') } } var food = new Food('banana')复制代码
모든 함수에는 프로토타입 객체를 가리키는 프로토타입 속성이 있습니다. 그러면 프로토타입은 실제로 객체입니다. 상속(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复制代码
_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复制代码
构造函数可以通过 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)
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!