>  기사  >  웹 프론트엔드  >  JavaScript 상속 및 프로토타입 체인

JavaScript 상속 및 프로토타입 체인

php中世界最好的语言
php中世界最好的语言원래의
2018-03-19 17:16:351810검색

이번에는 JavaScript 상속 및 프로토타입 체인에 대해 알려드리겠습니다. JavaScript 상속 및 프로토타입 체인 사용 시 주의 사항은 무엇인가요? 실제 사례를 살펴보겠습니다.

최근에 WeChat 미니 프로그램을 시청하고 있습니다. 오후에는 js의 기본 체인을 따라잡기 위해 js의 프로토타입 체인 상속을 살펴보고 싶습니다.

最近一直在看微信小程序,下午换换胃口看看js的原型链继承,补补js的基础

JavaScript对象有一个指向一个原型对象的链,当试图访问一个对象的属性的时候,他不仅仅会在该对象上面搜寻,还会搜寻该对象的原型,以及对象的原型的原型,依次层层搜索,直到找到名字匹配的属性或者到达原型链的末端

// 让我们假设我们有一个对象 o, 其有自己的属性 a 和 b:// {a: 1, b: 2}// o 的 [[Prototype]] 有属性 b 和 c:// {b: 3, c: 4}// 最后, o.[[Prototype]].[[Prototype]] 是 null.// 这就是原型链的末尾,即 null,// 根据定义,null 没有[[Prototype]].// 综上,整个原型链如下: // {a:1, b:2} ---> {b:3, c:4} ---> nullconsole.log(o.a); // 1// a是o的自身属性吗?是的,该属性的值为1console.log(o.b); // 2// b是o的自身属性吗?是的,该属性的值为2// 原型上也有一个'b'属性,但是它不会被访问到.这种情况称为"属性遮蔽 (property shadowing)"console.log(o.c); // 4// c是o的自身属性吗?不是,那看看原型上有没有// c是o.[[Prototype]]的属性吗?是的,该属性的值为4console.log(o.d); // undefined// d是o的自身属性吗?不是,那看看原型上有没有// d是o.[[Prototype]]的属性吗?不是,那看看它的原型上有没有// o.[[Prototype]].[[Prototype]] 为 null,停止搜索// 没有d属性,返回undefined

继承方法

当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。

var o = {
  a: 2,
  m: function(){
    return this.a + 1;
  }};console.log(o.m()); // 3// 当调用 o.m 时,'this'指向了o.var p = Object.create(o);// p是一个继承自 o 的对象p.a = 4; // 创建 p 的自身属性 aconsole.log(p.m()); // 5// 调用 p.m 时, 'this'指向 p. // 又因为 p 继承 o 的 m 函数// 此时的'this.a' 即 p.a,即 p 的自身属性 'a'

使用不同的方法来创建对象和生成原型链

语法结构创建的对象

var o = {a: 1};// o 这个对象继承了Object.prototype上面的所有属性// o 自身没有名为 hasOwnProperty 的属性// hasOwnProperty 是 Object.prototype 的属性// 因此 o 继承了 Object.prototype 的 hasOwnProperty// Object.prototype 的原型为 null// 原型链如下:// o ---> Object.prototype ---> nullvar a = ["yo", "whadup", "?"];// 数组都继承于 Array.prototype // (Array.prototype 中包含 indexOf, forEach等方法)// 原型链如下:// a ---> Array.prototype ---> Object.prototype ---> nullfunction f(){
  return 2;}// 函数都继承于Function.prototype// (Function.prototype 中包含 call, bind等方法)// 原型链如下:// f ---> Function.prototype ---> Object.prototype ---> null

构造器创建的对象

在 JavaScript 中,构造器其实就是一个普通的函数。当使用 new 操作符 来作用这个函数时,它就可以被称为构造方法构造函数)。

function Graph() {
  this.vertices = [];
  this.edges = [];
}
Graph.prototype = {
  addVertex: function(v){
    this.vertices.push(v);
  }
};
var g = new Graph();
// g是生成的对象,他的自身属性有'vertices'和'edges'.
// 在g被实例化时,g.[[Prototype]]指向了Graph.prototype.

Object.create 创建的对象

ECMAScript 5 中引入了一个新方法:Object.create()。可以调用这个方法来创建一个新对象。新对象的原型就是调用 create 方法时传入的第一个参数:

var a = {a: 1}; // a ---> Object.prototype ---> nullvar b = Object.create(a);// b ---> a ---> Object.prototype ---> nullconsole.log(b.a); // 1 (继承而来)var c = Object.create(b);// c ---> b ---> a ---> Object.prototype ---> nullvar d = Object.create(null);// d ---> nullconsole.log(d.hasOwnProperty); // undefined, 因为d没有继承Object.prototype

class 关键字创建的对象

ECMAScript6 引入了一套新的关键字用来实现 class。使用基于类语言的开发人员会对这些结构感到熟悉,但它们是不同的。JavaScript 仍然基于原型。这些新的关键字包括 class, constructorstaticextendssuper

"use strict";class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
    console.log(height)    //2
  }}class Square extends Polygon {
  constructor(sideLength) {
    super(sideLength, sideLength);
  }
  get area() {
    return this.height * this.width;
  }
  set sideLength(newLength) {
    this.height = newLength;
    this.width = newLength;
  }}var square = new Square(2);

性能

function Graph() {
  this.vertices = [];
  this.edges = [];}Graph.prototype = {
  addVertex: function(v){
    this.vertices.push(v);
  }};var g = new Graph();console.log(g.hasOwnProperty('vertices'));// trueconsole.log(g.hasOwnProperty('nope'));// falseconsole.log(g.hasOwnProperty('addVertex'));// falseconsole.log(g.proto.hasOwnProperty('addVertex'));// true

hasOwnProperty 是 JavaScript 中唯一处理属性并且不会遍历原型链的方法。

因此,当你执行:

var o = new Foo();

JavaScript 实际上执行的是(或者大致这样):

var o = new Object();
o._proto_ = Foo.prototype;
Foo.call(0)
o.someProp;

它检查o是否具有someProp属性。

如果没有,它会查找 Object.getPrototypeOf(o).someProp

如果仍旧没有,它会继续查找 Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp

ps:

Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]JavaScript 객체

에는 객체의 속성에 액세스하려고 할 때 프로토타입 객체를 가리키는 체인이 있습니다. , 객체에 대한 검색뿐만 아니라 객체의 프로토타입뿐만 아니라 객체의 프로토타입도 검색하고 일치하는 이름을 가진 속성을 찾거나 끝에 도달할 때까지 레이어별로 검색합니다. 프로토타입 체인

var proto = {};
var obj = Object.create(proto);
var a= Object.getPrototypeOf(obj)
console.log(a); {}

상속된 메서드 h3>상속된 함수가 호출되면 는 현재 상속된 객체를 가리킵니다. , 상속된 함수가 있는 프로토타입 객체가 아닙니다.

rrreee

다양한 방법을 사용하여 객체 생성 및 프로토타입 체인 생성

구문 구조 생성 객체

rrreee

생성자에 의해 생성된 개체

JavaScript에서 생성자는 실제로 일반 함수입니다. 이 함수에 대해 new 연산자를 사용하면 생성자 메서드

(생성자

).

rrreee

Object.create

로 생성된 객체ECMAScript 5에는 Object.create() 라는 새로운 메서드가 도입되었습니다. 코드>. 이 메소드를 호출하여 새 객체를 생성할 수 있습니다. 새 개체의 프로토타입은 <code>create 메서드를 호출할 때 전달되는 첫 번째 매개변수입니다. rrreee

class 키워드 생성 객체


ECMAScript6에는 클래스를 구현하기 위한 새로운 키워드 세트가 도입되었습니다. 이러한 구성은 클래스 기반 언어를 사용하는 개발자에게는 익숙하지만 다릅니다. JavaScript는 여전히 프로토타입을 기반으로 합니다. 이러한 새로운 키워드에는 class, constructor, static, extendssuper가 포함됩니다. rrreee

성능

rrreee

hasOwnProperty는 JavaScript에서 프로토타입 체인을 순회하지 않고 속성을 처리할 수 있는 유일한 방법입니다. 따라서 실행할 때:
rrreee

JavaScript는 실제로 실행됩니다(또는 이와 유사한 것): 🎜rrreeerrreee
🎜o에 someProp 속성. 🎜🎜그렇지 않으면 Object.getPrototypeOf(o).someProp을 찾고, 🎜🎜아직도 그렇지 않다면 계속해서 Object.getPrototypeOf(Object.getPrototypeOf(o)를 찾습니다. ).someProp . 🎜
🎜ps:🎜🎜Object.getPrototypeOf() 메서드는 지정된 객체의 프로토타입(내부 [[Prototype]] 속성의 값)을 반환합니다. ). 🎜rrreee🎜좋다고 생각하시면 MDN을 방문해 주세요🎜🎜이 기사의 사례를 읽으신 후 방법을 마스터하셨다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요! 🎜🎜추천 도서: 🎜🎜🎜React에는 어떤 클래스 정의 구성요소가 있나요?🎜🎜🎜🎜🎜ajax 연구 노트🎜🎜🎜

위 내용은 JavaScript 상속 및 프로토타입 체인의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.