原型对象与vue

449 阅读5分钟

原型 prototype__proto__

  • 对于使用过基于类的语言 (如 Java 或 C++) 的开发者们来说,JavaScript 实在是有些令人困惑 —— JavaScript 是动态的,本身不提供一个 class 的实现。即便是在 ES2015/ES6 中引入了 class 关键字,但那也只是语法糖,JavaScript 仍然是基于原型的。

  • 每个对象都有一个__proto__属性,并且指向它的prototype原型对象

  • 每个构造函数都有一个prototype原型对象

    • prototype原型对象里的constructor指向构造函数本身

img

有的同学可能会问prototype__proto__有什么用呢?

实例对象的__proto__指向构造函数的prototype,从而实现继承。

prototype对象相当于特定类型所有实例对象都可以访问的公共容器

img

看一下代码就清楚了

function Person(nick, age){
    this.nick = nick;
    this.age = age;
}
Person.prototype.sayName = function(){
    console.log(this.nick);
}

var p1 = new Person('Byron', 20);
var p2 = new Person('Casper', 25);
p1.sayName()  // Byron
p2.sayName()  // Casper
p1.__proto__ === Person.prototype       //true
p2.__proto__ === Person.prototype   //true
p1.__proto__ === p2.__proto__           //true
Person.prototype.constructor === Person  //true

注意

  1. Object.prototype.__proto__ 已被大多数浏览器厂商所支持的今天,其存在和确切行为仅在ECMAScript 2015规范中被标准化为传统功能,以确保Web浏览器的兼容性。为了更好的支持,建议只使用 Object.getPrototypeOf()
  2. Object.create(null) 新建的对象是没有__proto__属性的。

原型链

请看以下代码

var arr = [1,2,3]
arr.valueOf()  //  [1, 2, 3]

我们再来看一张图

console.dir(arr)

img

按照之前的理论,如果自身没有该方法,我们应该去Array.prototype对象里去找,但是你会发现arr.__proto__上压根就没有valueOf方法,那它是从哪里来的呢?

各位,请看这张图

img

很奇怪我们在Array.prototype.__proto__里找到了valueOf方法,为什么呢?

查找valueOf方法的过程

当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

查找valueOf大致流程

  1. 当前实例对象obj,查找obj的属性或方法,找到后返回
  2. 没有找到,通过obj. __proto__,找到obj构造函数的prototype并且查找上面的属性和方法,找到后返回
  3. 没有找到,把Array.prototype当做obj,重复以上步骤

当然不会一直找下去,原型链是有终点的,最后查找到Object.prototypeObject.prototype.__proto__ === null,意味着查找结束

img

我们来看看上图的关系

arr.__proto__ === Array.prototype
true
Array.prototype.__proto__ === Object.prototype
true
arr.__proto__.__proto__ === Object.prototype
true

// 原型链的终点
Object.prototype.__proto__ === null
true

原型链如下:

arr --__proto__--> Array.prototype --__proto__--> Object.prototype --__proto__--> null

这就是传说中的原型链,层层向上查找,最后还没有就返回undefined

实现数组去重

includes()方法来判断一个数组是否包含一个指定的值,根据情况,如果包含就返回true,不包含就返回false

var arr = [1,1,15,15,true,false,true,false,NaN,0,"0"]
function fn(arr){
	if(!Array.isArray(arr)){
		cosloe.log('type error!')
		return
	}
var array = []
for(var i = 0; i < arr.length; i++){
		if(!array.includes(arr[i])){
		array.push(arr[i])
		}
	}
	return array
}
console.log(fn(arr))
//(7) [1, 15, true, false, NaN, 0, "0"]

总结

prototype__proto__

  • 每个对象都有一个__proto__属性,并且指向它的prototype原型对象

  • 每个构造函数都有一个prototype原型对象

    • prototype原型对象里的constructor指向构造函数本身

原型链

每个实例对象(object)都有一个私有属性(称之为 proto)指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

Vue 的特点

1.遵循MVVM模式 2.编码简洁,体积小,运行效率高,适合移动/PC端开发 3.它本身只关注 UI,可以引入其它第三方库开发项目 4.采用组件化模式,提高代码复用率、且让代码更好维护

image-20220627112112058

5.使用虚拟DOMDiff算法,尽量复用DOM节点

image-20220627112235934

Vue中的MVVM模型

1.什么是MVVM?

MVVM是Model-View-ViewModel(模型-视图-视图模型)的简写,是M - V - VM 三部分组成。

本质:是MVC改进版

MVVM就是将其中View的状态和行为抽象化,其中ViewModel将视图(即View)和业务逻辑分开,它可以去除Model的数据的同时帮忙处理View中由于需要展示内容而涉及的业务逻辑。

MVVM采用:双向数据绑定

View中数据变化将自动反映到Model上,反之,Model中数据变化也将会自动展示在页面上。

ViewModel就是View和Model的桥梁。

ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回到Model。

MVVM的核心思想:是关注Model的变化。让MVVM框架利用自己的机制自动更新DOM(即所说的View视图),也就是所谓的数据-视图分离。

2.MVVM模型

M:模型Model --->也就是data中的数据 V:视图View --->也就是模板代码 VM:视图模型ViewModel --->也就是Vue实例(vm)

3.举例:对上面的MVVM模型更透彻的理解

image-20230514134556133

image-20230514134627093

image-20230514134656671

先给大家展示一下运行的效果(原本):

image-20230514134715009

再给大家展示一下,我再页面上的输入框中添加‘123456’然后会发现Model模型中的data数据发生了变化(改变后):

image-20230514134729777

npm run build

npm run serve

组件

1.模块与组件、模块化与组件化

image-20220630165421117

模块

  1. 理解:向外提供特定功能的 js 程序,一般就是一个 js 文件

  2. 为什么:js 文件很多很复杂

  3. 作用:复用、简化 js 的编写,提高 js 运行效率

    image-20220630165433920

组件

  1. 定义:用来实现局部功能的代码和资源的集合(html/css/js/image…)
  2. 为什么:一个界面的功能很复杂
  3. 作用:复用编码,简化项目编码,提高运行效率

模块化 当应用中的 js 都以模块来编写的,那这个应用就是一个模块化的应用 组件化 当应用中的功能都是多组件的方式来编写的,那这个应用就是一个组件化的应用

2.VueComponent

  • school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
  • 我们只需要写<school/><school></school>Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
  • 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent,即不同组件是不同的对象
  • 关于this指向:
    • 组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是VueComponent实例对象。
    • new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是Vue实例对象
  • VueComponent的实例对象,简称vc(也可称之为:组件实例对象)。Vue的实例对象,简称vm

3.一个重要的内置关系

VueComponent.prototype.proto === Vue.prototype

为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

image-20220630171938542

school.prototype.proto === Vue.prototype