十一、JavaScript 原型和原型链

一、原型

prototype就是英语“原型”的意思。原型是构造函数创建对象的原始模型

原型的特点:

  • 原型也是对象,原型是函数对象的一个属性。
  • 原型自带constructor属性, constructor指定构造函数。
  • 构造函数创建出的对象会继承原型的属性和方法。

在JavaScript中,任何一个函数,都有一个prototype属性,指向一个对象。打印prototype属性,你会发现这个属性指向一个空对象。打印prototype的类型,发现是object类型。

1.构造函数中prototype

在传统的 OOP 中,首先定义“类”,此后创建对象实例时,类中定义的所有属性和方法都被复制到实例中。在 JavaScript 中并不如此复制,而是在对象实例和它的构造器之间建立一个链接(它是__proto__属性,是从构造函数的prototype属性派生的),之后通过上溯原型链,在构造器中找到这些属性和方法。

1. 每个函数上面都有一个属性(prototype)指向了函数的原型对象(Person.prototype)。

代码例:👇

 <script>
    function Person (name){
      this.name = name;
      this.sayhai = function(){
        console.log('我的名字叫'+this.name);
      }
    }
    Person.prototype.eat = function(){
      console.log('会吃饭')
    }
    let a = new Person('zs');
    console.log(a)
  </script>

图解:👇

 当一个对象被new出来的时候,不仅仅执行了构造函数里面的语句,我们的感觉,构造函数的原型中,所有的属性也加给了这个对象

prototype一定是函数的属性,但这个函数是一个构造函数的时候,那么它new出来的对象,将以他的原型那个对象为new出来的实例的原型对象

2.实例中__proto__属性

实例中的__proto__指向的是原型对象

当一个对象被new出来的时候,不仅仅执行构造函数的语句,也会吧这个函数的__proto _ 指向构造函数的prototype

如上面的代码所示

a.__proto__👇

 

注意:

任何一个对象,都有__proto__属性,这个属性是Chrome自己的属性,别的浏览器不兼容,但是别的浏览器也有原型对象,只不过不能通过__proto__进行访问而已。

这是属性指向自己的原型对象。

3.原型的终点就是null

JS的世界中只有一个对象没有原型对象,这个对象就是Object.prototype。

Object是一个函数,是系统内置的构造函数,用于创造对象的。Object.prototype是所有对象的原型链终点。

所以,当我们在一个对象上打点调用某个方法的时候,系统会沿着原型链去寻找它的定义,一直找到Object.prototype。

特别的:

prototype我们称为“原型”,只有函数有原型。

__proto__我们称为“原型对象”,任何对象都有原型对象。

二、原型链

只要是对象,一定有原型对象,就是说只要这个东西是个对象,那么一定有__proto__属性。

我们想实例的原型对象也是一个对象,那么我们迫切的想看看这个原型对象的原型对象.如果这理论没有问题的话,这个原型对象应该也有__proto__指向他的原型对象吧.

function Student(){
    
}
var xiaoming = new Student();
// 原型对象的原型对象
console.log(xiaoming.__proto__.__proto__);
// 原型对象的原型对象的构造函数是谁
console.log(xiaoming.__proto__.__proto__.constructor); //Object

// 那我们看看还能不不能再向上查原型对象
console.log(xiaoming.__proto__.__proto__.__proto__);
// 结果为null

通过上面的示例, 发现开始的一句话其实是错误的.

JS的世界中只有一个对象没有原型对象,这个对象就是Object.prototype。

现在就能想明白一些事情,一个对象天生带一些属性和方法

比如:

function Student(){
    
}
var xiaoming = new Student();
// 小白马上可以调用toString()方法
console.log(xiaoming.toString());
// 打印 "[object Object]"

// 这个方法是小明原型对象的原型对象身上的方法,我们可以看下
console.log(xiaoming.__proto__.__proto__);

Object是一个函数,是系统内置的构造函数,用于创造对象的。Object.prototype是所有对象的原型链终点。

所以,当我们在一个对象上打点调用某个方法的时候,系统会沿着原型链去寻找它的定义,一直找到Object.prototype。

Object.prototype是所有对象原型链的终点,现在我强行给它添加一个属性

Object.prototype.sayHello = function(){
    alert("你好")
}
// 现在小明能sayHello
xiaoming.sayHello();

// 岂止xiaoming能sayHello 数组也能sayHello
var arr = [1,2,3];
arr.sayHello();

// 然后世界上一切都能sayHello了
"么么哒".sayHello();

无奈源于不够强大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值