Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScirpt之原型&原型对象和原型链 #1

Open
heyushuo opened this issue Dec 27, 2019 · 0 comments
Open

JavaScirpt之原型&原型对象和原型链 #1

heyushuo opened this issue Dec 27, 2019 · 0 comments

Comments

@heyushuo
Copy link
Owner

一.什么是原型呢?

我们创建每一个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象.(即 prototype 即为函数的原型该原型指向的是一个原型对象)

二.什么是原型对象呢?

  • 我们创建每一个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象(即原型对象).而这个对象的用途是包含
    可以由特定类型的所有 实例 共享的属性和方法.(字面意思 prototype 就是通过调用构造函数而创建的实例对象的原型对象)
  • 使用原型对象的好处是可以让所有的对象实例(实例对象)共享他包含的所有的属性和方法
  • 需要特别注意的是原型对象的理解,只要创建一个函数,该函数就会创建一个 prototype(原型)属性,这个属性指向函数的原型对象

三.原型对象和原型的关系?

1.proto是什么呢?

  • 这是每一个 JavaScript 对象(除了 null )都具有的一个属性,叫proto,这个属性会指向该对象的原型。
  • 当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性即proto),指向构造函数的原型对象

2.  constructor 是什么呢?

  • 在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性包含一个指向 prototype 属性所在函数的指针即(Person.prototype.constructor 指向 Person),而通过这个构造函数,我们可以继续为原型对象添加起他属性和方法

通过一张图片和代码展示他们之间的关系

//创建一个构造函数,并在构造函数的原型上添加一个name属性
function Person() {}
Person.prototype.name = "kebi";
var person1 = new Person();
console.log(person1.name); //kebi
var perso2 = new Person();
console.log(person2.name); //kebi
console.log(person.__proto__ === Person.prototype); // true 他两个的关系也是完全相等的

console.log(Person.prototype.constructor == Person); // true
// 顺便学习一个ES5的方法,可以获得对象的原型
console.log(Object.getPrototypeOf(person) === Person.prototype); // true
//b.isPrototypeOf(a)    这个方法的意思是,a对象是否指向b对象
Person.prototype.isPrototypeOf(person1); //true    因为person1中有一个__proto__属相指向原型对象(Person.prototype)
Person.prototype.isPrototypeOf(person2); //true   同理

3.总结一下 prototype 和__proto__到底是什么关系呢?

  • 函数对象的 prototype 属性, 可以称之为显式原型属性(简称: 显式原型)
  • 实例对象的__proto__属性, 可以称之为隐式原型属性(简称: 隐式原型)
  • 原型对象: 也就是 prototype 属性和__proto__属性指向的对象

四.什么是原型链?

1.原型的搜索机制

  • 当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。
  • 代码例子

function Person() {}

Person.prototype.name = "heyushuo";

var person = new Person();

person.name = "kebi";
console.log(person.name); // kebi

delete person.name;
console.log(person.name); //heyushuo

在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 kebi。

但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.__proto__,也就是 Person.prototype 中查找 (原型对象中),幸运的是我们找到了 name 属性,结果为 heyushuo。

但是万一还没有找到呢?原型的原型又是什么呢? ( 肯定需要一环一环地前行到原型链的末端才会停下来)

2.最顶层为默认的原型

所有的函数的默认原型都是 Object 的实例,所以默认原型都会包含一个内部指针,指向 Object.prototype(默认原型的原型对象),这也真是所有自定义类型都会继承 toString()/valueOf 等默认的方法的根本原因.一直查到最顶层才算一个完整的原型链

如图所示: 蓝色线为完整的原型链

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant