이 기사는 JavaScript의 프로토타입 객체에 대한 관련 지식을 제공하는 데 도움이 되기를 바랍니다.
수업을 이해하시나요? 수업의 특징은 무엇인가요? (캡슐화, 상속, 다형성)
클래스는 실제로 "특수 함수"입니다. 정의할 수 있는 함수 표현식 및 함수 선언과 마찬가지로 클래스 구문도 클래스 선언과 클래스 표현식 모드라는 두 가지 구성 요소로 구성됩니다. 클래스의 본문은 엄격 모드에서 실행됩니다.
클래스의 클래스 본문은 한 쌍의 중괄호 {}로 묶인 부분으로, 클래스 멤버가 정의되는 부분입니다. [멤버는 주로 메소드 또는 생성자입니다.]
클래스의 모든 메소드는 동일하며 클래스의 프로토타입 속성에 정의됩니다. 클래스 인스턴스에서 메서드를 호출하는 것은 프로토타입에서 메서드를 호출하는 것과 동일합니다.
class A(){ constructor(){} a(){} b(){} } //等价于 A.prototype={constructor(){},a(){},b(){}}
Composition:
Constructor:
생성자 메서드는 클래스에서 생성한 객체를 생성하고 초기화하는 데 사용되는 특수 메서드입니다. 클래스에는 생성자가 하나만 있을 수 있습니다. 생성자가 여러 개 있으면 오류가 보고됩니다. 생성자가 없으면 기본적으로 빈 생성자가 추가됩니다. 생성자는 기본적으로 실제 열 객체(예: this)를 반환합니다. 생성자는 super 키워드를 사용하여 상위 클래스 생성자를 호출할 수 있습니다.
Attributes
프로토타입 방법: 이 방법은 함수 키워드를 추가할 필요가 없으며 함수 정의를 직접 입력하면 됩니다. 쉼표를 사용하여 메소드를 구분할 수 없습니다. 오류가 보고됩니다.
정적 메서드: static을 사용하여 정적 메서드를 정의하고 정적 메서드를 호출합니다. 클래스의 인스턴스에서는 호출할 수 없으며 클래스를 통해서만 호출할 수 있습니다.
값 함수 getter 및 저장 함수 setter: 클래스의 get 및 set 키워드를 사용하여 특정 속성에 대한 저장 및 값 함수를 설정하고 속성의 액세스 동작을 차단합니다.
클래스 구문:
클래스 선언: 클래스 키워드 사용
class Rectangle{ constructor(height,width){ this.height=height; this.width=width; } }
참고: 함수 선언과 클래스 선언의 차이점: 클래스 선언은 승격되지 않고 함수 선언은 승격됩니다.
클래스 표현식: 클래스 표현식은 이름이 지정되거나 익명으로 지정될 수 있습니다. 명명된 클래스 표현식에 지정된 이름은 클래스 본문의 로컬 이름입니다.
let Rectangle=class{//匿名类 constructor(height,width){ this.height=height; this.width=width; } } let Rectangle= class Rectangle{//命名类 constructor(height,width){ this.height=height; this.width=width; } }
extends를 사용하여 하위 클래스 만들기:
extends 키워드는 클래스 선언이나 클래스 표현식에서 클래스를 다른 클래스의 하위 클래스로 만드는 데 사용됩니다.
super를 사용하여 슈퍼 클래스 호출:
super 키워드는 객체의 상위 객체에 대한 함수를 호출하는 데 사용됩니다.
클래스의 특징:
- 캡슐화: 주로 함수 설정을 통해, 개인 속성 및 메서드 블록 수준 범위를 통해 달성됩니다
- 다형성: 매개변수가 변경될 수 있으므로 함수를 통해 호출할 수 있습니다
- 상속: 주로 프로토타입 체인을 통해
노멀을 새로 만들면 어떻게 되나요? 기능?
생성자의 프로토타입 속성(프라이빗 필드 [[prototype]]과의 차이점 참고)을 프로토타입으로 사용하여 새 개체를 만듭니다.
이 매개변수와 호출 매개변수를 생성자에 전달하고 실행합니다.
생성자가 객체를 반환하면 객체를 반환하고, 그렇지 않으면 첫 번째 단계에서 만든 객체를 반환합니다.
new 이러한 종류의 동작은 함수 객체의 구문을 클래스와 유사하게 만들려고 시도하지만 객관적으로 두 가지 방법을 제공합니다. 하나는 생성자에 속성을 추가하는 것이고, 다른 하나는 프로토타입 속성에 속성을 추가하는 것입니다. 생성자의 속성을 추가합니다.
new 뒤의 함수 이름은 대문자로 써야 하나요?
아니요, 주로 분류의 편의를 위한 것입니다. 일반적인 제약 조건은 대문자입니다.
ProtoType을 이해하는 방법은 객체의 특정 속성을 찾는 것입니까?
prototype:
모든 함수에는 프로토타입 객체[prototype]라는 특수 속성이 있습니다.
js는 프로토타입 기반 언어이며, 객체는 프로토타입을 템플릿으로 사용합니다. 프로토타입의 메소드와 속성. 이러한 속성과 메서드는 객체 인스턴스 자체가 아닌 객체 생성자 위의 프로토타입 특성에 정의됩니다.
프로토타입 개체는 프로토타입 개체를 가질 수 있으며 개체의 프로토타입 개체가 null이 될 때까지 레이어별로 메서드와 속성을 상속받을 수 있습니다.
객체 인스턴스를 생성할 때 객체 인스턴스와 생성자의 프로토타입 속성에서 파생된 해당 생성자 [__proto__ 속성 사이에 링크가 설정됩니다. 즉, __proto__와 생성자의 프로토타입은 동일한 객체를 가리킵니다.] Object.getPrototypeof(new Foobar())와 Foobar.prototype은 동일합니다.
Object.create(). 지정된 프로토타입 개체에서 새 개체를 만듭니다. var newObj=Object.create(obj). 그런 다음 newObj의 __proto__=obj
각 실제 열 개체는 프로토타입에서 생성자 속성을 상속합니다. 이 속성은 이 인스턴스를 생성하는 생성자를 가리킵니다.
일반적으로 속성은 생성자에서 정의되고 메서드는 프로토타입에서 정의됩니다.
一般由构造函数实列化出一个新对象,新对象的原型对象是一个constructor和一个Object的原型对象组成。而函数构造函数的原型对象是也是由另外一个constructor和一个Function的原型对象组成。
var F=function(){}; Object.prototype.a=function(){}; Function.prototype.b=function(){}; var f=new F(); //上面的结果是,f能取到a,不能取到b. 详解: 1.f.__proto__===F.prototype 2.F.prototype.__proto__===Object.prototype(所以f可以访问a) 3.f.constructor===F 4.F.__proto__===Function.prototype(所以f.constructor.b可以访问)
查找属性的过程:
1.先查找自己身属性是否由包含该属性。
2.如果没有,才会沿着原型链,层层向上搜索,直到找到名字的属性
3.如果找到最后原型链的末尾,即最后的原型为null,那就是没有找到该属性。就会返回undefined
不同方法创建对象和原型链
1.使用语法结构创建对象
var o = {a: 1}; // o 这个对象继承了 Object.prototype 上面的所有属性 // o 自身没有名为 hasOwnProperty 的属性 // hasOwnProperty 是 Object.prototype 的属性 // 因此 o 继承了 Object.prototype 的 hasOwnProperty // Object.prototype 的原型为 null // 原型链如下: // o ---> Object.prototype ---> null var a = ["yo", "whadup", "?"]; // 数组都继承于 Array.prototype // (Array.prototype 中包含 indexOf, forEach 等方法) // 原型链如下: // a ---> Array.prototype ---> Object.prototype ---> null function f(){ return 2; } // 函数都继承于 Function.prototype // (Function.prototype 中包含 call, bind等方法) // 原型链如下: // f ---> Function.prototype ---> Object.prototype ---> null
2.使用构造函数创建对象
function A() { this.a = 1; this.b = 2; } A.prototype = { write: function(){ console.log(this.a); } }; var a = new A(); // a 是生成的对象,他的自身属性有 'a' 和 'b'。
3.使用Object.create()创建对象(ES5)
var a = {a: 1}; // a ---> Object.prototype ---> null var b = Object.create(a); // b ---> a ---> Object.prototype ---> null console.log(b.a); // 1 (继承而来) var c = Object.create(b); // c ---> b ---> a ---> Object.prototype ---> null var d = Object.create(null); // d ---> null console.log(d.hasOwnProperty); // undefined, 因为d没有继承Object.prototype 使用
4.使用class创建对象(ES6)
class A { constructor(a, b) { this.a = a; this.b = b; } } class B extends A { constructor(a,b,c) { super(a, b); this.c=c; } get ab() { return this.a + this.b; } set d(d) { this.a = d; this.b = d; this.c = d; } } var a= new A('a','b');//a的原型对象是 A.prototype var b = new B('a','b','c');// //b的原型对象是 B.prototype
当一个对象设置属性时都发生了什么?
如果对象包含普通数据访问属性,直接赋值只会修改属性值
var a={b=1}//因为b是a的普通属性,数据类型为Number
a.b="a"; //直接更改b的类型为String,且赋值为'a'.
如果对象找不到该属性,且原型链也找不到,就直接默认添加一个属性到该对象上。
var a={}//b不是a的普通属性,且原型链上也没有
a.b="a"; //直接在a上添加b的类型,为String,且赋值为'a'.
如果属性b,存在于原型链上
//在原型链上层存在名为b的普通数据访问属性并且没有标记为只读(writable:false),那就会直接在a中添加一个名为b的新属性,且值为'a'。而原型链上的b就会被屏蔽掉:
function A(){}; A.prototype.b=1; var a=new A(); a.b='a';
//在原型链上层存在b,但是他被标记为只读,那么无法修改已有属性,或者在a中创建屏蔽属性。如果运行在严格模式下,代码会抛出一个错误,否则,这条赋值语句会被忽略,总之,不会发生屏蔽。
function A(){ }; A.prototype.b=1 Object.defineProperty(A.prototype,'b',{ configurable:true, writable:false }) var a=new A(); a.b='a';//结果a.b还是1
【相关推荐:javascript学习教程】
위 내용은 프로토타입 객체의 JavaScript 학습 요약(구성 및 공유)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!