解读Vue的原型及原型链

本文详细介绍了JavaScript中的原型与原型链概念,包括原型对象的使用、原型链的工作原理、构造函数与原型链的关系,以及如何通过原型链实现继承。同时,特别关注了Vue.js中的原型链应用,展示了其在全局方法和实例属性访问中的作用。
摘要由CSDN通过智能技术生成

在 JavaScript 中,每个对象都有一个关联的原型(prototype)。原型是一个对象,其他对象可以通过原型实现属性和方法的继承。原型链是一种由对象组成的链式结构,它通过原型的引用连接了一系列对象,形成了一种继承关系。

在学习原型和原型链之前,我们需要首先掌握以下三个属性:

  • prototype: 每一个函数都有一个特殊的属性,叫做原型(prototype)
  • constructor: 相比于普通对象的属性,prototype属性本身会有一个属性constructor,该属性的值为prototype所在的函数
  • __proto__: 每一个对象都有一个__proto__属性,该属性指向对象(实例)所属构造函数(类)的原型prototype

原型(Prototype):

每个 JavaScript 对象都有一个原型对象,它用于查找对象的属性和方法。对象可以通过 __proto__ 属性访问它的原型。在 ES6 中,可以使用 Object.getPrototypeOf() 方法获取对象的原型。

const myObject = {};
const myPrototype = Object.getPrototypeOf(myObject);

console.log(myPrototype === Object.prototype);  // 输出: true

原型链(Prototype Chain):

原型链是一种对象之间通过原型引用连接起来的链式结构。当我们访问一个对象的属性或方法时,JavaScript 引擎首先在该对象本身查找,如果找不到,则会沿着原型链向上查找,直到找到对应的属性或方法,或者查找到达原型链的顶端(Object.prototype)。

function Animal(name) {
  this.name = name;
}

Animal.prototype.sayHello = function() {
  console.log(`Hello, I'm ${this.name}`);
};

const cat = new Animal('Whiskers');
cat.sayHello(); // 输出: Hello, I'm Whiskers

在上述例子中,cat 对象的原型是 Animal.prototypeAnimal.prototype 的原型是 Object.prototype。因此,当调用 sayHello 方法时,JavaScript 引擎首先在 cat 对象中查找,找不到的话就沿着原型链向上查找,最终在 Animal.prototype 中找到了 sayHello 方法。

原型链的终点:

原型链的终点是 Object.prototype,它是所有对象的根原型。Object.prototype 没有自己的原型,形成了原型链的终点。

构造函数与原型链:

通过构造函数创建的对象共享同一个原型。当我们创建一个新对象时,它的原型会指向构造函数的原型对象。

function Car(make, model) {
  this.make = make;
  this.model = model;
}

Car.prototype.drive = function() {
  console.log('Vroom!');
};

const myCar = new Car('Toyota', 'Camry');
myCar.drive(); // 输出: Vroom!

在上述例子中,myCar 对象的原型是 Car.prototype,而 Car.prototype 的原型是 Object.prototype,形成了原型链。

继承与原型链:

通过原型链,可以实现对象之间的继承。一个对象可以继承另一个对象的属性和方法,从而减少代码冗余。

function Bird(name) {
  this.name = name;
}

Bird.prototype.fly = function() {
  console.log(`${this.name} is flying.`);
};

function Penguin(name) {
  Bird.call(this, name);
}

Penguin.prototype = Object.create(Bird.prototype);
Penguin.prototype.constructor = Penguin;

Penguin.prototype.swim = function() {
  console.log(`${this.name} is swimming.`);
};

const penguin = new Penguin('Happy Feet');
penguin.fly();  // 输出: Happy Feet is flying.
penguin.swim(); // 输出: Happy Feet is swimming.

在上述例子中,Penguin 构造函数通过 Bird.call(this, name) 继承了 Bird 构造函数的属性。然后,通过 Object.create(Bird.prototype) 创建了一个新对象,将其设置为 Penguin.prototype,从而继承了 Bird.prototype 中的方法。最后,将 Penguin.prototype.constructor 设置为 Penguin,确保正确指向构造函数。这样,Penguin 对象就能够继承 Bird 对象的方法。

Vue进阶:

在 Vue.js 2 中,原型链主要用于两个方面:全局方法和实例属性的访问。

1. 全局方法的访问:

Vue.js 在其原型链上定义了一些全局方法,可以通过实例对象或者全局引用来调用。例如,$emit$on 等方法。

// 在组件中使用
export default {
  methods: {
    handleClick() {
      this.$emit('custom-event', 'Hello from child!');
    }
  }
};

// 在全局使用
Vue.prototype.$myGlobalMethod = function() {
  console.log('This is a global method!');
};

// 然后在任何组件中
this.$myGlobalMethod();

2. 实例属性的访问:

在 Vue.js 2 中,实例对象上有一些特定的属性,可以通过原型链访问。

// 创建 Vue 实例
const vm = new Vue({
  data: {
    message: 'Hello, Vue!'
  }
});

// 访问实例的属性
console.log(vm.$data.message); // 输出: Hello, Vue!

上述代码中,vm.$data.message 中的 $data 就是通过原型链访问到实例对象的属性。同样,还有其他一些实例属性,如 $props$el$options 等,它们可以提供对实例的不同方面的访问。

总的来说,原型链在 Vue.js 2 中主要用于提供全局方法和实例属性的访问。这样的设计使得在组件中可以方便地使用一些全局方法,同时也让开发者能够通过实例对象访问一些特定的实例属性。

3、Vue是一个函数

Vue 3中,使用原型链的方式与Vue 2有所不同。在Vue 3中,你可以使用`app.config.globalProperties`来添加全局属性或方法到Vue实例的原型链上。 具体使用方法如下: 1. 在`main.js`中创建Vue实例时,可以通过`app.config.globalProperties`来添加全局属性和方法。例如,如果你想在Vue实例上添加一个名为`$EventBus`的全局事件总线,可以这样写: ```javascript import { createApp } from 'vue'; import App from './App.vue'; const app = createApp(App); app.config.globalProperties.$EventBus = new Vue(); app.mount('#app'); ``` 2. 然后,在任何Vue组件中,你都可以通过`this.$EventBus`来访问全局事件总线,并使用其提供的方法进行事件的触发和监听。例如,在一个组件中可以这样使用: ```javascript export default { mounted() { this.$EventBus.$emit('event-name', data); }, methods: { handleEvent(data) { // 处理事件 } }, created() { this.$EventBus.$on('event-name', this.handleEvent); } } ``` 通过以上方法,你可以在Vue 3中使用原型链来添加全局属性和方法,并实现组件间的通信。注意,Vue 3中的`createApp`函数代替了Vue 2中的`new Vue()`,其他部分的用法基本相同。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Vue中关于JS原型链的应用](https://blog.csdn.net/qq_38802910/article/details/125884336)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Vue3、Vue2原型链挂载区别与实战举例](https://blog.csdn.net/qq_43547255/article/details/125925863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩小浪~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值