ECMAScript原型与原型链(二)

虽然ES6虽然引入了class关键字,但是,JavaScript关于类的概念任然是基于原型。

JavaScript关于属性和方法的复用和继承,都是通过对象,通过实例对象实现对构造函数的属性和方法的复用。

1. 构造函数

  1. 函数是JavaScript的一等公民,构造函数与普通函数并没有什么区别,只有当函数通过new关键字调用时,才称之为构造函数;

  2. 通常将构造函数的首字母大写,以显示与普通函数的区别;

  • new关键字调用便创建了实例对象;

    function Person() {}
    const person = new Person()
    
  • Person就是一个构造函数

  • person就是构造函数Person创建的实例对象

2. 原型对象

  • JavaScript的构造函数实例化一个对象的同时,具有一个属性: prototype, 称之为构造函数的原型对象。

    function Person() {};
    const person = new Person();
    console.log(Person.prototype);  
    
2.1 prototype具有两个属性
  1. constructor属性

constructor属性指向了构造函数自身;

console.log(Person.prototype.constructor === Peron);     //true
  1. __proto__属性
  • 原型对象的__proto__属性并不是像它的实例对象person的__proto__属性,实例对象的__proto__属性指向其构造函数的原型对象,而原型对象的__proto__属性,指向的是Object的对象原型,而非Person构造函数Function的原型对象;

    function Person()  {};
    const person = new Person()
    //Person的构造函数Function
    console.log(Person.constructor === Function); //true
    console.log(Person.__proto__ === Function.prototype); //true
    
    console.log(Person.prototype.__proto__ === Object.prototype); //true  
    
  • 由于prototype采用递归算法,该原型对象也有一个自己的属性(__proto__) ,
    原型对象正是利用了递归算法和__proto__属性,实现了对象属性和方法的继承;

function Person() {}
const person = new Person()
Object.prototype.msg = "落霞与孤鹜齐飞 秋水共长天一色";
console.log(person.msg);

3. 原型链

  • JavaScript 对象有一个指向原型对象的链,当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该原型对象,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾;
function Person() {};
const person = new Person();
console.log(Person.prototype.__proto__ === Object.prototype);  //true
console.log(Object.prototype.__proto__); //null
  • person访问属性时,首先在自身查找,如果查找不到就会通过person.__proto__到对象原型Proson.prototype上找,

  • 如果找不到,就会通过Person.prototype.__proto__向上一级原型对象查找,

  • 最后查找Object.prototype对象原型查找;

  • Object.prototype.__proto__返回null时,结束查找;

  • 通过__proto_向上查找属性的链称之为原型链。

原型与原型链

  • 可以看出构造函数Object、Person并没有太多的分别,它们同为Function的实例对象;

  • JavaScript设计时并不是将原型链末端交给原型对象(Function.prototype),而是由Object原型对象(Object.prototype)承担;

function Person() {};
const person = new Person();
console.log(Person.prototype.__proto__ === Object.prototype); //true
console.log(Object.prototype.__proto__); //null
console.log(Object.constructor === Function); //true
console.log(Object.prototype.__proto__ === Function.__prototype); //false
console.log(Person.constructor === Function); //true
console.log(Person.prototype.__proto__ === Function.__prototype); //false
  • 我们不妨看看Function身后有什么?
console.log(Function.constructor === Function); //true
console.log(Function.prototype.constructor === Function);  //true
总结

这就是原型对象的终极“

  • 实例对象通过__proto__关联上其构造函数的对象原型,进而通过对象原型的__proto__与上一级构造函数之的原型对象的__proto__关联,直至Object.prorotype.__proto__=null为止,结束属性查找。
  • 原型链就是通过这条关联关系实现了对象属性的继承。

参考文档

ECMAScript原型与原型链(一)

ECMAScript原型与原型链(三)

联系方式

联系方式

Email:yuanmin8888@outlook.com

微信: 微信二维码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Javascript 原型链Javascript 的一项特性,用于实现继承和属性查找。 在 Javascript 中,每个对象都有一个内部属性 `[[Prototype]]`,也称为原型。这个原型可以是另一个对象,它充当了当前对象的模板,包含了当前对象没有的属性和方法。如果我们想要访问一个对象中不存在的属性或方法,Javascript 引擎会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的顶端为止。 例如,假设有一个对象 `obj`,它的原型是另一个对象 `proto`,而 `proto` 的原型又是另一个对象 `grandProto`,那么当我们访问 `obj` 中的一个属性时,Javascript 引擎会先在 `obj` 中查找,如果找不到,就去 `proto` 中查找,还找不到就去 `grandProto` 中查找,以此类推,直到找到该属性或者到达原型链的顶端为止。 Javascript 中的原型链是通过 `__proto__` 属性来实现的。每个对象都有一个 `__proto__` 属性,它指向该对象的原型。在 ECMAScript 6 中,我们可以使用 `Object.getPrototypeOf()` 方法获取一个对象的原型,而在早期版本的 Javascript 中,则可以通过 `__proto__` 属性来获取。 除了 `__proto__` 属性外,Javascript 还提供了一种创建对象的方式,即构造函数。构造函数可以用来创建一个对象,并且可以设置该对象的属性和方法。当我们使用 `new` 关键字调用构造函数时,Javascript 引擎会自动为该对象创建一个 `__proto__` 属性,并将其指向构造函数的 `prototype` 属性。 例如,假设我们有一个构造函数 `Person`,它有一个属性 `name` 和一个方法 `sayHello`: ``` function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log('Hello, my name is ' + this.name); } ``` 当我们使用 `new` 关键字调用 `Person` 构造函数时,Javascript 引擎会创建一个新的对象,并将其 `__proto__` 属性指向 `Person.prototype`,然后调用构造函数,将 `name` 属性设置为传入的参数。最后返回该对象: ``` var person = new Person('John'); ``` 此时 `person.__proto__ === Person.prototype`,而 `Person.prototype.__proto__ === Object.prototype`,因此 `person` 对象的原型链可以表示为: ``` person -> Person.prototype -> Object.prototype -> null ``` 通过原型链,`person` 对象可以访问到 `Person.prototype` 中定义的 `sayHello` 方法以及 `Object.prototype` 中定义的其他方法和属性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值