>  기사  >  웹 프론트엔드  >  JS 프로토타입과 프로토타입 체인에 대한 가장 자세한 설명

JS 프로토타입과 프로토타입 체인에 대한 가장 자세한 설명

hzc
hzc앞으로
2020-06-24 09:50:121769검색

1. 일반 객체와 함수 객체

자바스크립트에서는 모든 것이 객체입니다! 하지만 대상도 다릅니다. 일반 객체와 함수 객체로 나뉘는데, Object와 Function은 JS에 포함된 함수 객체입니다. 다음 예는

 var o1 = {}; 
 var o2 =new Object(); var o3 = new f1(); 
 function f1(){}; 
 var f2 = function(){}; var f3 = new Function('str','console.log(str)');
 
 console.log(typeof Object); //function 
 console.log(typeof Function); //function   
 console.log(typeof f1); //function 
 console.log(typeof f2); //function 
 console.log(typeof f3); //function    
 console.log(typeof o1); //object 
 console.log(typeof o2); //object 
 console.log(typeof o3); //object

을 보여줍니다. 위 예에서 o1 o2 o3은 일반 개체이고 f1 f2 f3은 함수 개체입니다. 차이점을 구별하는 방법은 실제로 매우 간단합니다. new Function()을 통해 생성된 모든 개체는 함수 개체이고 다른 개체는 일반 개체입니다. f1, f2는 모두 최종 분석에서 new Function()을 통해 생성됩니다. 함수 객체는 New Function()을 통해서도 생성됩니다.

일반 객체와 함수 객체를 반드시 구별하세요. 아래에서는 자주 사용하겠습니다.

2. 생성자

먼저 생성자에 대한 지식을 검토해 보겠습니다.

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function() { alert(this.name) } 
 }
 var person1 = new Person('Zaxlct', 28, 'Software Engineer');
 var person2 = new Person('Mick', 23, 'Doctor');

위의 예에서 person1과 person2는 모두 Person의 인스턴스입니다. 두 인스턴스 모두 Person을 가리키는 constructorconstructor (构造函数)属性,该属性(是一个指针)指向 Person。 即:

   console.log(person1.constructor == Person); //true
   console.log(person2.constructor == Person); //true

我们要记住两个概念(构造函数,实例):  person1 和 person2 都是 构造函数 Person 的实例  一个公式:  实例的构造函数属性(constructor)指向构造函数。

三. 原型对象

在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象。(先用不管什么是 __proto__ 第二节的课程会详细的剖析)

 function Person() {}
 Person.prototype.name = 'Zaxlct';
 Person.prototype.age  = 28;
 Person.prototype.job  = 'Software Engineer';
 Person.prototype.sayName = function() {
   alert(this.name);
 }   
 var person1 = new Person();
 person1.sayName(); // 'Zaxlct' 
 var person2 = new Person();
 person2.sayName(); // 'Zaxlct' 
 console.log(person1.sayName == person2.sayName); //true

我们得到了本文第一个「定律」:

 每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性

那什么是原型对象呢?  我们把上面的例子改一改你就会明白了:

Person.prototype = {
    name:  'Zaxlct',
    age: 28,
    job: 'Software Engineer',
    sayName: function() {
      alert(this.name);
    }
 }

原型对象,顾名思义,它就是一个普通对象(废话 = =!)。从现在开始你要牢牢记住原型对象就是 Person.prototype ,如果你还是害怕它,那就把它想想成一个字母 A: var A = Person.prototype


在上面我们给 A 添加了 四个属性:name、age、job、sayName。其实它还有一个默认的属性:constructor

在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person)

上面这句话有点拗口,我们「翻译」一下:A 有一个默认的 constructor 属性,这个属性是一个指针,指向 Person。即:  Person.prototype.constructor == Person


在上面第二小节《构造函数》里,我们知道实例的构造函数属性(constructor)指向构造函数person1.constructor == Person(생성자) 속성을 가지고 있습니다. 즉:

 person1.constructor == Person
 Person.prototype.constructor == Person

우리는 두 가지 개념(생성자, 인스턴스)을 기억해야 합니다.

person1과 person2는 모두 Person 생성자의 인스턴스입니다. 공식: 인스턴스의 생성자 속성(생성자)은 생성자 . 3. 프로토타입 객체

JavaScript에서는 객체(함수도 객체이기도 함)가 정의될 ​​때마다 객체에는 미리 정의된 일부 속성이 포함됩니다. 각 🎜함수 개체🎜에는 함수의 🎜프로토타입 개체🎜를 가리키는 prototype 속성이 있습니다. (먼저 __proto__를 사용하고 두 번째 과정에서 자세히 분석합니다.) 🎜🎜
var A = new Person();
Person.prototype = A; // 注:上面两行代码只是帮助理解,并不能正常运行
🎜🎜이 기사에서 첫 번째 "🎜Law🎜"을 얻었습니다: 🎜🎜
  function Person(){};
  console.log(Person.prototype) //Person{}
  console.log(typeof Person.prototype) //Object
  console.log(typeof Function.prototype) // Function,这个特殊
  console.log(typeof Object.prototype) // Object
  console.log(typeof Function.prototype.prototype) //undefined

🎜 🎜그래서 뭐죠? 🎜프로토타입 개체🎜인가요? 위의 예를 바꾸면 다음과 같이 이해하게 될 것입니다. 🎜🎜
  var A = new Function ();
  Function.prototype = A;
🎜🎜프로토타입 개체는 이름에서 알 수 있듯이 일반 개체입니다(말도 안되는 = =!). 이제부터 프로토타입 객체가 Person.prototype이라는 점을 기억해야 합니다. 여전히 두렵다면 문자 A로 생각하세요. var A = Person.prototype🎜🎜
🎜🎜 위에서 A에 이름, 나이, 직업, sayName이라는 네 가지 속성을 추가했습니다. 실제로 constructor🎜🎜
🎜🎜기본 속성도 있습니다. 기본적으로 모든 🎜프로토타입 개체🎜🎜는 🎜자동으로 생성자🎜를 얻습니다🎜🎜. (생성자) 속성, 이 속성(포인터)은 prototype🎜 속성이 위치한 함수(Person)를 가리킵니다🎜🎜🎜🎜🎜🎜
🎜🎜위 문장은 약간 혼란스럽습니다. "번역"해 보겠습니다. A에는 Person을 가리키는 포인터인 기본 constructor 속성이 있습니다. 즉, Person.prototype.constructor == Person🎜🎜
🎜🎜위의 두 번째 섹션 "생성자"에서 🎜 인스턴스의 생성자 속성(생성자)이 다음을 가리킨다는 것을 알 수 있습니다. 생성자 🎜: person1.constructor == Person🎜🎜🎜🎜이 두 "공식"은 다소 관련이 있는 것 같습니다. 🎜🎜
var Person = function(name){
     this.name = name; // tip: 当函数执行时这个 this 指的是谁?
   };
   Person.prototype.getName = function(){
     return this.name;  // tip: 当函数执行时这个 this 指的是谁?
   }
   var person1 = new person('Mick');
   person1.getName(); //Mick
🎜🎜person1에 생성자 속성이 있는 이유는 무엇입니까? 이는 person1이 Person의 인스턴스이기 때문입니다. 🎜 🎜 그렇다면 Person.prototype에는 왜 생성자 속성이 있는 걸까요? ? 마찬가지로 Person.prototype(A로 생각)도 Person의 인스턴스입니다. 🎜 🎜 즉, Person이 생성되면 해당 인스턴스 객체가 생성되어 프로토타입에 할당됩니다. 🎜🎜🎜🎜🎜🎜
var A = new Person();
Person.prototype = A; // 注:上面两行代码只是帮助理解,并不能正常运行

结论:原型对象(Person.prototype)是 构造函数(Person)的一个实例。


原型对象其实就是普通对象(但 Function.prototype 除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。看下面的例子:

  function Person(){};
  console.log(Person.prototype) //Person{}
  console.log(typeof Person.prototype) //Object
  console.log(typeof Function.prototype) // Function,这个特殊
  console.log(typeof Object.prototype) // Object
  console.log(typeof Function.prototype.prototype) //undefined

Function.prototype 为什么是函数对象呢?

  var A = new Function ();
  Function.prototype = A;

上文提到凡是通过 new Function( ) 产生的对象都是函数对象。因为 A 是函数对象,所以Function.prototype 是函数对象。

那原型对象是用来做什么的呢?主要作用是用于继承。举个例子:

var Person = function(name){
     this.name = name; // tip: 当函数执行时这个 this 指的是谁?
   };
   Person.prototype.getName = function(){
     return this.name;  // tip: 当函数执行时这个 this 指的是谁?
   }
   var person1 = new person('Mick');
   person1.getName(); //Mick

从这个例子可以看出,通过给 Person.prototype 设置了一个函数对象的属性,那有 Person 的实例(person1)出来的普通对象就继承了这个属性。具体是怎么实现的继承,就要讲到下面的原型链了。

小问题,上面两个 this 都指向谁?

 var person1 = new person('Mick');
 person1.name = 'Mick'; // 此时 person1 已经有 name 这个属性了
 person1.getName(); //Mick

故两次 this 在函数执行时都指向 person1。

推荐教程:《JS教程

위 내용은 JS 프로토타입과 프로토타입 체인에 대한 가장 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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