在vue的源码中,vue/src/shared/util.js文件中存放的是一些方法。其中作者用了Object.prototype.toString这个方法来判断类型,但是并没有直接用,而是单独保存在一个变量:
const _toStr = Object.prototype.toString
那么为什么要这么做呢?
先说下判断类型。众所周知,typeof在判断对象时不能正确判断Null,并且不能识别出Array,但在判断基础类型时是没问题的。所以尤大也写了:
export function isPrimitive (value: any): boolean %checks { return ( typeof value === 'string' || typeof value === 'number' || // $flow-disable-line typeof value === 'symbol' || typeof value === 'boolean' ) }
判断Object也做了区分,isObject和isPlainObject :
export function isObject (obj: mixed): boolean %checks { return obj !== null && typeof obj === 'object' } export function isPlainObject (obj: any): boolean { return _toString.call(obj) === '[object Object]' }
到了判断复杂类型的时候,一般我们用Object.prototype.toString或者是instanceof。如果是前者的话会返回类似'[object Object]'的字符串。后者则会判断一个对象的原型链上是否存在一个构造函数。
两者还有一些不同。Object.prototype.toString.call(1) 和 Object.prototype.toString.call(Number(1))时,返回的都是"[object Number]",也就是说,它并不能区分原始类型和复杂类型。可见,Object.prototype.toString.call并不像很多教程说的那样好用。
Object.prototype.toString.call(1) "[object Number]" Object.prototype.toString.call(Number(1)) "[object Number]"
如果要使用,就需要像尤大一样,把原始类型单独拎出来判断,再去判断复杂类型,而走到这一步的时候尤大就写了上面说那行const _toStr。这是因为,toString实在是太容易被重写了。如果toString被其他人重写,将会对html" target="_blank">代码中涉及到的部分造成影响,所以就保存下来防止这种情况发生。
补充:Object.prototype.toString方法的原理
前言
我们在判断一个对象的内置类型时,我们一般可以使用以下方法:
var arr = []; console.log(Object.prototype.toString.call(arr)) //"[object Array]"
那么,这个方法的原理是什么呢?
ECMAScript 3
在toString方法被调用时,会执行下面的操作步骤:
1. 获取this对象的[[Class]]属性的值.
2. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串.
3. 返回第二步的操作结果Result(2).
[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性.在规范中,[[Class]]是这么定义的
[[Class]] 一个字符串值,表明了该对象的类型.
然后给了一段解释:
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是任意值,甚至可以是内置对象使用过的[[Class]]属性的值.[[Class]]属性的值可以用来判断一个原生对象属于哪种内置类型.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值。
ECMAScript 5
在toString方法被调用时,会执行下面的操作步骤
如果this的值为undefined,则返回"[object Undefined]".
如果this的值为null,则返回"[object Null]".
让O成为调用ToObject(this)的结果.
让class成为O的内部属性[[Class]]的值.
返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.
ES5中,[[Class]]属性的解释更加详细:
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.[[Class]]内部属性是引擎内部用来判断一个对象属于哪种类型的值的.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值。
总而言之,要获取一个对象的真实的内置类型,我们需要通过获取[[Class]]的属性值,在es5之前,该属性值只能通由Object.prototype.toString来访问,因此,通过Object.prototype.toString.call(arr)改变tostring方法的this指向,从而获得对象的内置类型。
总结
以上所述是小编给大家介绍的Vue源码中要const _toStr = Object.prototype.toString的原因分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
本文向大家介绍Vue 中 template 有且只能一个 root的原因解析(源码分析),包括了Vue 中 template 有且只能一个 root的原因解析(源码分析)的使用技巧和注意事项,需要的朋友参考一下 引言 今年, 疫情 并没有影响到各种面经的正常出现,可谓是络绎不绝(学不动...)。然后,在前段时间也看到一个这样的关于 Vue 的问题, 为什么每个组件 template 中有且只能一个
最近一直在看 vue 2.2.6 的源码,所以准备分几个模块分别记录一下。由于水平有限,对整个框架的源码还没有整体的把握。所以前期内容可能比较零散,更多的是记录自己看的过程。慢慢整理成比较完整的源码分析。 备注:最近为了加深印象,写了一个简单的 mvvm 的实现,参考了 Vue 中模板解析、数据监听、render 函数的生成 传送门。 该源码分析,会带着大家一起学习 Vue 的大部分代码,而不是简
本文向大家介绍Vue中之nextTick函数源码分析详解,包括了Vue中之nextTick函数源码分析详解的使用技巧和注意事项,需要的朋友参考一下 1. 什么是Vue.nextTick()? 官方文档解释如下: 在下次DOM更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。 2. 为什么要使用nextTick? 如上代码 在页面视图上显示bb,但是当我在控制台打印
本文向大家介绍为什么不要使用 async void的原因分析,包括了为什么不要使用 async void的原因分析的使用技巧和注意事项,需要的朋友参考一下 问题 在使用 Abp 框架的后台作业时,当后台作业抛出异常,会导致整个程序崩溃。在 Abp 框架的底层执行后台作业的时候,有 try/catch 语句块用来捕获后台任务执行时的异常,但是在这里没有生效。 原始代码如下: 调用接口时的效果: 原因
本文向大家介绍深入理解Vue transition源码分析,包括了深入理解Vue transition源码分析的使用技巧和注意事项,需要的朋友参考一下 这两天学习了Vue transition感觉这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记。 本来打算自己造一个transition的轮子,所以决定先看看源码,理清思路。Vue的transition组件提供了一系列钩子函数,并且具有良好
本文向大家介绍vue router 源码概览案例分析,包括了vue router 源码概览案例分析的使用技巧和注意事项,需要的朋友参考一下 源码这个东西对于实际的工作其实没有立竿见影的效果,不会像那些针对性极强的文章一样看了之后就立马可以运用到实际项目中,产生什么样的效果,源码的作用是一个潜移默化的过程,它的理念、设计模式、代码结构等看了之后可能不会立即知识变现(或者说变现很少),而是在日后的工作